Deal with resizing and wrap things in ComPtr

Still leaks objects though :(
d3d12
jackun 4 years ago
parent eb83a379f3
commit 60ef67686a

@ -14,79 +14,78 @@
#include "dx_shared.h"
#include <winuser.h>
long(__stdcall* oPresent)(IDXGISwapChain3*, UINT, UINT) = nullptr;
using namespace Microsoft::WRL;
decltype(&IDXGISwapChain3::Present) oPresent = nullptr;
void(*oExecuteCommandListsD3D12)(ID3D12CommandQueue*, UINT, ID3D12CommandList*);
HRESULT(*oSignalD3D12)(ID3D12CommandQueue*, ID3D12Fence*, UINT64) = nullptr;
PresentD3D12 oPresentD3D12;
tResizeBuffers oResizeBuffers;
ID3D12Device* d3d12Device = nullptr;
IDXGISwapChain* pSwapChain_;
ID3D12DescriptorHeap* d3d12DescriptorHeapBackBuffers = nullptr;
ID3D12DescriptorHeap* d3d12DescriptorHeapImGuiRender = nullptr;
ID3D12GraphicsCommandList* d3d12CommandList = nullptr;
ID3D12Fence* d3d12Fence = nullptr;
UINT64 d3d12FenceValue = 0;
ID3D12CommandQueue* d3d12CommandQueue = nullptr;
using namespace Microsoft::WRL;
Microsoft::WRL::ComPtr<ID3D12CommandQueue> queue;
Microsoft::WRL::ComPtr<IDXGISwapChain3> swapchain_;
ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeapBackBuffers;
ComPtr<ID3D12DescriptorHeap> d3d12DescriptorHeapImGuiRender;
ComPtr<ID3D12GraphicsCommandList> d3d12CommandList;
ComPtr<ID3D12Fence> d3d12Fence;
UINT64 d3d12FenceValue = 0;
ComPtr<ID3D12CommandQueue> d3d12CommandQueue;
ComPtr<ID3D12Device> d3d12Device;
bool initDX12 = false;
struct FrameContext {
ID3D12CommandAllocator* commandAllocator = nullptr;
ID3D12Resource* main_render_target_resource = nullptr;
D3D12_CPU_DESCRIPTOR_HANDLE main_render_target_descriptor;
};
uint32_t buffersCounts = -1;
FrameContext* frameContext;
std::vector<FrameContext> frameContext;
bool DX12Init(IDXGISwapChain* pSwapChain)
{
if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D12Device), (void**)&d3d12Device))) {
if (SUCCEEDED(pSwapChain->GetDevice(IID_PPV_ARGS(&d3d12Device)))) {
pSwapChain_ = pSwapChain;
imgui_create(pSwapChain, d3d12Device);
imgui_create(pSwapChain, d3d12Device.Get());
ImGui::SetCurrentContext(state.imgui_ctx);
CreateEvent(nullptr, false, false, nullptr);
//CreateEvent(nullptr, false, false, nullptr);
DXGI_SWAP_CHAIN_DESC sdesc;
pSwapChain->GetDesc(&sdesc);
buffersCounts = sdesc.BufferCount;
frameContext = new FrameContext[buffersCounts];
frameContext.resize(sdesc.BufferCount);
D3D12_DESCRIPTOR_HEAP_DESC descriptorImGuiRender = {};
descriptorImGuiRender.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
descriptorImGuiRender.NumDescriptors = buffersCounts;
descriptorImGuiRender.NumDescriptors = sdesc.BufferCount;
descriptorImGuiRender.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
if (d3d12Device->CreateDescriptorHeap(&descriptorImGuiRender, __uuidof(ID3D12DescriptorHeap), (void**)&d3d12DescriptorHeapImGuiRender))
if (FAILED(d3d12Device->CreateDescriptorHeap(&descriptorImGuiRender, IID_PPV_ARGS(&d3d12DescriptorHeapImGuiRender))))
return false;
ID3D12CommandAllocator* allocator;
if (d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&allocator) < 0)
if (FAILED(d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator))))
return false;
for (size_t i = 0; i < buffersCounts; i++) {
for (size_t i = 0; i < frameContext.size(); i++) {
frameContext[i].commandAllocator = allocator;
}
if (d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, allocator, NULL, __uuidof(ID3D12GraphicsCommandList), (void**)&d3d12CommandList) < 0)
if (d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, allocator, NULL, IID_PPV_ARGS(&d3d12CommandList)) < 0)
return false;
// Reset() expects it to be closed, so close it now.
d3d12CommandList->Close();
D3D12_DESCRIPTOR_HEAP_DESC descriptorBackBuffers;
descriptorBackBuffers.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
descriptorBackBuffers.NumDescriptors = buffersCounts;
descriptorBackBuffers.NumDescriptors = sdesc.BufferCount;
descriptorBackBuffers.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
descriptorBackBuffers.NodeMask = 1;
if (d3d12Device->CreateDescriptorHeap(&descriptorBackBuffers, __uuidof(ID3D12DescriptorHeap), (void**)&d3d12DescriptorHeapBackBuffers) != S_OK)
if (d3d12Device->CreateDescriptorHeap(&descriptorBackBuffers, IID_PPV_ARGS(&d3d12DescriptorHeapBackBuffers)) != S_OK)
return false;
const auto rtvDescriptorSize = d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = d3d12DescriptorHeapBackBuffers->GetCPUDescriptorHandleForHeapStart();
for (size_t i = 0; i < buffersCounts; i++) {
for (size_t i = 0; i < frameContext.size(); i++) {
ID3D12Resource* pBackBuffer = nullptr;
frameContext[i].main_render_target_descriptor = rtvHandle;
@ -97,8 +96,8 @@ bool DX12Init(IDXGISwapChain* pSwapChain)
}
auto mainWindow = sdesc.OutputWindow;
ImGui_ImplWin32_Init(sdesc.OutputWindow);
ImGui_ImplDX12_Init(d3d12Device, buffersCounts,
DXGI_FORMAT_R8G8B8A8_UNORM, d3d12DescriptorHeapImGuiRender,
ImGui_ImplDX12_Init(d3d12Device.Get(), frameContext.size(),
DXGI_FORMAT_R8G8B8A8_UNORM, d3d12DescriptorHeapImGuiRender.Get(),
d3d12DescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(),
d3d12DescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart());
@ -113,8 +112,7 @@ long __fastcall hkPresent12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT
if (!initDX12)
{
DX12Init(pSwapChain);
initDX12 = true;
initDX12 = DX12Init(pSwapChain);
}
ImGui::SetCurrentContext(state.imgui_ctx);
@ -140,10 +138,10 @@ long __fastcall hkPresent12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT
d3d12CommandList->Reset(currentFrameContext.commandAllocator, nullptr);
d3d12CommandList->ResourceBarrier(1, &barrier);
d3d12CommandList->OMSetRenderTargets(1, &currentFrameContext.main_render_target_descriptor, FALSE, nullptr);
d3d12CommandList->SetDescriptorHeaps(1, &d3d12DescriptorHeapImGuiRender);
d3d12CommandList->SetDescriptorHeaps(1, d3d12DescriptorHeapImGuiRender.GetAddressOf());
// printf("imgui/d3d12 render\n");
ImGui::Render();
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), d3d12CommandList);
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), d3d12CommandList.Get());
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
@ -151,10 +149,10 @@ long __fastcall hkPresent12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT
d3d12CommandList->ResourceBarrier(1, &barrier);
d3d12CommandList->Close();
d3d12CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&d3d12CommandList);
d3d12CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList * const *)d3d12CommandList.GetAddressOf());
//ImGui::SetCurrentContext(prev_ctx);
return oPresent(pSwapChain, SyncInterval, Flags);
return std::invoke(oPresent, pSwapChain, SyncInterval, Flags);
}
void hookExecuteCommandListsD3D12(ID3D12CommandQueue* queue, UINT NumCommandLists, ID3D12CommandList* ppCommandLists) {
@ -165,7 +163,7 @@ void hookExecuteCommandListsD3D12(ID3D12CommandQueue* queue, UINT NumCommandList
}
HRESULT hookSignalD3D12(ID3D12CommandQueue* queue, ID3D12Fence* fence, UINT64 value) {
if (d3d12CommandQueue != nullptr && queue == d3d12CommandQueue) {
if (d3d12CommandQueue != nullptr && queue == d3d12CommandQueue.Get()) {
d3d12Fence = fence;
d3d12FenceValue = value;
}
@ -175,25 +173,30 @@ HRESULT hookSignalD3D12(ID3D12CommandQueue* queue, ID3D12Fence* fence, UINT64 va
HRESULT __stdcall hkResizeBuffers(IDXGISwapChain* pThis, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags)
{
//if (pSwapChain_) { pSwapChain_->Release(); pSwapChain_ = nullptr; }
if (d3d12CommandQueue) { d3d12CommandQueue->Release(); d3d12CommandQueue = nullptr; }
if (d3d12CommandList) { d3d12CommandList->Release(); d3d12CommandList = nullptr; }
if (d3d12Fence) { d3d12Fence->Release(); d3d12Fence = nullptr; }
if (d3d12DescriptorHeapBackBuffers) { d3d12DescriptorHeapBackBuffers->Release(); d3d12DescriptorHeapBackBuffers = nullptr; }
if (d3d12DescriptorHeapImGuiRender) { d3d12DescriptorHeapImGuiRender->Release(); d3d12DescriptorHeapImGuiRender = nullptr; }
for (uint32_t i = 0; i < sizeof(FrameContext); ++i)
{
frameContext[i] = {};
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();
}
//if (d3d12Device) { d3d12Device->Release(); d3d12Device = nullptr; }
ImGui_ImplDX12_Shutdown();
initDX12 = false;
auto hr = oResizeBuffers(pThis, BufferCount, Width, Height, NewFormat, SwapChainFlags);
if (hr != S_OK)
printf("ResizeBuffers Failed\n");
pSwapChain_ = pThis;
d3d12CommandQueue = queue.Get();
pSwapChain_->GetDevice(__uuidof(ID3D12Device), (void**)&d3d12Device);
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);
return hr;
}

@ -613,6 +613,30 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
}
}
void ImGui_ImplDX12_Resize(int num_frames_in_flight)
{
for (UINT i = 0; i < g_numFramesInFlight; i++)
{
FrameResources* fr = &g_pFrameResources[i];
SafeRelease(fr->IndexBuffer);
SafeRelease(fr->VertexBuffer);
}
delete[] g_pFrameResources;
g_pFrameResources = new FrameResources[num_frames_in_flight];
g_numFramesInFlight = num_frames_in_flight;
g_frameIndex = UINT_MAX;
for (int i = 0; i < num_frames_in_flight; i++)
{
FrameResources* fr = &g_pFrameResources[i];
fr->IndexBuffer = NULL;
fr->VertexBuffer = NULL;
fr->IndexBufferSize = 10000;
fr->VertexBufferSize = 5000;
}
}
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
{

@ -30,6 +30,7 @@ IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames
IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
IMGUI_IMPL_API void ImGui_ImplDX12_Resize(int num_frames_in_flight);
// Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();

Loading…
Cancel
Save