From 295d583c1db23577c9f1f8f9b5a5a4875d151cfe Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 2 Apr 2019 03:46:06 +0200 Subject: [PATCH] [d3d11] Lazily allocate predicate on SetPredication Many games use CreatePredicate to create occlusion queries without actually using predication, and we don't want to pay any runtime cost for this when predicates aren't actually being used. --- src/d3d11/d3d11_context.cpp | 11 +++++++---- src/d3d11/d3d11_device.cpp | 2 +- src/d3d11/d3d11_query.cpp | 23 +++++++++++++---------- src/d3d11/d3d11_query.h | 10 ++-------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 07f4571b..1a3fa5d0 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -283,12 +283,15 @@ namespace dxvk { return; EmitCs([ - cPredicate = predicate - ? predicate->GetPredicate() - : DxvkBufferSlice(), + cPredicate = Com(predicate), cValue = PredicateValue ] (DxvkContext* ctx) { - ctx->setPredicate(cPredicate, + DxvkBufferSlice predSlice; + + if (cPredicate != nullptr) + predSlice = cPredicate->GetPredicate(ctx); + + ctx->setPredicate(predSlice, cValue ? VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT : 0); }); } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index ab3c7c6a..cc2fdb71 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -987,7 +987,7 @@ namespace dxvk { return S_FALSE; try { - *ppPredicate = ref(new D3D11Query(this, *pPredicateDesc, AllocPredicateSlice())); + *ppPredicate = ref(new D3D11Query(this, *pPredicateDesc)); return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); diff --git a/src/d3d11/d3d11_query.cpp b/src/d3d11/d3d11_query.cpp index 5e561432..1a027887 100644 --- a/src/d3d11/d3d11_query.cpp +++ b/src/d3d11/d3d11_query.cpp @@ -6,16 +6,7 @@ namespace dxvk { D3D11Query::D3D11Query( D3D11Device* device, const D3D11_QUERY_DESC& desc) - : D3D11Query(device, desc, DxvkBufferSlice()) { - - } - - - D3D11Query::D3D11Query( - D3D11Device* device, - const D3D11_QUERY_DESC& desc, - const DxvkBufferSlice& predicate) - : m_device(device), m_desc(desc), m_predicate(predicate), + : m_device(device), m_desc(desc), m_d3d10(this, device->GetD3D10Interface()) { Rc dxvkDevice = m_device->GetDXVKDevice(); @@ -308,6 +299,18 @@ namespace dxvk { } + DxvkBufferSlice D3D11Query::GetPredicate(DxvkContext* ctx) { + std::lock_guard lock(m_predicateLock); + + if (unlikely(!m_predicate.defined())) { + m_predicate = m_device->AllocPredicateSlice(); + ctx->writePredicate(m_predicate, m_query); + } + + return m_predicate; + } + + UINT64 D3D11Query::GetTimestampQueryFrequency() const { Rc device = m_device->GetDXVKDevice(); Rc adapter = device->adapter(); diff --git a/src/d3d11/d3d11_query.h b/src/d3d11/d3d11_query.h index 0f77c900..1e102cb4 100644 --- a/src/d3d11/d3d11_query.h +++ b/src/d3d11/d3d11_query.h @@ -17,11 +17,6 @@ namespace dxvk { D3D11Device* device, const D3D11_QUERY_DESC& desc); - D3D11Query( - D3D11Device* device, - const D3D11_QUERY_DESC& desc, - const DxvkBufferSlice& predicate); - ~D3D11Query(); HRESULT STDMETHODCALLTYPE QueryInterface( @@ -44,9 +39,7 @@ namespace dxvk { void* pData, UINT GetDataFlags); - DxvkBufferSlice GetPredicate() const { - return m_predicate; - } + DxvkBufferSlice GetPredicate(DxvkContext* ctx); D3D10Query* GetD3D10Iface() { return &m_d3d10; @@ -60,6 +53,7 @@ namespace dxvk { Rc m_query = nullptr; Rc m_event = nullptr; + sync::Spinlock m_predicateLock; DxvkBufferSlice m_predicate; D3D10Query m_d3d10;