From 824128c6f1e9ff990538a75fcf55e42ff5cfccc4 Mon Sep 17 00:00:00 2001 From: jackun Date: Tue, 28 Jul 2020 14:34:34 +0300 Subject: [PATCH] Fix some more references, one ID3D12Device ref to go --- src/kiero/d3d12_impl.cpp | 135 +++++++++++++++++++++++++++++---------- src/kiero/d3d12_impl.h | 25 ++++---- src/kiero/dx_shared.cpp | 4 +- src/kiero/main.cpp | 38 ++++++++++- 4 files changed, 153 insertions(+), 49 deletions(-) diff --git a/src/kiero/d3d12_impl.cpp b/src/kiero/d3d12_impl.cpp index 1f004a0b..bbba1e31 100644 --- a/src/kiero/d3d12_impl.cpp +++ b/src/kiero/d3d12_impl.cpp @@ -14,6 +14,10 @@ #include "dx_shared.h" #include +#ifdef _MSC_VER +#pragma comment(lib, "dxguid") // WKPDID_D3DDebugObjectName +#endif + using namespace Microsoft::WRL; decltype(&IDXGISwapChain3::Present) oPresent = nullptr; @@ -22,27 +26,47 @@ HRESULT(*oSignalD3D12)(ID3D12CommandQueue*, ID3D12Fence*, UINT64) = nullptr; PresentD3D12 oPresentD3D12; tResizeBuffers oResizeBuffers; -ComPtr d3d12DescriptorHeapBackBuffers; -ComPtr d3d12DescriptorHeapImGuiRender; -ComPtr d3d12CommandList; -ComPtr d3d12Fence; -UINT64 d3d12FenceValue = 0; -ComPtr d3d12CommandQueue; -ComPtr d3d12Device; -bool initDX12 = false; +static ComPtr d3d12DescriptorHeapBackBuffers; +static ComPtr d3d12DescriptorHeapImGuiRender; +static ComPtr d3d12CommandList; +static ComPtr d3d12Fence; +static UINT64 d3d12FenceValue = 0; +static ComPtr d3d12CommandQueue; +static ComPtr d3d12Device; +static bool initDX12 = false; struct FrameContext { - ID3D12CommandAllocator* commandAllocator = nullptr; - ID3D12Resource* main_render_target_resource = nullptr; + ComPtr commandAllocator; + ComPtr main_render_target_resource; D3D12_CPU_DESCRIPTOR_HANDLE main_render_target_descriptor; }; std::vector frameContext; +#ifndef NDEBUG +static const char* dbgNames[]{ + "d3d12DescriptorHeapImGuiRender", + "allocator", + "d3d12CommandList", + "d3d12DescriptorHeapBackBuffers", + "pBackBuffer", + "d3d12Device", + "pSwapChain", +}; +#endif + bool DX12Init(IDXGISwapChain* pSwapChain) { if (SUCCEEDED(pSwapChain->GetDevice(IID_PPV_ARGS(&d3d12Device)))) { +#if 0 //ndef NDEBUG + // Gets enabled in debug build anyway? + ID3D12Debug* pDebug = NULL; + D3D12GetDebugInterface(__uuidof(ID3D12Debug), (void**)&pDebug); + pDebug->EnableDebugLayer(); + pDebug->Release(); +#endif + imgui_create(pSwapChain, d3d12Device.Get()); ImGui::SetCurrentContext(state.imgui_ctx); //CreateEvent(nullptr, false, false, nullptr); @@ -50,6 +74,7 @@ bool DX12Init(IDXGISwapChain* pSwapChain) DXGI_SWAP_CHAIN_DESC sdesc; pSwapChain->GetDesc(&sdesc); + frameContext.clear(); frameContext.resize(sdesc.BufferCount); D3D12_DESCRIPTOR_HEAP_DESC descriptorImGuiRender = {}; @@ -59,9 +84,9 @@ bool DX12Init(IDXGISwapChain* pSwapChain) if (FAILED(d3d12Device->CreateDescriptorHeap(&descriptorImGuiRender, IID_PPV_ARGS(&d3d12DescriptorHeapImGuiRender)))) return false; - ID3D12CommandAllocator* allocator; - if (FAILED(d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)))) - return false; + ID3D12CommandAllocator *allocator; + if (FAILED(d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)))) + return false; for (size_t i = 0; i < frameContext.size(); i++) { frameContext[i].commandAllocator = allocator; @@ -92,8 +117,25 @@ bool DX12Init(IDXGISwapChain* pSwapChain) pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); d3d12Device->CreateRenderTargetView(pBackBuffer, nullptr, rtvHandle); frameContext[i].main_render_target_resource = pBackBuffer; + pBackBuffer->Release(); rtvHandle.ptr += rtvDescriptorSize; +#ifndef NDEBUG + pBackBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[4]) - 1, dbgNames[4]); +#endif } + +#ifndef NDEBUG + d3d12DescriptorHeapImGuiRender->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[0]) - 1, dbgNames[0]); + allocator->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[1]) - 1, dbgNames[1]); + d3d12CommandList->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[2]) - 1, dbgNames[2]); + d3d12DescriptorHeapBackBuffers->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[3]) - 1, dbgNames[3]); + d3d12Device->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[5]) - 1, dbgNames[5]); + pSwapChain->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof(dbgNames[6]) - 1, dbgNames[6]); +#endif + + // Already ref'ed in frameContext so release this reference + allocator->Release(); + auto mainWindow = sdesc.OutputWindow; ImGui_ImplWin32_Init(sdesc.OutputWindow); ImGui_ImplDX12_Init(d3d12Device.Get(), frameContext.size(), @@ -130,12 +172,12 @@ long __fastcall hkPresent12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT D3D12_RESOURCE_BARRIER barrier; barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = currentFrameContext.main_render_target_resource; + barrier.Transition.pResource = currentFrameContext.main_render_target_resource.Get(); barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; - d3d12CommandList->Reset(currentFrameContext.commandAllocator, nullptr); + d3d12CommandList->Reset(currentFrameContext.commandAllocator.Get(), nullptr); d3d12CommandList->ResourceBarrier(1, &barrier); d3d12CommandList->OMSetRenderTargets(1, ¤tFrameContext.main_render_target_descriptor, FALSE, nullptr); d3d12CommandList->SetDescriptorHeaps(1, d3d12DescriptorHeapImGuiRender.GetAddressOf()); @@ -151,7 +193,7 @@ long __fastcall hkPresent12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT d3d12CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList * const *)d3d12CommandList.GetAddressOf()); - //ImGui::SetCurrentContext(prev_ctx); + ImGui::SetCurrentContext(prev_ctx); return std::invoke(oPresent, pSwapChain, SyncInterval, Flags); } @@ -173,30 +215,18 @@ HRESULT hookSignalD3D12(ID3D12CommandQueue* queue, ID3D12Fence* fence, UINT64 va HRESULT __stdcall hkResizeBuffers(IDXGISwapChain* pThis, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) { - auto allocator = frameContext[0].commandAllocator; - auto rtvHandle = frameContext[0].main_render_target_descriptor; - for (size_t i = 0; i < frameContext.size(); i++) { - frameContext[i].main_render_target_resource->Release(); - } + auto ctx = ImGui::GetCurrentContext(); + ImGui::SetCurrentContext(state.imgui_ctx); + ImGui_ImplDX12_Shutdown(); + ImGui::SetCurrentContext(ctx); + + frameContext.clear(); auto hr = oResizeBuffers(pThis, BufferCount, Width, Height, NewFormat, SwapChainFlags); if (hr != S_OK) printf("ResizeBuffers Failed\n"); - frameContext.resize(BufferCount); - - const auto rtvDescriptorSize = d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - for (size_t i = 0; i < frameContext.size(); i++) { - ID3D12Resource* pBackBuffer = nullptr; - - frameContext[i].main_render_target_descriptor = rtvHandle; - pThis->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); - d3d12Device->CreateRenderTargetView(pBackBuffer, nullptr, rtvHandle); - frameContext[i].main_render_target_resource = pBackBuffer; - rtvHandle.ptr += rtvDescriptorSize; - } - - ImGui_ImplDX12_Resize(BufferCount); + DX12Init(pThis); return hr; } @@ -213,4 +243,39 @@ void impl::d3d12::init() assert(ret == kiero::Status::Success); } +void impl::d3d12::uninit() +{ + printf("uninit dx12\n"); + kiero::unbind(54); + kiero::unbind(58); + kiero::unbind(140); + kiero::unbind(145); + +#ifndef NDEBUG + ID3D12DebugDevice* pDebugDevice = NULL; + d3d12Device->QueryInterface(&pDebugDevice); +#endif + + if (state.imgui_ctx) { + auto ctx = ImGui::GetCurrentContext(); + ImGui::SetCurrentContext(state.imgui_ctx); + ImGui_ImplDX12_Shutdown(); + ImGui::DestroyContext(state.imgui_ctx); + state.imgui_ctx = nullptr; + ImGui::SetCurrentContext(ctx); + } + frameContext.clear(); + d3d12DescriptorHeapBackBuffers.Reset(); + d3d12DescriptorHeapImGuiRender.Reset(); + d3d12CommandList.Reset(); + d3d12Fence.Reset(); + d3d12CommandQueue.Reset(); + d3d12Device.Reset(); + +#ifndef NDEBUG + pDebugDevice->ReportLiveDeviceObjects(D3D12_RLDO_DETAIL | D3D12_RLDO_IGNORE_INTERNAL); + pDebugDevice->Release(); +#endif +} + #endif // KIERO_INCLUDE_D3D12 diff --git a/src/kiero/d3d12_impl.h b/src/kiero/d3d12_impl.h index 29d48688..adf17e5f 100644 --- a/src/kiero/d3d12_impl.h +++ b/src/kiero/d3d12_impl.h @@ -10,21 +10,22 @@ namespace impl namespace d3d12 { void init(); + void uninit(); } } +typedef long(__fastcall* PresentD3D12) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); +typedef HRESULT(__stdcall* tResizeBuffers)(IDXGISwapChain* pThis, UINT BufferCount, UINT Width, + UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags); -#endif // __D3D12_IMPL_H__ - typedef long(__fastcall* PresentD3D12) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); - extern PresentD3D12 oPresentD3D12; - extern void(*oExecuteCommandListsD3D12)(ID3D12CommandQueue*, UINT, ID3D12CommandList*); - typedef HRESULT(__stdcall* tResizeBuffers)(IDXGISwapChain* pThis, UINT BufferCount, UINT Width, - UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags); - extern tResizeBuffers oResizeBuffers; +extern PresentD3D12 oPresentD3D12; +extern void(*oExecuteCommandListsD3D12)(ID3D12CommandQueue*, UINT, ID3D12CommandList*); +extern tResizeBuffers oResizeBuffers; + +typedef void(__fastcall* DrawInstancedD3D12)(ID3D12GraphicsCommandList* dCommandList, UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation); +extern DrawInstancedD3D12 oDrawInstancedD3D12; - extern tResizeBuffers oResizeBuffers; - typedef void(__fastcall* DrawInstancedD3D12)(ID3D12GraphicsCommandList* dCommandList, UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation); - extern DrawInstancedD3D12 oDrawInstancedD3D12; +typedef void(__fastcall* DrawIndexedInstancedD3D12)(ID3D12GraphicsCommandList* dCommandList, UINT IndexCount, UINT InstanceCount, UINT StartIndex, INT BaseVertex); +extern DrawIndexedInstancedD3D12 oDrawIndexedInstancedD3D12; - typedef void(__fastcall* DrawIndexedInstancedD3D12)(ID3D12GraphicsCommandList* dCommandList, UINT IndexCount, UINT InstanceCount, UINT StartIndex, INT BaseVertex); - extern DrawIndexedInstancedD3D12 oDrawIndexedInstancedD3D12; +#endif // __D3D12_IMPL_H__ diff --git a/src/kiero/dx_shared.cpp b/src/kiero/dx_shared.cpp index fca2693b..0a5e92c2 100644 --- a/src/kiero/dx_shared.cpp +++ b/src/kiero/dx_shared.cpp @@ -38,6 +38,8 @@ void imgui_create(void *ctx, void *device) pDXGIDevice->GetAdapter(&pDXGIAdapter); DXGI_ADAPTER_DESC adapterDesc; hr = pDXGIAdapter->GetDesc(&adapterDesc); + pDXGIAdapter->Release(); + pDXGIDevice->Release(); if (S_OK == hr) { vendorID = adapterDesc.VendorId; @@ -78,4 +80,4 @@ void imgui_create(void *ctx, void *device) // Restore global context or ours might clash with apps that use Dear ImGui ImGui::SetCurrentContext(saved_ctx); -} \ No newline at end of file +} diff --git a/src/kiero/main.cpp b/src/kiero/main.cpp index 57dfea99..1e58b8fb 100644 --- a/src/kiero/main.cpp +++ b/src/kiero/main.cpp @@ -80,6 +80,39 @@ int kieroExampleThread() return 0; } +void kieroShutdownThread() +{ + switch (kiero::getRenderType()) + { +#if KIERO_INCLUDE_D3D9 + case kiero::RenderType::D3D9: + //impl::d3d9::uninit(); + break; +#endif +#if KIERO_INCLUDE_D3D10 + case kiero::RenderType::D3D10: + impl::d3d10::uninit(); + break; +#endif +#if KIERO_INCLUDE_D3D11 + case kiero::RenderType::D3D11: + //impl::d3d11::uninit(); + break; +#endif +#if KIERO_INCLUDE_D3D12 + case kiero::RenderType::D3D12: + impl::d3d12::uninit(); + break; +#endif + case kiero::RenderType::OpenGL: + // TODO: OpenGL implementation? + break; + case kiero::RenderType::Vulkan: + // TODO: Vulcan implementation? + break; + } +} + BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID) { @@ -90,7 +123,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID) case DLL_PROCESS_ATTACH: CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)kieroExampleThread, NULL, 0, NULL); break; + case DLL_PROCESS_DETACH: + kieroShutdownThread(); + break; } return TRUE; -} \ No newline at end of file +}