From c7163729411a07c245e0a0f628bd777ff6219e18 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jun 2018 12:29:24 +0200 Subject: [PATCH] [d3d11] Move GetData implementation to D3D11ImmediateContext It is illegal to call this method on a deferred context, so we should filter out those calls. This allows the implementation to make use of features specific to the immediate context. --- src/d3d11/d3d11_context.cpp | 41 --------------------------------- src/d3d11/d3d11_context.h | 6 ----- src/d3d11/d3d11_context_def.cpp | 10 ++++++++ src/d3d11/d3d11_context_def.h | 6 +++++ src/d3d11/d3d11_context_imm.cpp | 41 +++++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_imm.h | 6 +++++ 6 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 15a3ce69f..46978a844 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -224,47 +224,6 @@ namespace dxvk { } - HRESULT STDMETHODCALLTYPE D3D11DeviceContext::GetData( - ID3D11Asynchronous* pAsync, - void* pData, - UINT DataSize, - UINT GetDataFlags) { - // Make sure that we can safely write to the memory - // location pointed to by pData if it is specified. - if (DataSize == 0) - pData = nullptr; - - if (pData != nullptr && pAsync->GetDataSize() != DataSize) { - Logger::err(str::format( - "D3D11: GetData: Data size mismatch", - "\n Expected: ", pAsync->GetDataSize(), - "\n Got: ", DataSize)); - return E_INVALIDARG; - } - - // Fallout 4 never actually calls this function without - // D3D11_ASYNC_GETDATA_DONOTFLUSH set, which may cause - // the game to freeze in certain situations. - if (m_parent->TestOption(D3D11Option::DisableGetDataFlagDoNotFlush)) - GetDataFlags &= ~D3D11_ASYNC_GETDATA_DONOTFLUSH; - - // Flush in order to make sure the query commands get dispatched - if ((GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH) == 0) - Flush(); - - // This method handles various different but incompatible interfaces, - // so we have to find out what we are actually dealing with - Com query; - - if (SUCCEEDED(pAsync->QueryInterface(__uuidof(ID3D11Query), reinterpret_cast(&query)))) - return static_cast(query.ptr())->GetData(pData, GetDataFlags); - - // The interface is not supported - Logger::err("D3D11: GetData: Unsupported Async type"); - return E_INVALIDARG; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SetPredication( ID3D11Predicate* pPredicate, BOOL PredicateValue) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index be00f9a30..b22063fd5 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -45,12 +45,6 @@ namespace dxvk { void STDMETHODCALLTYPE End(ID3D11Asynchronous *pAsync) final; - HRESULT STDMETHODCALLTYPE GetData( - ID3D11Asynchronous* pAsync, - void* pData, - UINT DataSize, - UINT GetDataFlags) final; - void STDMETHODCALLTYPE SetPredication( ID3D11Predicate* pPredicate, BOOL PredicateValue) final; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 817afbcbd..c10f87b15 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -23,6 +23,16 @@ namespace dxvk { } + HRESULT STDMETHODCALLTYPE D3D11DeferredContext::GetData( + ID3D11Asynchronous* pAsync, + void* pData, + UINT DataSize, + UINT GetDataFlags) { + Logger::err("D3D11: GetData called on a deferred context"); + return DXGI_ERROR_INVALID_CALL; + } + + void STDMETHODCALLTYPE D3D11DeferredContext::Flush() { Logger::err("D3D11: Flush called on a deferred context"); } diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index bf2fc6d57..86a6a76e2 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -34,6 +34,12 @@ namespace dxvk { UINT STDMETHODCALLTYPE GetContextFlags() final; + HRESULT STDMETHODCALLTYPE GetData( + ID3D11Asynchronous* pAsync, + void* pData, + UINT DataSize, + UINT GetDataFlags) final; + void STDMETHODCALLTYPE Flush() final; void STDMETHODCALLTYPE ExecuteCommandList( diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 8e0b49a28..4ebdcef5c 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -45,6 +45,47 @@ namespace dxvk { } + HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::GetData( + ID3D11Asynchronous* pAsync, + void* pData, + UINT DataSize, + UINT GetDataFlags) { + // Make sure that we can safely write to the memory + // location pointed to by pData if it is specified. + if (DataSize == 0) + pData = nullptr; + + if (pData != nullptr && pAsync->GetDataSize() != DataSize) { + Logger::err(str::format( + "D3D11: GetData: Data size mismatch", + "\n Expected: ", pAsync->GetDataSize(), + "\n Got: ", DataSize)); + return E_INVALIDARG; + } + + // Fallout 4 never actually calls this function without + // D3D11_ASYNC_GETDATA_DONOTFLUSH set, which may cause + // the game to freeze in certain situations. + if (m_parent->TestOption(D3D11Option::DisableGetDataFlagDoNotFlush)) + GetDataFlags &= ~D3D11_ASYNC_GETDATA_DONOTFLUSH; + + // Flush in order to make sure the query commands get dispatched + if ((GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH) == 0) + Flush(); + + // This method handles various different but incompatible interfaces, + // so we have to find out what we are actually dealing with + Com query; + + if (SUCCEEDED(pAsync->QueryInterface(__uuidof(ID3D11Query), reinterpret_cast(&query)))) + return static_cast(query.ptr())->GetData(pData, GetDataFlags); + + // The interface is not supported + Logger::err("D3D11: GetData: Unsupported Async type"); + return E_INVALIDARG; + } + + void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() { m_parent->FlushInitContext(); diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 5c72796ce..ed41a682e 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -27,6 +27,12 @@ namespace dxvk { UINT STDMETHODCALLTYPE GetContextFlags() final; + HRESULT STDMETHODCALLTYPE GetData( + ID3D11Asynchronous* pAsync, + void* pData, + UINT DataSize, + UINT GetDataFlags) final; + void STDMETHODCALLTYPE Flush() final; void STDMETHODCALLTYPE ExecuteCommandList(