1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 10:24:10 +01:00

[d3d9] Adjust waiting in LockBuffer to staging buffer upload

Now that we're uploading using a staging buffer,
we don't need to wait for non default buffers.

We should also respect READONLY for WRITEONLY buffers
(yes, it sounds dumb) because Nostale relies on that.
This commit is contained in:
Robin Kertels 2021-04-22 22:10:09 +02:00 committed by Joshie
parent ed24c17d53
commit b83261b759

View File

@ -4452,10 +4452,6 @@ namespace dxvk {
if (desc.Pool != D3DPOOL_DEFAULT)
Flags &= ~(D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE);
// Ignore READONLY if we are a WRITEONLY resource.
if (desc.Usage & D3DUSAGE_WRITEONLY)
Flags &= ~D3DLOCK_READONLY;
// Ignore DONOTWAIT if we are DYNAMIC
// Yes... D3D9 is a good API.
if (desc.Usage & D3DUSAGE_DYNAMIC)
@ -4464,14 +4460,6 @@ namespace dxvk {
// We only bounds check for MANAGED.
// (TODO: Apparently this is meant to happen for DYNAMIC too but I am not sure
// how that works given it is meant to be a DIRECT access..?)
// D3D9 does not do region tracking for READONLY locks
// But lets also account for whether we get readback from ProcessVertices
const bool quickRead = ((Flags & D3DLOCK_READONLY) && !pResource->WasWrittenByGPU());
const bool boundsCheck = desc.Pool != D3DPOOL_DEFAULT && !quickRead;
// We can only respect this for these cases -- otherwise R/W OOB still get copied on native
// and some stupid games depend on that.
const bool respectUserBounds = !(Flags & D3DLOCK_DISCARD) &&
SizeToLock != 0;
@ -4479,8 +4467,10 @@ namespace dxvk {
// These values may be out of range and don't get clamped.
uint32_t offset = respectUserBounds ? OffsetToLock : 0;
uint32_t size = respectUserBounds ? std::min(SizeToLock, desc.Size - offset) : desc.Size;
D3D9Range lockRange = D3D9Range(offset, offset + size);
pResource->DirtyRange().Conjoin(D3D9Range(offset, offset + size));
if (!(Flags & D3DLOCK_READONLY))
pResource->DirtyRange().Conjoin(lockRange);
Rc<DxvkBuffer> mappingBuffer = pResource->GetBuffer<D3D9_COMMON_BUFFER_TYPE_MAPPING>();
@ -4514,9 +4504,11 @@ namespace dxvk {
// If we are respecting the bounds ie. (MANAGED) we can test overlap
// of our bounds, otherwise we just ignore this and go for it all the time.
const bool skipWait = (Flags & D3DLOCK_NOOVERWRITE) ||
quickRead ||
(boundsCheck && !pResource->GPUReadingRange().Overlaps(pResource->DirtyRange()));
const bool wasWrittenByGPU = pResource->WasWrittenByGPU();
const bool readOnly = Flags & D3DLOCK_READONLY;
const bool noOverlap = !pResource->GPUReadingRange().Overlaps(lockRange);
const bool noOverwrite = Flags & D3DLOCK_NOOVERWRITE;
const bool skipWait = (!wasWrittenByGPU && (readOnly || noOverlap)) || noOverwrite;
if (!skipWait) {
if (!WaitForResource(mappingBuffer, Flags))
return D3DERR_WASSTILLDRAWING;