diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 64e79042..025ecb49 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -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 mappingBuffer = pResource->GetBuffer(); @@ -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;