[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(
Rc<DxvkCsChunk>&& Chunk,
UINT DrawCount) {
Rc<DxvkCsChunk>&& Chunk) {
m_chunks.push_back(std::move(Chunk));
m_drawCount += DrawCount;
}
@ -54,8 +52,6 @@ namespace dxvk {
for (const auto& chunk : m_chunks)
cmdList->m_chunks.push_back(chunk);
cmdList->m_drawCount += m_drawCount;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -63,8 +63,8 @@ namespace dxvk {
FlushCsChunk();
// Reset optimization info
m_drawCount = 0;
m_csIsBusy = false;
m_lastFlush = std::chrono::high_resolution_clock::now();
}
}
@ -80,8 +80,7 @@ namespace dxvk {
// As an optimization, flush everything if the
// number of pending draw calls is high enough.
if (m_drawCount >= MaxPendingDraws)
Flush();
FlushImplicit();
// Dispatch command list to the CS thread and
// restore the immediate context's state
@ -95,7 +94,6 @@ namespace dxvk {
// Mark CS thread as busy so that subsequent
// flush operations get executed correctly.
m_csIsBusy = true;
m_drawCount += commandList->GetDrawCount();
}
@ -202,8 +200,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 >= MaxPendingDraws)
Flush();
FlushImplicit();
D3D11DeviceContext::OMSetRenderTargets(
NumViews, ppRenderTargetViews, pDepthStencilView);
@ -386,5 +383,18 @@ namespace dxvk {
m_csThread.dispatchChunk(std::move(chunk));
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
#include <chrono>
#include "d3d11_context.h"
namespace dxvk {
@ -8,7 +10,8 @@ namespace dxvk {
class D3D11CommonTexture;
class D3D11ImmediateContext : public D3D11DeviceContext {
constexpr static UINT MaxPendingDraws = 500;
constexpr static uint32_t MinFlushIntervalUs = 2500;
constexpr static uint32_t MaxPendingSubmits = 2;
public:
D3D11ImmediateContext(
@ -56,6 +59,9 @@ namespace dxvk {
DxvkCsThread m_csThread;
bool m_csIsBusy = false;
std::chrono::high_resolution_clock::time_point m_lastFlush
= std::chrono::high_resolution_clock::now();
HRESULT MapBuffer(
D3D11Buffer* pResource,
@ -81,6 +87,8 @@ namespace dxvk {
UINT MapFlags);
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
void FlushImplicit();
};