From 9c6209fbf5df76c013518154f4eb63c7ebb83c7c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 14 Oct 2019 01:27:59 +0200 Subject: [PATCH] [d3d11] Fix reference counting for state objects Fixes various wine test failures. Also, state objects are now allocated in the hash map itself rather than a wrapped COM object. --- src/d3d11/d3d11_blend.cpp | 16 ++++++++++++++++ src/d3d11/d3d11_blend.h | 6 ++++++ src/d3d11/d3d11_depth_stencil.cpp | 16 ++++++++++++++++ src/d3d11/d3d11_depth_stencil.h | 6 ++++++ src/d3d11/d3d11_rasterizer.cpp | 16 ++++++++++++++++ src/d3d11/d3d11_rasterizer.h | 8 +++++++- src/d3d11/d3d11_sampler.cpp | 16 ++++++++++++++++ src/d3d11/d3d11_sampler.h | 6 ++++++ src/d3d11/d3d11_state.h | 16 +++++++++------- 9 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_blend.cpp b/src/d3d11/d3d11_blend.cpp index bf8b35dad..532adc7d0 100644 --- a/src/d3d11/d3d11_blend.cpp +++ b/src/d3d11/d3d11_blend.cpp @@ -36,6 +36,22 @@ namespace dxvk { } + ULONG STDMETHODCALLTYPE D3D11BlendState::AddRef() { + ULONG refCount = m_refCount++; + if (!refCount) + m_device->AddRef(); + return refCount; + } + + + ULONG STDMETHODCALLTYPE D3D11BlendState::Release() { + ULONG refCount = --m_refCount; + if (!refCount) + m_device->Release(); + return refCount; + } + + HRESULT STDMETHODCALLTYPE D3D11BlendState::QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) return E_POINTER; diff --git a/src/d3d11/d3d11_blend.h b/src/d3d11/d3d11_blend.h index dcb2789c3..150cd2104 100644 --- a/src/d3d11/d3d11_blend.h +++ b/src/d3d11/d3d11_blend.h @@ -22,6 +22,10 @@ namespace dxvk { const D3D11_BLEND_DESC1& desc); ~D3D11BlendState(); + ULONG STDMETHODCALLTYPE AddRef() final; + + ULONG STDMETHODCALLTYPE Release() final; + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppvObject) final; @@ -61,6 +65,8 @@ namespace dxvk { DxvkLogicOpState m_loState; D3D10BlendState m_d3d10; + + std::atomic m_refCount = { 0u }; static DxvkBlendMode DecodeBlendMode( const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc); diff --git a/src/d3d11/d3d11_depth_stencil.cpp b/src/d3d11/d3d11_depth_stencil.cpp index 7a22807a1..48e552b0a 100644 --- a/src/d3d11/d3d11_depth_stencil.cpp +++ b/src/d3d11/d3d11_depth_stencil.cpp @@ -21,6 +21,22 @@ namespace dxvk { } + ULONG STDMETHODCALLTYPE D3D11DepthStencilState::AddRef() { + ULONG refCount = m_refCount++; + if (!refCount) + m_device->AddRef(); + return refCount; + } + + + ULONG STDMETHODCALLTYPE D3D11DepthStencilState::Release() { + ULONG refCount = --m_refCount; + if (!refCount) + m_device->Release(); + return refCount; + } + + HRESULT STDMETHODCALLTYPE D3D11DepthStencilState::QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) return E_POINTER; diff --git a/src/d3d11/d3d11_depth_stencil.h b/src/d3d11/d3d11_depth_stencil.h index 809c9ae59..ecf4a6d95 100644 --- a/src/d3d11/d3d11_depth_stencil.h +++ b/src/d3d11/d3d11_depth_stencil.h @@ -22,6 +22,10 @@ namespace dxvk { const D3D11_DEPTH_STENCIL_DESC& desc); ~D3D11DepthStencilState(); + ULONG STDMETHODCALLTYPE AddRef() final; + + ULONG STDMETHODCALLTYPE Release() final; + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppvObject) final; @@ -50,6 +54,8 @@ namespace dxvk { D3D11_DEPTH_STENCIL_DESC m_desc; DxvkDepthStencilState m_state; D3D10DepthStencilState m_d3d10; + + std::atomic m_refCount = { 0u }; VkStencilOpState DecodeStencilOpState( const D3D11_DEPTH_STENCILOP_DESC& StencilDesc, diff --git a/src/d3d11/d3d11_rasterizer.cpp b/src/d3d11/d3d11_rasterizer.cpp index b79cfe5bd..6ee71f02f 100644 --- a/src/d3d11/d3d11_rasterizer.cpp +++ b/src/d3d11/d3d11_rasterizer.cpp @@ -50,6 +50,22 @@ namespace dxvk { } + ULONG STDMETHODCALLTYPE D3D11RasterizerState::AddRef() { + ULONG refCount = m_refCount++; + if (!refCount) + m_device->AddRef(); + return refCount; + } + + + ULONG STDMETHODCALLTYPE D3D11RasterizerState::Release() { + ULONG refCount = --m_refCount; + if (!refCount) + m_device->Release(); + return refCount; + } + + HRESULT STDMETHODCALLTYPE D3D11RasterizerState::QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) return E_POINTER; diff --git a/src/d3d11/d3d11_rasterizer.h b/src/d3d11/d3d11_rasterizer.h index 3bf4e0ffe..5fc386e0b 100644 --- a/src/d3d11/d3d11_rasterizer.h +++ b/src/d3d11/d3d11_rasterizer.h @@ -20,7 +20,11 @@ namespace dxvk { D3D11Device* device, const D3D11_RASTERIZER_DESC2& desc); ~D3D11RasterizerState(); - + + ULONG STDMETHODCALLTYPE AddRef() final; + + ULONG STDMETHODCALLTYPE Release() final; + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppvObject) final; @@ -66,6 +70,8 @@ namespace dxvk { DxvkRasterizerState m_state; DxvkDepthBias m_depthBias; D3D10RasterizerState m_d3d10; + + std::atomic m_refCount = { 0u }; }; diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index b367eae32..5aff4e15a 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -59,6 +59,22 @@ namespace dxvk { } + ULONG STDMETHODCALLTYPE D3D11SamplerState::AddRef() { + ULONG refCount = m_refCount++; + if (!refCount) + m_device->AddRef(); + return refCount; + } + + + ULONG STDMETHODCALLTYPE D3D11SamplerState::Release() { + ULONG refCount = --m_refCount; + if (!refCount) + m_device->Release(); + return refCount; + } + + HRESULT STDMETHODCALLTYPE D3D11SamplerState::QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) return E_POINTER; diff --git a/src/d3d11/d3d11_sampler.h b/src/d3d11/d3d11_sampler.h index 75d16fa18..26d4e5a60 100644 --- a/src/d3d11/d3d11_sampler.h +++ b/src/d3d11/d3d11_sampler.h @@ -21,6 +21,10 @@ namespace dxvk { const D3D11_SAMPLER_DESC& desc); ~D3D11SamplerState(); + ULONG STDMETHODCALLTYPE AddRef() final; + + ULONG STDMETHODCALLTYPE Release() final; + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppvObject) final; @@ -49,6 +53,8 @@ namespace dxvk { Rc m_sampler; D3D10SamplerState m_d3d10; + std::atomic m_refCount = { 0u }; + static bool ValidateAddressMode( D3D11_TEXTURE_ADDRESS_MODE Mode); diff --git a/src/d3d11/d3d11_state.h b/src/d3d11/d3d11_state.h index 9d9b39daa..bb030a0f9 100644 --- a/src/d3d11/d3d11_state.h +++ b/src/d3d11/d3d11_state.h @@ -56,20 +56,22 @@ namespace dxvk { T* Create(D3D11Device* device, const DescType& desc) { std::lock_guard lock(m_mutex); - auto pair = m_objects.find(desc); + auto entry = m_objects.find(desc); - if (pair != m_objects.end()) - return pair->second.ref(); + if (entry != m_objects.end()) + return ref(&entry->second); - Com result = new T(device, desc); - m_objects.insert({ desc, result }); - return result.ref(); + auto result = m_objects.emplace( + std::piecewise_construct, + std::tuple(desc), + std::tuple(device, desc)); + return ref(&result.first->second); } private: std::mutex m_mutex; - std::unordered_map, + std::unordered_map m_objects; };