mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +01:00
[d3d11] Implement new auto-flush heuristic
This commit is contained in:
parent
cfe99368fb
commit
4a0c81276f
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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);
|
||||||
@ -386,5 +383,18 @@ namespace dxvk {
|
|||||||
m_csThread.dispatchChunk(std::move(chunk));
|
m_csThread.dispatchChunk(std::move(chunk));
|
||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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(
|
||||||
@ -56,6 +59,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,
|
||||||
@ -81,6 +87,8 @@ namespace dxvk {
|
|||||||
UINT MapFlags);
|
UINT MapFlags);
|
||||||
|
|
||||||
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
||||||
|
|
||||||
|
void FlushImplicit();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user