mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 01:24:12 +01:00
[d3d11] Implemented CS chunk submission for deferred contexts
Changes were necessary due to the fact that chunks in deferred contexts are not directly submitted to the CS thread.
This commit is contained in:
parent
eff07dcf3f
commit
3148155c35
@ -34,4 +34,23 @@ namespace dxvk {
|
|||||||
return m_contextFlags;
|
return m_contextFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11CommandList::AddChunk(Rc<DxvkCsChunk>&& Chunk) {
|
||||||
|
m_chunks.push_back(std::move(Chunk));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11CommandList::EmitToCommandList(ID3D11CommandList* pCommandList) {
|
||||||
|
auto cmdList = static_cast<D3D11CommandList*>(pCommandList);
|
||||||
|
|
||||||
|
for (auto chunk : m_chunks)
|
||||||
|
cmdList->m_chunks.push_back(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11CommandList::EmitToCsThread(const Rc<DxvkCsThread>& CsThread) {
|
||||||
|
for (auto chunk : m_chunks)
|
||||||
|
CsThread->dispatchChunk(Rc<DxvkCsChunk>(chunk));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d11_device_child.h"
|
#include "d3d11_context.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
class D3D11Device;
|
|
||||||
|
|
||||||
class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList> {
|
class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -25,11 +23,21 @@ namespace dxvk {
|
|||||||
|
|
||||||
UINT GetContextFlags();
|
UINT GetContextFlags();
|
||||||
|
|
||||||
|
void AddChunk(Rc<DxvkCsChunk>&& Chunk);
|
||||||
|
|
||||||
|
void EmitToCommandList(
|
||||||
|
ID3D11CommandList* pCommandList);
|
||||||
|
|
||||||
|
void EmitToCsThread(
|
||||||
|
const Rc<DxvkCsThread>& CsThread);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
D3D11Device* const m_device;
|
D3D11Device* const m_device;
|
||||||
UINT const m_contextFlags;
|
UINT const m_contextFlags;
|
||||||
|
|
||||||
|
std::vector<Rc<DxvkCsChunk>> m_chunks;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -568,12 +568,21 @@ namespace dxvk {
|
|||||||
template<typename Cmd>
|
template<typename Cmd>
|
||||||
void EmitCs(Cmd&& command) {
|
void EmitCs(Cmd&& command) {
|
||||||
if (!m_csChunk->push(command)) {
|
if (!m_csChunk->push(command)) {
|
||||||
EmitCsChunk();
|
EmitCsChunk(std::move(m_csChunk));
|
||||||
|
|
||||||
|
m_csChunk = new DxvkCsChunk();
|
||||||
m_csChunk->push(command);
|
m_csChunk->push(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void EmitCsChunk() = 0;
|
void FlushCsChunk() {
|
||||||
|
if (m_csChunk->commandCount() != 0) {
|
||||||
|
EmitCsChunk(std::move(m_csChunk));
|
||||||
|
m_csChunk = new DxvkCsChunk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ namespace dxvk {
|
|||||||
Rc<DxvkDevice> Device,
|
Rc<DxvkDevice> Device,
|
||||||
UINT ContextFlags)
|
UINT ContextFlags)
|
||||||
: D3D11DeviceContext(pParent, Device),
|
: D3D11DeviceContext(pParent, Device),
|
||||||
m_contextFlags(ContextFlags) {
|
m_contextFlags(ContextFlags),
|
||||||
|
m_commandList (CreateCommandList()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +61,13 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11DeferredContext::EmitCsChunk() {
|
Com<D3D11CommandList> D3D11DeferredContext::CreateCommandList() {
|
||||||
|
return new D3D11CommandList(m_parent, m_contextFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11DeferredContext::EmitCsChunk(Rc<DxvkCsChunk>&& chunk) {
|
||||||
|
m_commandList->AddChunk(std::move(chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "d3d11_cmdlist.h"
|
||||||
#include "d3d11_context.h"
|
#include "d3d11_context.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -42,7 +43,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
const UINT m_contextFlags;
|
const UINT m_contextFlags;
|
||||||
|
|
||||||
void EmitCsChunk() final;
|
Com<D3D11CommandList> m_commandList;
|
||||||
|
|
||||||
|
Com<D3D11CommandList> CreateCommandList();
|
||||||
|
|
||||||
|
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ namespace dxvk {
|
|||||||
dev->createCommandList());
|
dev->createCommandList());
|
||||||
});
|
});
|
||||||
|
|
||||||
EmitCsChunk();
|
FlushCsChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ namespace dxvk {
|
|||||||
void D3D11ImmediateContext::SynchronizeCsThread() {
|
void D3D11ImmediateContext::SynchronizeCsThread() {
|
||||||
// Dispatch current chunk so that all commands
|
// Dispatch current chunk so that all commands
|
||||||
// recorded prior to this function will be run
|
// recorded prior to this function will be run
|
||||||
EmitCsChunk();
|
FlushCsChunk();
|
||||||
|
|
||||||
m_csThread.synchronize();
|
m_csThread.synchronize();
|
||||||
}
|
}
|
||||||
@ -266,9 +266,8 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11ImmediateContext::EmitCsChunk() {
|
void D3D11ImmediateContext::EmitCsChunk(Rc<DxvkCsChunk>&& chunk) {
|
||||||
if (m_csChunk->commandCount() > 0)
|
m_csThread.dispatchChunk(std::move(chunk));
|
||||||
m_csChunk = m_csThread.dispatchChunk(std::move(m_csChunk));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -50,7 +50,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
void SynchronizeDevice();
|
void SynchronizeDevice();
|
||||||
|
|
||||||
void EmitCsChunk() final;
|
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,9 +40,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkCsChunk> DxvkCsThread::dispatchChunk(Rc<DxvkCsChunk>&& chunk) {
|
void DxvkCsThread::dispatchChunk(Rc<DxvkCsChunk>&& chunk) {
|
||||||
Rc<DxvkCsChunk> nextChunk = nullptr;
|
|
||||||
|
|
||||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_chunksQueued.push(std::move(chunk));
|
m_chunksQueued.push(std::move(chunk));
|
||||||
m_chunksPending += 1;
|
m_chunksPending += 1;
|
||||||
@ -56,21 +54,10 @@ namespace dxvk {
|
|||||||
|| (m_stopped.load());
|
|| (m_stopped.load());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_chunksUnused.size() != 0) {
|
|
||||||
nextChunk = std::move(m_chunksUnused.front());
|
|
||||||
m_chunksUnused.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wake CS thread
|
// Wake CS thread
|
||||||
m_condOnAdd.notify_one();
|
m_condOnAdd.notify_one();
|
||||||
|
|
||||||
// Allocate new chunk if needed
|
|
||||||
if (nextChunk == nullptr)
|
|
||||||
nextChunk = new DxvkCsChunk();
|
|
||||||
|
|
||||||
return nextChunk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,8 +77,6 @@ namespace dxvk {
|
|||||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
if (chunk != nullptr) {
|
if (chunk != nullptr) {
|
||||||
m_chunksPending -= 1;
|
m_chunksPending -= 1;
|
||||||
m_chunksUnused.push(std::move(chunk));
|
|
||||||
|
|
||||||
m_condOnSync.notify_one();
|
m_condOnSync.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,9 +152,8 @@ namespace dxvk {
|
|||||||
* Can be used to efficiently play back large
|
* Can be used to efficiently play back large
|
||||||
* command lists recorded on another thread.
|
* command lists recorded on another thread.
|
||||||
* \param [in] chunk The chunk to dispatch
|
* \param [in] chunk The chunk to dispatch
|
||||||
* \returns New chunk for the next submissions
|
|
||||||
*/
|
*/
|
||||||
Rc<DxvkCsChunk> dispatchChunk(Rc<DxvkCsChunk>&& chunk);
|
void dispatchChunk(Rc<DxvkCsChunk>&& chunk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Synchronizes with the thread
|
* \brief Synchronizes with the thread
|
||||||
@ -175,7 +174,6 @@ namespace dxvk {
|
|||||||
std::condition_variable m_condOnAdd;
|
std::condition_variable m_condOnAdd;
|
||||||
std::condition_variable m_condOnSync;
|
std::condition_variable m_condOnSync;
|
||||||
std::queue<Rc<DxvkCsChunk>> m_chunksQueued;
|
std::queue<Rc<DxvkCsChunk>> m_chunksQueued;
|
||||||
std::queue<Rc<DxvkCsChunk>> m_chunksUnused;
|
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
||||||
uint32_t m_chunksPending = 0;
|
uint32_t m_chunksPending = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user