From 5558460853f155550cf63b03bb682afce029630b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 1 Jun 2020 15:52:25 +0100 Subject: [PATCH] [d3d9] Don't mark lock on DONOTWAIT path Fixes some issues in some games using this feature. --- src/d3d9/d3d9_common_texture.h | 10 +++++++--- src/d3d9/d3d9_device.cpp | 11 ++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index 4e589691..fcca8924 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -302,15 +302,19 @@ namespace dxvk { const D3D9_VK_FORMAT_MAPPING& GetMapping() { return m_mapping; } - bool MarkLocked(UINT Subresource, bool value) { return m_locked.exchange(Subresource, value); } + void SetLocked(UINT Subresource, bool value) { m_locked.set(Subresource, value); } - bool SetDirty(UINT Subresource, bool value) { return m_dirty.exchange(Subresource, value); } + bool GetLocked(UINT Subresource) const { return m_locked.get(Subresource); } + + void SetDirty(UINT Subresource, bool value) { m_dirty.set(Subresource, value); } + + bool GetDirty(UINT Subresource) const { return m_dirty.get(Subresource); } void MarkAllDirty() { m_dirty.setAll(); } void SetReadOnlyLocked(UINT Subresource, bool readOnly) { return m_readOnly.set(Subresource, readOnly); } - bool GetReadOnlyLocked(UINT Subresource) { return m_readOnly.get(Subresource); } + bool GetReadOnlyLocked(UINT Subresource) const { return m_readOnly.get(Subresource); } const Rc& GetSampleView(bool srgb) const { return m_sampleView.Pick(srgb && IsSrgbCompatible()); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 2f05e63b..8c613c78 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3893,7 +3893,7 @@ namespace dxvk { UINT Subresource = pResource->CalcSubresource(Face, MipLevel); // Don't allow multiple lockings. - if (unlikely(pResource->MarkLocked(Subresource, true))) + if (unlikely(pResource->GetLocked(Subresource))) return D3DERR_INVALIDCALL; if (unlikely((Flags & (D3DLOCK_DISCARD | D3DLOCK_READONLY)) == (D3DLOCK_DISCARD | D3DLOCK_READONLY))) @@ -3959,7 +3959,8 @@ namespace dxvk { // If we are dirty, then we need to copy -> buffer // We are also always dirty if we are a render target, // a depth stencil, or auto generate mipmaps. - bool dirty = pResource->SetDirty(Subresource, false) || renderable; + bool dirty = pResource->GetDirty(Subresource) || renderable; + pResource->SetDirty(Subresource, false); DxvkBufferSliceHandle physSlice; @@ -4095,6 +4096,8 @@ namespace dxvk { pLockedBox->SlicePitch = formatInfo->elementSize * blockCount.width * blockCount.height; } + pResource->SetLocked(Subresource, true); + const uint32_t offset = CalcImageLockOffset( pLockedBox->SlicePitch, pLockedBox->RowPitch, @@ -4117,9 +4120,11 @@ namespace dxvk { UINT Subresource = pResource->CalcSubresource(Face, MipLevel); // We weren't locked anyway! - if (unlikely(!pResource->MarkLocked(Subresource, false))) + if (unlikely(!pResource->GetLocked(Subresource))) return D3DERR_INVALIDCALL; + pResource->SetLocked(Subresource, false); + // Do we have a pending copy? if (!pResource->GetReadOnlyLocked(Subresource)) { // Only flush buffer -> image if we actually have an image