mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[d3d11] Flush immediate context on command list execution
This optimization may help keep the GPU busy in case there's a large number of draw calls pending at the time a command list from a deferred context is submitted for execution.
This commit is contained in:
parent
0b2e88b087
commit
7de27d4fd8
@ -41,8 +41,11 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11CommandList::AddChunk(Rc<DxvkCsChunk>&& Chunk) {
|
void D3D11CommandList::AddChunk(
|
||||||
|
Rc<DxvkCsChunk>&& Chunk,
|
||||||
|
UINT DrawCount) {
|
||||||
m_chunks.push_back(std::move(Chunk));
|
m_chunks.push_back(std::move(Chunk));
|
||||||
|
m_drawCount += DrawCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -51,6 +54,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (auto chunk : m_chunks)
|
for (auto chunk : m_chunks)
|
||||||
cmdList->m_chunks.push_back(chunk);
|
cmdList->m_chunks.push_back(chunk);
|
||||||
|
|
||||||
|
cmdList->m_drawCount += m_drawCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
UINT STDMETHODCALLTYPE GetContextFlags() final;
|
UINT STDMETHODCALLTYPE GetContextFlags() final;
|
||||||
|
|
||||||
void AddChunk(Rc<DxvkCsChunk>&& Chunk);
|
void AddChunk(
|
||||||
|
Rc<DxvkCsChunk>&& Chunk,
|
||||||
|
UINT DrawCount);
|
||||||
|
|
||||||
void EmitToCommandList(
|
void EmitToCommandList(
|
||||||
ID3D11CommandList* pCommandList);
|
ID3D11CommandList* pCommandList);
|
||||||
@ -31,10 +33,15 @@ namespace dxvk {
|
|||||||
void EmitToCsThread(
|
void EmitToCsThread(
|
||||||
DxvkCsThread* CsThread);
|
DxvkCsThread* CsThread);
|
||||||
|
|
||||||
|
UINT GetDrawCount() const {
|
||||||
|
return m_drawCount;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
D3D11Device* const m_device;
|
D3D11Device* const m_device;
|
||||||
UINT const m_contextFlags;
|
UINT const m_contextFlags;
|
||||||
|
UINT m_drawCount = 0;
|
||||||
|
|
||||||
std::vector<Rc<DxvkCsChunk>> m_chunks;
|
std::vector<Rc<DxvkCsChunk>> m_chunks;
|
||||||
|
|
||||||
|
@ -648,7 +648,7 @@ namespace dxvk {
|
|||||||
Com<D3D11RasterizerState> m_defaultRasterizerState;
|
Com<D3D11RasterizerState> m_defaultRasterizerState;
|
||||||
|
|
||||||
D3D11ContextState m_state;
|
D3D11ContextState m_state;
|
||||||
uint64_t m_drawCount = 0;
|
UINT m_drawCount = 0;
|
||||||
|
|
||||||
void ApplyInputLayout();
|
void ApplyInputLayout();
|
||||||
|
|
||||||
|
@ -256,7 +256,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D11DeferredContext::EmitCsChunk(Rc<DxvkCsChunk>&& chunk) {
|
void D3D11DeferredContext::EmitCsChunk(Rc<DxvkCsChunk>&& chunk) {
|
||||||
m_commandList->AddChunk(std::move(chunk));
|
m_commandList->AddChunk(std::move(chunk), m_drawCount);
|
||||||
|
m_drawCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -72,16 +72,30 @@ namespace dxvk {
|
|||||||
void STDMETHODCALLTYPE D3D11ImmediateContext::ExecuteCommandList(
|
void STDMETHODCALLTYPE D3D11ImmediateContext::ExecuteCommandList(
|
||||||
ID3D11CommandList* pCommandList,
|
ID3D11CommandList* pCommandList,
|
||||||
BOOL RestoreContextState) {
|
BOOL RestoreContextState) {
|
||||||
|
auto commandList = static_cast<D3D11CommandList*>(pCommandList);
|
||||||
|
|
||||||
|
// Flush any outstanding commands so that
|
||||||
|
// we don't mess up the execution order
|
||||||
FlushCsChunk();
|
FlushCsChunk();
|
||||||
|
|
||||||
static_cast<D3D11CommandList*>(pCommandList)->EmitToCsThread(&m_csThread);
|
// As an optimization, flush everything if the
|
||||||
|
// number of pending draw calls is high enough.
|
||||||
|
if (m_drawCount >= MaxPendingDraws)
|
||||||
|
Flush();
|
||||||
|
|
||||||
|
// Dispatch command list to the CS thread and
|
||||||
|
// restore the immediate context's state
|
||||||
|
commandList->EmitToCsThread(&m_csThread);
|
||||||
|
|
||||||
if (RestoreContextState)
|
if (RestoreContextState)
|
||||||
RestoreState();
|
RestoreState();
|
||||||
else
|
else
|
||||||
ClearState();
|
ClearState();
|
||||||
|
|
||||||
|
// Mark CS thread as busy so that subsequent
|
||||||
|
// flush operations get executed correctly.
|
||||||
m_csIsBusy = true;
|
m_csIsBusy = true;
|
||||||
|
m_drawCount += commandList->GetDrawCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,7 +204,7 @@ namespace dxvk {
|
|||||||
// prior to the previous context flush is above a certain threshold,
|
// prior to the previous context flush is above a certain threshold,
|
||||||
// submit the current command buffer in order to keep the GPU busy.
|
// submit the current command buffer in order to keep the GPU busy.
|
||||||
// This also helps keep the command buffers at a reasonable size.
|
// This also helps keep the command buffers at a reasonable size.
|
||||||
if (m_drawCount >= 500)
|
if (m_drawCount >= MaxPendingDraws)
|
||||||
Flush();
|
Flush();
|
||||||
|
|
||||||
D3D11DeviceContext::OMSetRenderTargets(
|
D3D11DeviceContext::OMSetRenderTargets(
|
||||||
|
@ -8,7 +8,7 @@ namespace dxvk {
|
|||||||
class D3D11CommonTexture;
|
class D3D11CommonTexture;
|
||||||
|
|
||||||
class D3D11ImmediateContext : public D3D11DeviceContext {
|
class D3D11ImmediateContext : public D3D11DeviceContext {
|
||||||
|
constexpr static UINT MaxPendingDraws = 500;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11ImmediateContext(
|
D3D11ImmediateContext(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user