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

[d3d11] Implement new auto-flush heuristic

This commit is contained in:
Philip Rebohle 2018-06-04 23:31:49 +02:00
parent cfe99368fb
commit 4a0c81276f
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
7 changed files with 28 additions and 38 deletions

View File

@ -42,10 +42,8 @@ namespace dxvk {
void D3D11CommandList::AddChunk( void D3D11CommandList::AddChunk(
Rc<DxvkCsChunk>&& Chunk, Rc<DxvkCsChunk>&& Chunk) {
UINT DrawCount) {
m_chunks.push_back(std::move(Chunk)); m_chunks.push_back(std::move(Chunk));
m_drawCount += DrawCount;
} }
@ -54,8 +52,6 @@ namespace dxvk {
for (const auto& chunk : m_chunks) for (const auto& chunk : m_chunks)
cmdList->m_chunks.push_back(chunk); cmdList->m_chunks.push_back(chunk);
cmdList->m_drawCount += m_drawCount;
} }

View File

@ -24,8 +24,7 @@ namespace dxvk {
UINT STDMETHODCALLTYPE GetContextFlags() final; UINT STDMETHODCALLTYPE GetContextFlags() final;
void AddChunk( void AddChunk(
Rc<DxvkCsChunk>&& Chunk, Rc<DxvkCsChunk>&& Chunk);
UINT DrawCount);
void EmitToCommandList( void EmitToCommandList(
ID3D11CommandList* pCommandList); ID3D11CommandList* pCommandList);
@ -33,15 +32,10 @@ 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;

View File

@ -1117,8 +1117,6 @@ namespace dxvk {
VertexCount, 1, VertexCount, 1,
StartVertexLocation, 0); StartVertexLocation, 0);
}); });
m_drawCount += 1;
} }
@ -1132,8 +1130,6 @@ namespace dxvk {
StartIndexLocation, StartIndexLocation,
BaseVertexLocation, 0); BaseVertexLocation, 0);
}); });
m_drawCount += 1;
} }
@ -1149,8 +1145,6 @@ namespace dxvk {
StartVertexLocation, StartVertexLocation,
StartInstanceLocation); StartInstanceLocation);
}); });
m_drawCount += 1;
} }
@ -1168,8 +1162,6 @@ namespace dxvk {
BaseVertexLocation, BaseVertexLocation,
StartInstanceLocation); StartInstanceLocation);
}); });
m_drawCount += 1;
} }
@ -1183,8 +1175,6 @@ namespace dxvk {
ctx->drawIndexedIndirect( ctx->drawIndexedIndirect(
bufferSlice, 1, 0); bufferSlice, 1, 0);
}); });
m_drawCount += 1;
} }
@ -1197,8 +1187,6 @@ namespace dxvk {
(DxvkContext* ctx) { (DxvkContext* ctx) {
ctx->drawIndirect(bufferSlice, 1, 0); ctx->drawIndirect(bufferSlice, 1, 0);
}); });
m_drawCount += 1;
} }
@ -1212,8 +1200,6 @@ namespace dxvk {
ThreadGroupCountY, ThreadGroupCountY,
ThreadGroupCountZ); ThreadGroupCountZ);
}); });
m_drawCount += 1;
} }
@ -1226,8 +1212,6 @@ namespace dxvk {
(DxvkContext* ctx) { (DxvkContext* ctx) {
ctx->dispatchIndirect(bufferSlice); ctx->dispatchIndirect(bufferSlice);
}); });
m_drawCount += 1;
} }

View File

@ -654,7 +654,6 @@ namespace dxvk {
Com<D3D11RasterizerState> m_defaultRasterizerState; Com<D3D11RasterizerState> m_defaultRasterizerState;
D3D11ContextState m_state; D3D11ContextState m_state;
UINT m_drawCount = 0;
void ApplyInputLayout(); void ApplyInputLayout();

View File

@ -290,8 +290,7 @@ namespace dxvk {
void D3D11DeferredContext::EmitCsChunk(Rc<DxvkCsChunk>&& chunk) { void D3D11DeferredContext::EmitCsChunk(Rc<DxvkCsChunk>&& chunk) {
m_commandList->AddChunk(std::move(chunk), m_drawCount); m_commandList->AddChunk(std::move(chunk));
m_drawCount = 0;
} }
} }

View File

@ -63,8 +63,8 @@ namespace dxvk {
FlushCsChunk(); FlushCsChunk();
// Reset optimization info // Reset optimization info
m_drawCount = 0;
m_csIsBusy = false; m_csIsBusy = false;
m_lastFlush = std::chrono::high_resolution_clock::now();
} }
} }
@ -80,8 +80,7 @@ namespace dxvk {
// As an optimization, flush everything if the // As an optimization, flush everything if the
// number of pending draw calls is high enough. // number of pending draw calls is high enough.
if (m_drawCount >= MaxPendingDraws) FlushImplicit();
Flush();
// Dispatch command list to the CS thread and // Dispatch command list to the CS thread and
// restore the immediate context's state // restore the immediate context's state
@ -95,7 +94,6 @@ namespace dxvk {
// Mark CS thread as busy so that subsequent // Mark CS thread as busy so that subsequent
// flush operations get executed correctly. // flush operations get executed correctly.
m_csIsBusy = true; m_csIsBusy = true;
m_drawCount += commandList->GetDrawCount();
} }
@ -202,8 +200,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 >= MaxPendingDraws) FlushImplicit();
Flush();
D3D11DeviceContext::OMSetRenderTargets( D3D11DeviceContext::OMSetRenderTargets(
NumViews, ppRenderTargetViews, pDepthStencilView); NumViews, ppRenderTargetViews, pDepthStencilView);
@ -387,4 +384,17 @@ namespace dxvk {
m_csIsBusy = true; m_csIsBusy = true;
} }
void D3D11ImmediateContext::FlushImplicit() {
// Flush only if the GPU is about to go idle, in
// order to keep the number of submissions low.
if (m_device->pendingSubmissions() <= MaxPendingSubmits) {
auto now = std::chrono::high_resolution_clock::now();
// Prevent flushing too often in short intervals.
if (now - m_lastFlush >= std::chrono::microseconds(MinFlushIntervalUs))
Flush();
}
}
} }

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <chrono>
#include "d3d11_context.h" #include "d3d11_context.h"
namespace dxvk { namespace dxvk {
@ -8,7 +10,8 @@ namespace dxvk {
class D3D11CommonTexture; class D3D11CommonTexture;
class D3D11ImmediateContext : public D3D11DeviceContext { class D3D11ImmediateContext : public D3D11DeviceContext {
constexpr static UINT MaxPendingDraws = 500; constexpr static uint32_t MinFlushIntervalUs = 2500;
constexpr static uint32_t MaxPendingSubmits = 2;
public: public:
D3D11ImmediateContext( D3D11ImmediateContext(
@ -57,6 +60,9 @@ namespace dxvk {
DxvkCsThread m_csThread; DxvkCsThread m_csThread;
bool m_csIsBusy = false; bool m_csIsBusy = false;
std::chrono::high_resolution_clock::time_point m_lastFlush
= std::chrono::high_resolution_clock::now();
HRESULT MapBuffer( HRESULT MapBuffer(
D3D11Buffer* pResource, D3D11Buffer* pResource,
D3D11_MAP MapType, D3D11_MAP MapType,
@ -82,6 +88,8 @@ namespace dxvk {
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final; void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
void FlushImplicit();
}; };
} }