1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +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( 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);
@ -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();
}
}
} }

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

View File

@ -333,6 +333,17 @@ namespace dxvk {
void unlockSubmission() { void unlockSubmission() {
m_submissionLock.unlock(); 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 * \brief Waits until the device becomes idle

View File

@ -27,6 +27,7 @@ namespace dxvk {
return m_entries.size() < MaxNumQueuedCommandBuffers; return m_entries.size() < MaxNumQueuedCommandBuffers;
}); });
m_submits += 1;
m_entries.push(cmdList); m_entries.push(cmdList);
m_condOnAdd.notify_one(); m_condOnAdd.notify_one();
} }
@ -65,6 +66,8 @@ namespace dxvk {
"DxvkSubmissionQueue: Failed to sync fence: ", "DxvkSubmissionQueue: Failed to sync fence: ",
status)); status));
} }
m_submits -= 1;
} }
} }
} }

View File

@ -14,8 +14,6 @@ namespace dxvk {
/** /**
* \brief Submission queue * \brief Submission queue
*
*
*/ */
class DxvkSubmissionQueue { class DxvkSubmissionQueue {
@ -23,7 +21,28 @@ namespace dxvk {
DxvkSubmissionQueue(DxvkDevice* device); DxvkSubmissionQueue(DxvkDevice* device);
~DxvkSubmissionQueue(); ~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); void submit(const Rc<DxvkCommandList>& cmdList);
private: private:
@ -31,6 +50,7 @@ namespace dxvk {
DxvkDevice* m_device; DxvkDevice* m_device;
std::atomic<bool> m_stopped = { false }; std::atomic<bool> m_stopped = { false };
std::atomic<uint32_t> m_submits = { 0u };
std::mutex m_mutex; std::mutex m_mutex;
std::condition_variable m_condOnAdd; std::condition_variable m_condOnAdd;