mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-06 11:28:31 +00:00
(Breaking) Backends: DX12: changed ImGui_ImplDX12_Init() signature. Added ImGui_ImplDX12_InitInfo. Added support for Srv allocators.
Ref 7708
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
// Config for example app
|
||||
static const int APP_NUM_FRAMES_IN_FLIGHT = 3;
|
||||
static const int APP_NUM_BACK_BUFFERS = 3;
|
||||
static const int APP_SRV_HEAP_SIZE = 64;
|
||||
|
||||
struct FrameContext
|
||||
{
|
||||
@@ -32,6 +33,51 @@ struct FrameContext
|
||||
UINT64 FenceValue;
|
||||
};
|
||||
|
||||
// Simple free list based allocator
|
||||
struct ExampleDescriptorHeapAllocator
|
||||
{
|
||||
ID3D12DescriptorHeap* Heap = nullptr;
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE HeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE HeapStartCpu;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE HeapStartGpu;
|
||||
UINT HeapHandleIncrement;
|
||||
ImVector<int> FreeIndices;
|
||||
|
||||
void Create(ID3D12Device* device, ID3D12DescriptorHeap* heap)
|
||||
{
|
||||
IM_ASSERT(Heap == nullptr && FreeIndices.empty());
|
||||
Heap = heap;
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = heap->GetDesc();
|
||||
HeapType = desc.Type;
|
||||
HeapStartCpu = Heap->GetCPUDescriptorHandleForHeapStart();
|
||||
HeapStartGpu = Heap->GetGPUDescriptorHandleForHeapStart();
|
||||
HeapHandleIncrement = device->GetDescriptorHandleIncrementSize(HeapType);
|
||||
FreeIndices.reserve((int)desc.NumDescriptors);
|
||||
for (int n = desc.NumDescriptors; n > 0; n--)
|
||||
FreeIndices.push_back(n);
|
||||
}
|
||||
void Destroy()
|
||||
{
|
||||
Heap = NULL;
|
||||
FreeIndices.clear();
|
||||
}
|
||||
void Alloc(D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_desc_handle)
|
||||
{
|
||||
IM_ASSERT(FreeIndices.Size > 0);
|
||||
int idx = FreeIndices.back();
|
||||
FreeIndices.pop_back();
|
||||
out_cpu_desc_handle->ptr = HeapStartCpu.ptr + (idx * HeapHandleIncrement);
|
||||
out_gpu_desc_handle->ptr = HeapStartGpu.ptr + (idx * HeapHandleIncrement);
|
||||
}
|
||||
void Free(D3D12_CPU_DESCRIPTOR_HANDLE out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE out_gpu_desc_handle)
|
||||
{
|
||||
int cpu_idx = (int)((out_cpu_desc_handle.ptr - HeapStartCpu.ptr) / HeapHandleIncrement);
|
||||
int gpu_idx = (int)((out_gpu_desc_handle.ptr - HeapStartGpu.ptr) / HeapHandleIncrement);
|
||||
IM_ASSERT(cpu_idx == gpu_idx);
|
||||
FreeIndices.push_back(cpu_idx);
|
||||
}
|
||||
};
|
||||
|
||||
// Data
|
||||
static FrameContext g_frameContext[APP_NUM_FRAMES_IN_FLIGHT] = {};
|
||||
static UINT g_frameIndex = 0;
|
||||
@@ -39,6 +85,7 @@ static UINT g_frameIndex = 0;
|
||||
static ID3D12Device* g_pd3dDevice = nullptr;
|
||||
static ID3D12DescriptorHeap* g_pd3dRtvDescHeap = nullptr;
|
||||
static ID3D12DescriptorHeap* g_pd3dSrvDescHeap = nullptr;
|
||||
static ExampleDescriptorHeapAllocator g_pd3dSrvDescHeapAlloc;
|
||||
static ID3D12CommandQueue* g_pd3dCommandQueue = nullptr;
|
||||
static ID3D12GraphicsCommandList* g_pd3dCommandList = nullptr;
|
||||
static ID3D12Fence* g_fence = nullptr;
|
||||
@@ -93,10 +140,18 @@ int main(int, char**)
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap,
|
||||
g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(),
|
||||
g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart());
|
||||
|
||||
ImGui_ImplDX12_InitInfo init_info = {};
|
||||
init_info.Device = g_pd3dDevice;
|
||||
init_info.CommandQueue = g_pd3dCommandQueue;
|
||||
init_info.NumFramesInFlight = APP_NUM_FRAMES_IN_FLIGHT;
|
||||
init_info.RTVFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
// Allocating SRV descriptors (for textures) is up to the application, so we provide callbacks.
|
||||
// (current version of the backend will only allocate one descriptor, future versions will need to allocate more)
|
||||
init_info.SrvDescriptorHeap = g_pd3dSrvDescHeap;
|
||||
init_info.SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle) { return g_pd3dSrvDescHeapAlloc.Alloc(out_cpu_handle, out_gpu_handle); };
|
||||
init_info.SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle) { return g_pd3dSrvDescHeapAlloc.Free(cpu_handle, gpu_handle); };
|
||||
ImGui_ImplDX12_Init(&init_info);
|
||||
|
||||
// Load Fonts
|
||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||
@@ -310,10 +365,11 @@ bool CreateDeviceD3D(HWND hWnd)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||
desc.NumDescriptors = 1;
|
||||
desc.NumDescriptors = APP_SRV_HEAP_SIZE;
|
||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||
if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dSrvDescHeap)) != S_OK)
|
||||
return false;
|
||||
g_pd3dSrvDescHeapAlloc.Create(g_pd3dDevice, g_pd3dSrvDescHeap);
|
||||
}
|
||||
|
||||
{
|
||||
|
Reference in New Issue
Block a user