mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 02:52:10 +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_drawCount += DrawCount;
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +54,8 @@ namespace dxvk {
|
||||
|
||||
for (auto chunk : m_chunks)
|
||||
cmdList->m_chunks.push_back(chunk);
|
||||
|
||||
cmdList->m_drawCount += m_drawCount;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,7 +23,9 @@ namespace dxvk {
|
||||
|
||||
UINT STDMETHODCALLTYPE GetContextFlags() final;
|
||||
|
||||
void AddChunk(Rc<DxvkCsChunk>&& Chunk);
|
||||
void AddChunk(
|
||||
Rc<DxvkCsChunk>&& Chunk,
|
||||
UINT DrawCount);
|
||||
|
||||
void EmitToCommandList(
|
||||
ID3D11CommandList* pCommandList);
|
||||
@ -31,10 +33,15 @@ namespace dxvk {
|
||||
void EmitToCsThread(
|
||||
DxvkCsThread* CsThread);
|
||||
|
||||
UINT GetDrawCount() const {
|
||||
return m_drawCount;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
D3D11Device* const m_device;
|
||||
UINT const m_contextFlags;
|
||||
UINT m_drawCount = 0;
|
||||
|
||||
std::vector<Rc<DxvkCsChunk>> m_chunks;
|
||||
|
||||
|
@ -648,7 +648,7 @@ namespace dxvk {
|
||||
Com<D3D11RasterizerState> m_defaultRasterizerState;
|
||||
|
||||
D3D11ContextState m_state;
|
||||
uint64_t m_drawCount = 0;
|
||||
UINT m_drawCount = 0;
|
||||
|
||||
void ApplyInputLayout();
|
||||
|
||||
|
@ -256,7 +256,8 @@ namespace dxvk {
|
||||
|
||||
|
||||
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(
|
||||
ID3D11CommandList* pCommandList,
|
||||
BOOL RestoreContextState) {
|
||||
auto commandList = static_cast<D3D11CommandList*>(pCommandList);
|
||||
|
||||
// Flush any outstanding commands so that
|
||||
// we don't mess up the execution order
|
||||
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)
|
||||
RestoreState();
|
||||
else
|
||||
ClearState();
|
||||
|
||||
// Mark CS thread as busy so that subsequent
|
||||
// flush operations get executed correctly.
|
||||
m_csIsBusy = true;
|
||||
m_drawCount += commandList->GetDrawCount();
|
||||
}
|
||||
|
||||
|
||||
@ -190,7 +204,7 @@ namespace dxvk {
|
||||
// prior to the previous context flush is above a certain threshold,
|
||||
// submit the current command buffer in order to keep the GPU busy.
|
||||
// This also helps keep the command buffers at a reasonable size.
|
||||
if (m_drawCount >= 500)
|
||||
if (m_drawCount >= MaxPendingDraws)
|
||||
Flush();
|
||||
|
||||
D3D11DeviceContext::OMSetRenderTargets(
|
||||
|
@ -8,7 +8,7 @@ namespace dxvk {
|
||||
class D3D11CommonTexture;
|
||||
|
||||
class D3D11ImmediateContext : public D3D11DeviceContext {
|
||||
|
||||
constexpr static UINT MaxPendingDraws = 500;
|
||||
public:
|
||||
|
||||
D3D11ImmediateContext(
|
||||
|
Loading…
x
Reference in New Issue
Block a user