mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-03 22:24:13 +01:00
[d3d11] Add functions to emit externally generated CS chunks
This commit is contained in:
parent
abd888a0bb
commit
438a08f87c
@ -886,6 +886,15 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D11ImmediateContext::EmitCsChunkExternal(
|
||||
DxvkCsChunkRef&& Chunk,
|
||||
bool Synchronize) {
|
||||
// Do not update the sequence number when emitting a chunk
|
||||
// from an external source since that would break tracking
|
||||
m_csThread.injectChunk(std::move(Chunk), Synchronize);
|
||||
}
|
||||
|
||||
|
||||
void D3D11ImmediateContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
|
||||
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
|
||||
}
|
||||
|
@ -97,6 +97,10 @@ namespace dxvk {
|
||||
return m_multithread.AcquireLock();
|
||||
}
|
||||
|
||||
void EmitCsChunkExternal(
|
||||
DxvkCsChunkRef&& Chunk,
|
||||
bool Synchronize);
|
||||
|
||||
private:
|
||||
|
||||
DxvkCsThread m_csThread;
|
||||
|
@ -125,6 +125,22 @@ namespace dxvk {
|
||||
m_condOnAdd.notify_one();
|
||||
return seq;
|
||||
}
|
||||
|
||||
|
||||
void DxvkCsThread::injectChunk(DxvkCsChunkRef&& chunk, bool synchronize) {
|
||||
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
uint64_t timeline = ++m_chunksInjectedCount;
|
||||
m_chunksInjected.push_back(std::move(chunk));
|
||||
|
||||
m_condOnAdd.notify_one();
|
||||
|
||||
if (synchronize) {
|
||||
m_condOnSync.wait(lock, [this, timeline] {
|
||||
return m_chunksInjectedComplete.load() >= timeline;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkCsThread::synchronize(uint64_t seq) {
|
||||
@ -163,14 +179,18 @@ namespace dxvk {
|
||||
|
||||
try {
|
||||
while (!m_stopped.load()) {
|
||||
bool injected = false;
|
||||
|
||||
{ std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
m_condOnAdd.wait(lock, [this] {
|
||||
return (!m_chunksQueued.empty())
|
||||
|| (!m_chunksInjected.empty())
|
||||
|| (m_stopped.load());
|
||||
});
|
||||
|
||||
std::swap(chunks, m_chunksQueued);
|
||||
injected = !m_chunksInjected.empty();
|
||||
std::swap(chunks, injected ? m_chunksInjected : m_chunksQueued);
|
||||
}
|
||||
|
||||
for (auto& chunk : chunks) {
|
||||
@ -182,7 +202,7 @@ namespace dxvk {
|
||||
// will only ever be contested if synchronization is
|
||||
// actually necessary.
|
||||
{ std::unique_lock<dxvk::mutex> lock(m_counterMutex);
|
||||
m_chunksExecuted += 1;
|
||||
(injected ? m_chunksInjectedComplete : m_chunksExecuted) += 1u;
|
||||
m_condOnSync.notify_one();
|
||||
}
|
||||
|
||||
|
@ -183,6 +183,11 @@ namespace dxvk {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool push(T&& command) {
|
||||
return push(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a command with data to the chunk
|
||||
*
|
||||
@ -398,7 +403,20 @@ namespace dxvk {
|
||||
* \returns Sequence number of the submission
|
||||
*/
|
||||
uint64_t dispatchChunk(DxvkCsChunkRef&& chunk);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Injects chunk into the command stream
|
||||
*
|
||||
* This is meant to be used when serialized execution is required
|
||||
* from a thread other than the main thread recording rendering
|
||||
* commands. The context can still be safely accessed, but chunks
|
||||
* will not be executed in any particular oder. These chunks also
|
||||
* do not contribute to the main timeline.
|
||||
* \param [in] chunk The chunk to dispatch
|
||||
* \param [in] synchronize Whether to wait for execution to complete
|
||||
*/
|
||||
void injectChunk(DxvkCsChunkRef&& chunk, bool synchronize);
|
||||
|
||||
/**
|
||||
* \brief Synchronizes with the thread
|
||||
*
|
||||
@ -428,12 +446,16 @@ namespace dxvk {
|
||||
dxvk::mutex m_counterMutex;
|
||||
std::atomic<uint64_t> m_chunksDispatched = { 0ull };
|
||||
std::atomic<uint64_t> m_chunksExecuted = { 0ull };
|
||||
|
||||
std::atomic<uint64_t> m_chunksInjectedCount = { 0ull };
|
||||
std::atomic<uint64_t> m_chunksInjectedComplete = { 0ull };
|
||||
|
||||
std::atomic<bool> m_stopped = { false };
|
||||
dxvk::mutex m_mutex;
|
||||
dxvk::condition_variable m_condOnAdd;
|
||||
dxvk::condition_variable m_condOnSync;
|
||||
std::vector<DxvkCsChunkRef> m_chunksQueued;
|
||||
std::vector<DxvkCsChunkRef> m_chunksInjected;
|
||||
dxvk::thread m_thread;
|
||||
|
||||
void threadFunc();
|
||||
|
Loading…
Reference in New Issue
Block a user