mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
Merge branch 'auto-flush-v2'
This commit is contained in:
commit
6579b2ad99
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -654,7 +654,6 @@ namespace dxvk {
|
||||
Com<D3D11RasterizerState> m_defaultRasterizerState;
|
||||
|
||||
D3D11ContextState m_state;
|
||||
UINT m_drawCount = 0;
|
||||
|
||||
void ApplyInputLayout();
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
@ -387,4 +384,17 @@ namespace dxvk {
|
||||
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
|
||||
|
||||
#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(
|
||||
@ -57,6 +60,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,
|
||||
D3D11_MAP MapType,
|
||||
@ -82,6 +88,8 @@ namespace dxvk {
|
||||
|
||||
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
||||
|
||||
void FlushImplicit();
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -334,6 +334,17 @@ namespace dxvk {
|
||||
m_submissionLock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Number of pending submissions
|
||||
*
|
||||
* A return value of 0 indicates
|
||||
* that the GPU is currently idle.
|
||||
* \returns Pending submission count
|
||||
*/
|
||||
uint32_t pendingSubmissions() const {
|
||||
return m_submissionQueue.pendingSubmissions();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Waits until the device becomes idle
|
||||
*
|
||||
|
@ -27,6 +27,7 @@ namespace dxvk {
|
||||
return m_entries.size() < MaxNumQueuedCommandBuffers;
|
||||
});
|
||||
|
||||
m_submits += 1;
|
||||
m_entries.push(cmdList);
|
||||
m_condOnAdd.notify_one();
|
||||
}
|
||||
@ -65,6 +66,8 @@ namespace dxvk {
|
||||
"DxvkSubmissionQueue: Failed to sync fence: ",
|
||||
status));
|
||||
}
|
||||
|
||||
m_submits -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,6 @@ namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Submission queue
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DxvkSubmissionQueue {
|
||||
|
||||
@ -24,6 +22,27 @@ namespace dxvk {
|
||||
DxvkSubmissionQueue(DxvkDevice* device);
|
||||
~DxvkSubmissionQueue();
|
||||
|
||||
/**
|
||||
* \brief Number of pending submissions
|
||||
*
|
||||
* A return value of 0 indicates
|
||||
* that the GPU is currently idle.
|
||||
* \returns Pending submission count
|
||||
*/
|
||||
uint32_t pendingSubmissions() const {
|
||||
return m_submits.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Submits a command list
|
||||
*
|
||||
* Submits a command list to the queue thread.
|
||||
* This thread will wait for the command list
|
||||
* to finish executing on the GPU and signal
|
||||
* any queries and events that are used by
|
||||
* the command list in question.
|
||||
* \param [in] cmdList The command list
|
||||
*/
|
||||
void submit(const Rc<DxvkCommandList>& cmdList);
|
||||
|
||||
private:
|
||||
@ -31,6 +50,7 @@ namespace dxvk {
|
||||
DxvkDevice* m_device;
|
||||
|
||||
std::atomic<bool> m_stopped = { false };
|
||||
std::atomic<uint32_t> m_submits = { 0u };
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_condOnAdd;
|
||||
|
Loading…
x
Reference in New Issue
Block a user