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

[d3d11] Re-implemented draw call-based context flush

After doing more testing, it became apparent that this
optimization is beneficial most of the time and may also
improve stability by limiting the number of commands
recorded into a single command buffer.
This commit is contained in:
Philip Rebohle 2018-01-13 23:09:03 +01:00
parent c1f16d36bd
commit c7a9763f6d
2 changed files with 20 additions and 4 deletions

View File

@ -166,6 +166,7 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11DeviceContext::Flush() {
if (m_type == D3D11_DEVICE_CONTEXT_IMMEDIATE) {
m_parent->FlushInitContext();
m_drawCount = 0;
m_device->submitCommandList(
m_context->endRecording(),
@ -737,6 +738,7 @@ namespace dxvk {
m_context->draw(
VertexCount, 1,
StartVertexLocation, 0);
m_drawCount += 1;
}
@ -748,6 +750,7 @@ namespace dxvk {
IndexCount, 1,
StartIndexLocation,
BaseVertexLocation, 0);
m_drawCount += 1;
}
@ -761,6 +764,7 @@ namespace dxvk {
InstanceCount,
StartVertexLocation,
StartInstanceLocation);
m_drawCount += 1;
}
@ -776,6 +780,7 @@ namespace dxvk {
StartIndexLocation,
BaseVertexLocation,
StartInstanceLocation);
m_drawCount += 1;
}
@ -786,6 +791,7 @@ namespace dxvk {
DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs);
m_context->drawIndexedIndirect(bufferSlice, 1, 0);
m_drawCount += 1;
}
@ -796,6 +802,7 @@ namespace dxvk {
DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs);
m_context->drawIndirect(bufferSlice, 1, 0);
m_drawCount += 1;
}
@ -807,6 +814,7 @@ namespace dxvk {
ThreadGroupCountX,
ThreadGroupCountY,
ThreadGroupCountZ);
m_drawCount += 1;
}
@ -817,6 +825,7 @@ namespace dxvk {
DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs);
m_context->dispatchIndirect(bufferSlice);
m_drawCount += 1;
}
@ -1541,6 +1550,12 @@ namespace dxvk {
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView) {
// Optimization: If the number of draw and dispatch calls issued
// prior to the previous context flush is above a certain threshold,
// submit the current command buffer in order to keep the GPU busy.
if (m_drawCount >= 500)
this->Flush();
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
D3D11RenderTargetView* view = nullptr;

View File

@ -554,15 +554,16 @@ namespace dxvk {
const D3D11_DEVICE_CONTEXT_TYPE m_type = D3D11_DEVICE_CONTEXT_IMMEDIATE;
const UINT m_flags = 0;
Rc<DxvkDevice> m_device;
Rc<DxvkContext> m_context;
Rc<DxvkSampler> m_defaultSampler;
Rc<DxvkDevice> m_device;
Rc<DxvkContext> m_context;
Rc<DxvkSampler> m_defaultSampler;
Com<D3D11BlendState> m_defaultBlendState;
Com<D3D11DepthStencilState> m_defaultDepthStencilState;
Com<D3D11RasterizerState> m_defaultRasterizerState;
D3D11ContextState m_state;
D3D11ContextState m_state;
uint64_t m_drawCount = 0;
void BindConstantBuffers(
DxbcProgramType ShaderStage,