1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 22:29:15 +01:00

[d3d11] Optimized command submission

The context will now be flushed after a render pass that consisted of
several hundreds of draw calls. This way the GPU should be kept busy.
This commit is contained in:
Philip Rebohle 2018-01-08 17:45:21 +01:00
parent 9024f8bb2c
commit 3925675b89
2 changed files with 19 additions and 0 deletions

View File

@ -161,6 +161,8 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11DeviceContext::Flush() { void STDMETHODCALLTYPE D3D11DeviceContext::Flush() {
if (m_type == D3D11_DEVICE_CONTEXT_IMMEDIATE) { if (m_type == D3D11_DEVICE_CONTEXT_IMMEDIATE) {
m_executedDrawCalls = 0;
m_device->submitCommandList( m_device->submitCommandList(
m_context->endRecording(), m_context->endRecording(),
nullptr, nullptr); nullptr, nullptr);
@ -720,6 +722,7 @@ namespace dxvk {
m_context->draw( m_context->draw(
VertexCount, 1, VertexCount, 1,
StartVertexLocation, 0); StartVertexLocation, 0);
m_executedDrawCalls += 1;
} }
@ -731,6 +734,7 @@ namespace dxvk {
IndexCount, 1, IndexCount, 1,
StartIndexLocation, StartIndexLocation,
BaseVertexLocation, 0); BaseVertexLocation, 0);
m_executedDrawCalls += 1;
} }
@ -744,6 +748,7 @@ namespace dxvk {
InstanceCount, InstanceCount,
StartVertexLocation, StartVertexLocation,
StartInstanceLocation); StartInstanceLocation);
m_executedDrawCalls += 1;
} }
@ -759,6 +764,7 @@ namespace dxvk {
StartIndexLocation, StartIndexLocation,
BaseVertexLocation, BaseVertexLocation,
StartInstanceLocation); StartInstanceLocation);
m_executedDrawCalls += 1;
} }
@ -769,6 +775,7 @@ namespace dxvk {
DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs);
m_context->drawIndexedIndirect(bufferSlice, 1, 0); m_context->drawIndexedIndirect(bufferSlice, 1, 0);
m_executedDrawCalls += 1;
} }
@ -779,6 +786,7 @@ namespace dxvk {
DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs);
m_context->drawIndirect(bufferSlice, 1, 0); m_context->drawIndirect(bufferSlice, 1, 0);
m_executedDrawCalls += 1;
} }
@ -790,6 +798,7 @@ namespace dxvk {
ThreadGroupCountX, ThreadGroupCountX,
ThreadGroupCountY, ThreadGroupCountY,
ThreadGroupCountZ); ThreadGroupCountZ);
m_executedDrawCalls += 1;
} }
@ -800,6 +809,7 @@ namespace dxvk {
DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs);
m_context->dispatchIndirect(bufferSlice); m_context->dispatchIndirect(bufferSlice);
m_executedDrawCalls += 1;
} }
@ -1522,6 +1532,13 @@ namespace dxvk {
UINT NumViews, UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView) { ID3D11DepthStencilView* pDepthStencilView) {
// Optimization: If the app has executed at least a given
// number of draw calls since the last explicit flush, flush
// the context in order to keep the GPU busy. We'll do this
// here because we are going to start a new render pass anyway.
if (m_executedDrawCalls >= 500)
this->Flush();
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
D3D11RenderTargetView* view = nullptr; D3D11RenderTargetView* view = nullptr;

View File

@ -563,6 +563,8 @@ namespace dxvk {
D3D11ContextState m_state; D3D11ContextState m_state;
uint32_t m_executedDrawCalls = 0;
void BindConstantBuffers( void BindConstantBuffers(
DxbcProgramType ShaderStage, DxbcProgramType ShaderStage,
D3D11ConstantBufferBindings& Bindings, D3D11ConstantBufferBindings& Bindings,