Skip to content

Commit

Permalink
[d3d11] Implicitly flush when queueing an event query
Browse files Browse the repository at this point in the history
Significantly improves GPU utilization in Quake Champions.
  • Loading branch information
doitsujin committed Oct 17, 2018
1 parent 5ecfbd8 commit 5124fd8
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
28 changes: 21 additions & 7 deletions src/d3d11/d3d11_context_imm.cpp
Expand Up @@ -48,6 +48,20 @@ namespace dxvk {
}


void STDMETHODCALLTYPE D3D11ImmediateContext::End(
ID3D11Asynchronous* pAsync) {
D3D11DeviceContext::End(pAsync);

if (pAsync) {
D3D11_QUERY_DESC desc;
static_cast<D3D11Query*>(pAsync)->GetDesc(&desc);

if (desc.Query == D3D11_QUERY_EVENT)
FlushImplicit(TRUE);
}
}


HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::GetData(
ID3D11Asynchronous* pAsync,
void* pData,
Expand Down Expand Up @@ -75,7 +89,7 @@ namespace dxvk {
// If we're likely going to spin on the asynchronous object,
// flush the context so that we're keeping the GPU busy
if (hr == S_FALSE)
FlushImplicit();
FlushImplicit(FALSE);

return hr;
}
Expand Down Expand Up @@ -116,7 +130,7 @@ namespace dxvk {

// As an optimization, flush everything if the
// number of pending draw calls is high enough.
FlushImplicit();
FlushImplicit(FALSE);

// Dispatch command list to the CS thread and
// restore the immediate context's state
Expand Down Expand Up @@ -193,7 +207,7 @@ namespace dxvk {
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView) {
FlushImplicit();
FlushImplicit(FALSE);

D3D11DeviceContext::OMSetRenderTargets(
NumViews, ppRenderTargetViews, pDepthStencilView);
Expand All @@ -208,7 +222,7 @@ namespace dxvk {
UINT NumUAVs,
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
const UINT* pUAVInitialCounts) {
FlushImplicit();
FlushImplicit(FALSE);

D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(
NumRTVs, ppRenderTargetViews, pDepthStencilView,
Expand Down Expand Up @@ -429,7 +443,7 @@ namespace dxvk {
// We don't have to wait, but misbehaving games may
// still try to spin on `Map` until the resource is
// idle, so we should flush pending commands
FlushImplicit();
FlushImplicit(FALSE);
return false;
} else {
// Make sure pending commands using the resource get
Expand All @@ -452,10 +466,10 @@ namespace dxvk {
}


void D3D11ImmediateContext::FlushImplicit() {
void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) {
// Flush only if the GPU is about to go idle, in
// order to keep the number of submissions low.
if (m_device->pendingSubmissions() <= MaxPendingSubmits) {
if (StrongHint || m_device->pendingSubmissions() <= MaxPendingSubmits) {
auto now = std::chrono::high_resolution_clock::now();

// Prevent flushing too often in short intervals.
Expand Down
5 changes: 4 additions & 1 deletion src/d3d11/d3d11_context_imm.h
Expand Up @@ -25,6 +25,9 @@ namespace dxvk {

UINT STDMETHODCALLTYPE GetContextFlags();

void STDMETHODCALLTYPE End(
ID3D11Asynchronous* pAsync);

HRESULT STDMETHODCALLTYPE GetData(
ID3D11Asynchronous* pAsync,
void* pData,
Expand Down Expand Up @@ -101,7 +104,7 @@ namespace dxvk {

void EmitCsChunk(DxvkCsChunkRef&& chunk);

void FlushImplicit();
void FlushImplicit(BOOL StrongHint);

};

Expand Down

0 comments on commit 5124fd8

Please sign in to comment.