diff --git a/include/boo/graphicsdev/D3D.hpp b/include/boo/graphicsdev/D3D.hpp index 252e661..4363054 100644 --- a/include/boo/graphicsdev/D3D.hpp +++ b/include/boo/graphicsdev/D3D.hpp @@ -22,6 +22,7 @@ namespace boo class ID3DDataFactory : public IGraphicsDataFactory { public: + virtual ~ID3DDataFactory() {} bool bindingNeedsVertexFormat() const {return false;} virtual IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, ComPtr& vertBlobOut, ComPtr& fragBlobOut, diff --git a/lib/graphicsdev/D3D11.cpp b/lib/graphicsdev/D3D11.cpp index 00a45b2..a94a768 100644 --- a/lib/graphicsdev/D3D11.cpp +++ b/lib/graphicsdev/D3D11.cpp @@ -705,13 +705,18 @@ struct D3D11CommandQueue : IGraphicsCommandQueue ThrowIfFailed(ctx->m_dev->CreateDeferredContext1(0, &m_dynamicCtx)); } - ~D3D11CommandQueue() + void stopRenderer() { m_running = false; m_cv.notify_one(); m_thr.join(); } + ~D3D11CommandQueue() + { + if (m_running) stopRenderer(); + } + void setShaderDataBinding(IShaderDataBinding* binding) { D3D11ShaderDataBinding* cbind = static_cast(binding); @@ -873,11 +878,25 @@ class D3D11DataFactory : public ID3DDataFactory D3D11Data* m_deferredData = nullptr; struct D3D11Context* m_ctx; std::unordered_set m_committedData; + + void destroyData(IGraphicsData* d) + { + D3D11Data* data = static_cast(d); + m_committedData.erase(data); + delete data; + } + + void destroyAllData() + { + for (IGraphicsData* data : m_committedData) + delete static_cast(data); + m_committedData.clear(); + } public: D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx) : m_parent(parent), m_deferredData(new struct D3D11Data()), m_ctx(ctx) {} - ~D3D11DataFactory() = default; + ~D3D11DataFactory() {destroyAllData();} Platform platform() const {return Platform::D3D11;} const SystemChar* platformName() const {return _S("D3D11");} @@ -1014,26 +1033,12 @@ public: m_deferredData = new struct D3D11Data(); } - IGraphicsData* commit() + IGraphicsDataToken commit() { D3D11Data* retval = m_deferredData; m_deferredData = new struct D3D11Data(); m_committedData.insert(retval); - return retval; - } - - void destroyData(IGraphicsData* d) - { - D3D11Data* data = static_cast(d); - m_committedData.erase(data); - delete data; - } - - void destroyAllData() - { - for (IGraphicsData* data : m_committedData) - delete static_cast(data); - m_committedData.clear(); + return IGraphicsDataToken(this, retval); } }; diff --git a/lib/graphicsdev/D3D12.cpp b/lib/graphicsdev/D3D12.cpp index d9789ff..28d4eb7 100644 --- a/lib/graphicsdev/D3D12.cpp +++ b/lib/graphicsdev/D3D12.cpp @@ -888,6 +888,9 @@ struct D3D12CommandQueue : IGraphicsCommandQueue HANDLE m_dynamicBufFenceHandle; bool m_dynamicNeedsReset = false; + HANDLE m_renderFenceHandle; + bool m_running = true; + size_t m_fillBuf = 0; size_t m_drawBuf = 0; @@ -940,6 +943,7 @@ struct D3D12CommandQueue : IGraphicsCommandQueue ThrowIfFailed(ctx->m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_fence)); ThrowIfFailed(ctx->m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, ctx->m_qalloc[0].Get(), nullptr, __uuidof(ID3D12GraphicsCommandList), &m_cmdList)); + m_renderFenceHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr); m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get()); ThrowIfFailed(ctx->m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_dynamicBufFence)); @@ -952,6 +956,21 @@ struct D3D12CommandQueue : IGraphicsCommandQueue nullptr, __uuidof(ID3D12GraphicsCommandList), &m_dynamicCmdList)); } + void stopRenderer() + { + m_running = false; + if (m_fence->GetCompletedValue() < m_submittedFenceVal) + { + ThrowIfFailed(m_fence->SetEventOnCompletion(m_submittedFenceVal, m_renderFenceHandle)); + WaitForSingleObject(m_renderFenceHandle, INFINITE); + } + } + + ~D3D12CommandQueue() + { + if (m_running) stopRenderer(); + } + void setShaderDataBinding(IShaderDataBinding* binding) { D3D12ShaderDataBinding* cbind = static_cast(binding); @@ -1200,6 +1219,20 @@ class D3D12DataFactory : public ID3DDataFactory D3D12Data* m_deferredData = nullptr; struct D3D12Context* m_ctx; std::unordered_set m_committedData; + + void destroyData(IGraphicsData* d) + { + D3D12Data* data = static_cast(d); + m_committedData.erase(data); + delete data; + } + + void destroyAllData() + { + for (IGraphicsData* data : m_committedData) + delete static_cast(data); + m_committedData.clear(); + } public: D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx) : m_parent(parent), m_deferredData(new struct D3D12Data()), m_ctx(ctx) @@ -1222,7 +1255,7 @@ public: ThrowIfFailed(ctx->m_dev->CreateRootSignature(0, rsOutBlob->GetBufferPointer(), rsOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), &ctx->m_rs)); } - ~D3D12DataFactory() = default; + ~D3D12DataFactory() {destroyAllData();} Platform platform() const {return Platform::D3D12;} const SystemChar* platformName() const {return _S("D3D12");} @@ -1360,7 +1393,7 @@ public: m_deferredData = new struct D3D12Data(); } - IGraphicsData* commit() + IGraphicsDataToken commit() { D3D12Data* retval = static_cast(m_deferredData); @@ -1461,26 +1494,15 @@ public: /* All set! */ m_deferredData = new struct D3D12Data(); m_committedData.insert(retval); - return retval; - } - - void destroyData(IGraphicsData* d) - { - D3D12Data* data = static_cast(d); - m_committedData.erase(data); - delete data; - } - - void destroyAllData() - { - for (IGraphicsData* data : m_committedData) - delete static_cast(data); - m_committedData.clear(); + return IGraphicsDataToken(this, retval); } }; void D3D12CommandQueue::execute() { + if (!m_running) + return; + /* Stage dynamic uploads */ D3D12DataFactory* gfxF = static_cast(m_parent->getDataFactory()); for (D3D12Data* d : gfxF->m_committedData)