1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 20:52:10 +01:00

Merge branch 'auto-flush-v2'

This commit is contained in:
Philip Rebohle 2018-06-05 18:46:46 +02:00
commit 6579b2ad99
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
10 changed files with 64 additions and 40 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();
};

View File

@ -333,6 +333,17 @@ namespace dxvk {
void unlockSubmission() {
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

View File

@ -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;
}
}
}

View File

@ -14,8 +14,6 @@ namespace dxvk {
/**
* \brief Submission queue
*
*
*/
class DxvkSubmissionQueue {
@ -23,7 +21,28 @@ 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;