Examples: Win32+DX12: Tweaks.

This commit is contained in:
ocornut 2024-11-15 16:03:58 +01:00
parent 8be0723fb7
commit 3260ea6954
3 changed files with 24 additions and 18 deletions

View File

@ -6,6 +6,9 @@
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui: // Learn about Dear ImGui:

View File

@ -6,6 +6,9 @@
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui: // Learn about Dear ImGui:

View File

@ -22,7 +22,9 @@
#pragma comment(lib, "dxguid.lib") #pragma comment(lib, "dxguid.lib")
#endif #endif
#include "imgui_internal.h" // Config for example app
static const int APP_NUM_FRAMES_IN_FLIGHT = 3;
static const int APP_NUM_BACK_BUFFERS = 3;
struct FrameContext struct FrameContext
{ {
@ -31,11 +33,9 @@ struct FrameContext
}; };
// Data // Data
static int const NUM_FRAMES_IN_FLIGHT = 3; static FrameContext g_frameContext[APP_NUM_FRAMES_IN_FLIGHT] = {};
static FrameContext g_frameContext[NUM_FRAMES_IN_FLIGHT] = {};
static UINT g_frameIndex = 0; static UINT g_frameIndex = 0;
static int const NUM_BACK_BUFFERS = 3;
static ID3D12Device* g_pd3dDevice = nullptr; static ID3D12Device* g_pd3dDevice = nullptr;
static ID3D12DescriptorHeap* g_pd3dRtvDescHeap = nullptr; static ID3D12DescriptorHeap* g_pd3dRtvDescHeap = nullptr;
static ID3D12DescriptorHeap* g_pd3dSrvDescHeap = nullptr; static ID3D12DescriptorHeap* g_pd3dSrvDescHeap = nullptr;
@ -47,8 +47,8 @@ static UINT64 g_fenceLastSignaledValue = 0;
static IDXGISwapChain3* g_pSwapChain = nullptr; static IDXGISwapChain3* g_pSwapChain = nullptr;
static bool g_SwapChainOccluded = false; static bool g_SwapChainOccluded = false;
static HANDLE g_hSwapChainWaitableObject = nullptr; static HANDLE g_hSwapChainWaitableObject = nullptr;
static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {}; static ID3D12Resource* g_mainRenderTargetResource[APP_NUM_BACK_BUFFERS] = {};
static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {}; static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[APP_NUM_BACK_BUFFERS] = {};
// Forward declarations of helper functions // Forward declarations of helper functions
bool CreateDeviceD3D(HWND hWnd); bool CreateDeviceD3D(HWND hWnd);
@ -249,7 +249,7 @@ bool CreateDeviceD3D(HWND hWnd)
DXGI_SWAP_CHAIN_DESC1 sd; DXGI_SWAP_CHAIN_DESC1 sd;
{ {
ZeroMemory(&sd, sizeof(sd)); ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = NUM_BACK_BUFFERS; sd.BufferCount = APP_NUM_BACK_BUFFERS;
sd.Width = 0; sd.Width = 0;
sd.Height = 0; sd.Height = 0;
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
@ -292,7 +292,7 @@ bool CreateDeviceD3D(HWND hWnd)
{ {
D3D12_DESCRIPTOR_HEAP_DESC desc = {}; D3D12_DESCRIPTOR_HEAP_DESC desc = {};
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.NumDescriptors = NUM_BACK_BUFFERS; desc.NumDescriptors = APP_NUM_BACK_BUFFERS;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
desc.NodeMask = 1; desc.NodeMask = 1;
if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)) != S_OK) if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)) != S_OK)
@ -300,7 +300,7 @@ bool CreateDeviceD3D(HWND hWnd)
SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart(); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
{ {
g_mainRenderTargetDescriptor[i] = rtvHandle; g_mainRenderTargetDescriptor[i] = rtvHandle;
rtvHandle.ptr += rtvDescriptorSize; rtvHandle.ptr += rtvDescriptorSize;
@ -325,7 +325,7 @@ bool CreateDeviceD3D(HWND hWnd)
return false; return false;
} }
for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++) for (UINT i = 0; i < APP_NUM_FRAMES_IN_FLIGHT; i++)
if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK) if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK)
return false; return false;
@ -351,7 +351,7 @@ bool CreateDeviceD3D(HWND hWnd)
return false; return false;
swapChain1->Release(); swapChain1->Release();
dxgiFactory->Release(); dxgiFactory->Release();
g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS); g_pSwapChain->SetMaximumFrameLatency(APP_NUM_BACK_BUFFERS);
g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject(); g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject();
} }
@ -364,7 +364,7 @@ void CleanupDeviceD3D()
CleanupRenderTarget(); CleanupRenderTarget();
if (g_pSwapChain) { g_pSwapChain->SetFullscreenState(false, nullptr); g_pSwapChain->Release(); g_pSwapChain = nullptr; } if (g_pSwapChain) { g_pSwapChain->SetFullscreenState(false, nullptr); g_pSwapChain->Release(); g_pSwapChain = nullptr; }
if (g_hSwapChainWaitableObject != nullptr) { CloseHandle(g_hSwapChainWaitableObject); } if (g_hSwapChainWaitableObject != nullptr) { CloseHandle(g_hSwapChainWaitableObject); }
for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++) for (UINT i = 0; i < APP_NUM_FRAMES_IN_FLIGHT; i++)
if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = nullptr; } if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = nullptr; }
if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = nullptr; } if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = nullptr; }
if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = nullptr; } if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = nullptr; }
@ -386,7 +386,7 @@ void CleanupDeviceD3D()
void CreateRenderTarget() void CreateRenderTarget()
{ {
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
{ {
ID3D12Resource* pBackBuffer = nullptr; ID3D12Resource* pBackBuffer = nullptr;
g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer));
@ -399,13 +399,13 @@ void CleanupRenderTarget()
{ {
WaitForLastSubmittedFrame(); WaitForLastSubmittedFrame();
for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = nullptr; } if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = nullptr; }
} }
void WaitForLastSubmittedFrame() void WaitForLastSubmittedFrame()
{ {
FrameContext* frameCtx = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT]; FrameContext* frameCtx = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtx->FenceValue; UINT64 fenceValue = frameCtx->FenceValue;
if (fenceValue == 0) if (fenceValue == 0)
@ -427,7 +427,7 @@ FrameContext* WaitForNextFrameResources()
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, nullptr }; HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, nullptr };
DWORD numWaitableObjects = 1; DWORD numWaitableObjects = 1;
FrameContext* frameCtx = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT]; FrameContext* frameCtx = &g_frameContext[nextFrameIndex % APP_NUM_FRAMES_IN_FLIGHT];
UINT64 fenceValue = frameCtx->FenceValue; UINT64 fenceValue = frameCtx->FenceValue;
if (fenceValue != 0) // means no fence was signaled if (fenceValue != 0) // means no fence was signaled
{ {