mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-15 17:23:13 +02:00
Merge branch 'features/backends_context' into docking
# Conflicts: # backends/imgui_impl_dx10.cpp # backends/imgui_impl_dx11.cpp # backends/imgui_impl_dx12.cpp # backends/imgui_impl_dx9.cpp # backends/imgui_impl_glfw.cpp # backends/imgui_impl_opengl2.cpp # backends/imgui_impl_opengl3.cpp # backends/imgui_impl_sdl.cpp # backends/imgui_impl_vulkan.cpp # backends/imgui_impl_win32.cpp # examples/example_apple_opengl2/main.mm
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically.
|
||||
@ -51,15 +52,26 @@
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
static ID3D12Device* g_pd3dDevice = NULL;
|
||||
static ID3D12RootSignature* g_pRootSignature = NULL;
|
||||
static ID3D12PipelineState* g_pPipelineState = NULL;
|
||||
static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN;
|
||||
static ID3D12Resource* g_pFontTextureResource = NULL;
|
||||
static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {};
|
||||
static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {};
|
||||
static ID3D12DescriptorHeap* g_pd3dSrvDescHeap = NULL;
|
||||
static UINT g_numFramesInFlight = 0;
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
DXGI_FORMAT RTVFormat;
|
||||
ID3D12Resource* pFontTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
UINT numFramesInFlight;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Wrapping access to backend data (to facilitate multiple-contexts stored in io.BackendPlatformUserData)
|
||||
static ImGui_ImplDX12_Data* g_Data;
|
||||
static ImGui_ImplDX12_Data* ImGui_ImplDX12_CreateBackendData() { IM_ASSERT(g_Data == NULL); g_Data = IM_NEW(ImGui_ImplDX12_Data); return g_Data; }
|
||||
static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData() { return ImGui::GetCurrentContext() != NULL ? g_Data : NULL; }
|
||||
static void ImGui_ImplDX12_DestroyBackendData() { IM_DELETE(g_Data); g_Data = NULL; }
|
||||
|
||||
// Buffers used during the rendering of a frame
|
||||
struct ImGui_ImplDX12_RenderBuffers
|
||||
@ -91,13 +103,14 @@ struct ImGuiViewportDataDx12
|
||||
ID3D12Fence* Fence;
|
||||
UINT64 FenceSignaledValue;
|
||||
HANDLE FenceEvent;
|
||||
UINT NumFramesInFlight;
|
||||
ImGui_ImplDX12_FrameContext* FrameCtx;
|
||||
|
||||
// Render buffers
|
||||
UINT FrameIndex;
|
||||
ImGui_ImplDX12_RenderBuffers* FrameRenderBuffers;
|
||||
|
||||
ImGuiViewportDataDx12()
|
||||
ImGuiViewportDataDx12(UINT num_frames_in_flight)
|
||||
{
|
||||
CommandQueue = NULL;
|
||||
CommandList = NULL;
|
||||
@ -106,11 +119,12 @@ struct ImGuiViewportDataDx12
|
||||
Fence = NULL;
|
||||
FenceSignaledValue = 0;
|
||||
FenceEvent = NULL;
|
||||
FrameCtx = new ImGui_ImplDX12_FrameContext[g_numFramesInFlight];
|
||||
NumFramesInFlight = num_frames_in_flight;
|
||||
FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight];
|
||||
FrameIndex = UINT_MAX;
|
||||
FrameRenderBuffers = new ImGui_ImplDX12_RenderBuffers[g_numFramesInFlight];
|
||||
FrameRenderBuffers = new ImGui_ImplDX12_RenderBuffers[NumFramesInFlight];
|
||||
|
||||
for (UINT i = 0; i < g_numFramesInFlight; ++i)
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
FrameCtx[i].CommandAllocator = NULL;
|
||||
FrameCtx[i].RenderTarget = NULL;
|
||||
@ -130,7 +144,7 @@ struct ImGuiViewportDataDx12
|
||||
IM_ASSERT(Fence == NULL);
|
||||
IM_ASSERT(FenceEvent == NULL);
|
||||
|
||||
for (UINT i = 0; i < g_numFramesInFlight; ++i)
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
IM_ASSERT(FrameCtx[i].CommandAllocator == NULL && FrameCtx[i].RenderTarget == NULL);
|
||||
IM_ASSERT(FrameRenderBuffers[i].IndexBuffer == NULL && FrameRenderBuffers[i].VertexBuffer == NULL);
|
||||
@ -167,6 +181,8 @@ static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
|
||||
VERTEX_CONSTANT_BUFFER vertex_constant_buffer;
|
||||
@ -211,8 +227,8 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
||||
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||
ctx->IASetIndexBuffer(&ibv);
|
||||
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->SetPipelineState(g_pPipelineState);
|
||||
ctx->SetGraphicsRootSignature(g_pRootSignature);
|
||||
ctx->SetPipelineState(bd->pPipelineState);
|
||||
ctx->SetGraphicsRootSignature(bd->pRootSignature);
|
||||
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||
|
||||
// Setup blend factor
|
||||
@ -227,9 +243,10 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGuiViewportDataDx12* render_data = (ImGuiViewportDataDx12*)draw_data->OwnerViewport->RendererUserData;
|
||||
render_data->FrameIndex++;
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &render_data->FrameRenderBuffers[render_data->FrameIndex % g_numFramesInFlight];
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &render_data->FrameRenderBuffers[render_data->FrameIndex % bd->numFramesInFlight];
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
@ -252,7 +269,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
|
||||
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
|
||||
return;
|
||||
}
|
||||
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
@ -275,7 +292,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
|
||||
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -346,6 +363,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
@ -373,7 +391,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
ID3D12Resource* pTexture = NULL;
|
||||
g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, NULL, IID_PPV_ARGS(&pTexture));
|
||||
|
||||
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
@ -395,7 +413,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
|
||||
ID3D12Resource* uploadBuffer = NULL;
|
||||
HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&uploadBuffer));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
@ -430,7 +448,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
|
||||
ID3D12Fence* fence = NULL;
|
||||
hr = g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
HANDLE event = CreateEvent(0, 0, 0, 0);
|
||||
@ -442,15 +460,15 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
queueDesc.NodeMask = 1;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = NULL;
|
||||
hr = g_pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
||||
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandAllocator* cmdAlloc = NULL;
|
||||
hr = g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12GraphicsCommandList* cmdList = NULL;
|
||||
hr = g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, IID_PPV_ARGS(&cmdList));
|
||||
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, IID_PPV_ARGS(&cmdList));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL);
|
||||
@ -481,9 +499,9 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, g_hFontSrvCpuDescHandle);
|
||||
SafeRelease(g_pFontTextureResource);
|
||||
g_pFontTextureResource = pTexture;
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
bd->pFontTextureResource = pTexture;
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
@ -494,15 +512,16 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||
static_assert(sizeof(ImTextureID) >= sizeof(g_hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
||||
io.Fonts->SetTexID((ImTextureID)g_hFontSrvGpuDescHandle.ptr);
|
||||
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
||||
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return false;
|
||||
if (g_pPipelineState)
|
||||
if (bd->pPipelineState)
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
|
||||
// Create the root signature
|
||||
@ -583,7 +602,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK)
|
||||
return false;
|
||||
|
||||
g_pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&g_pRootSignature));
|
||||
bd->pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&bd->pRootSignature));
|
||||
blob->Release();
|
||||
}
|
||||
|
||||
@ -597,10 +616,10 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
|
||||
psoDesc.NodeMask = 1;
|
||||
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
psoDesc.pRootSignature = g_pRootSignature;
|
||||
psoDesc.pRootSignature = bd->pRootSignature;
|
||||
psoDesc.SampleMask = UINT_MAX;
|
||||
psoDesc.NumRenderTargets = 1;
|
||||
psoDesc.RTVFormats[0] = g_RTVFormat;
|
||||
psoDesc.RTVFormats[0] = bd->RTVFormat;
|
||||
psoDesc.SampleDesc.Count = 1;
|
||||
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||
|
||||
@ -719,7 +738,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
desc.BackFace = desc.FrontFace;
|
||||
}
|
||||
|
||||
HRESULT result_pipeline_state = g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState));
|
||||
HRESULT result_pipeline_state = bd->pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&bd->pPipelineState));
|
||||
vertexShaderBlob->Release();
|
||||
pixelShaderBlob->Release();
|
||||
if (result_pipeline_state != S_OK)
|
||||
@ -732,54 +751,58 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
|
||||
void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
SafeRelease(g_pRootSignature);
|
||||
SafeRelease(g_pPipelineState);
|
||||
SafeRelease(g_pFontTextureResource);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->SetTexID(NULL); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
io.Fonts->SetTexID(NULL); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// Setup backend capabilities flags
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
||||
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_CreateBackendData();
|
||||
bd->pd3dDevice = device;
|
||||
bd->RTVFormat = rtv_format;
|
||||
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
||||
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||
|
||||
// Setup backend capabilities flags
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx12";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) // FIXME-VIEWPORT: Actually unfinished..
|
||||
|
||||
g_pd3dDevice = device;
|
||||
g_RTVFormat = rtv_format;
|
||||
g_hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
||||
g_hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||
g_numFramesInFlight = num_frames_in_flight;
|
||||
g_pd3dSrvDescHeap = cbv_srv_heap;
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX12_InitPlatformInterface();
|
||||
|
||||
// Create a dummy ImGuiViewportDataDx12 holder for the main viewport,
|
||||
// Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGuiViewportDataDx12)();
|
||||
|
||||
// Setup backend capabilities flags
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX12_InitPlatformInterface();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGuiViewportDataDx12)(bd->numFramesInFlight);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
|
||||
// Manually delete main viewport render resources in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
if (ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)main_viewport->RendererUserData)
|
||||
{
|
||||
// We could just call ImGui_ImplDX12_DestroyWindow(main_viewport) as a convenience but that would be misleading since we only use data->Resources[]
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&data->FrameRenderBuffers[i]);
|
||||
IM_DELETE(data);
|
||||
main_viewport->RendererUserData = NULL;
|
||||
@ -789,16 +812,15 @@ void ImGui_ImplDX12_Shutdown()
|
||||
ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
|
||||
g_pd3dDevice = NULL;
|
||||
g_hFontSrvCpuDescHandle.ptr = 0;
|
||||
g_hFontSrvGpuDescHandle.ptr = 0;
|
||||
g_numFramesInFlight = 0;
|
||||
g_pd3dSrvDescHeap = NULL;
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
ImGui_ImplDX12_DestroyBackendData();
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_NewFrame()
|
||||
{
|
||||
if (!g_pPipelineState)
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (!bd->pPipelineState)
|
||||
ImGui_ImplDX12_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
@ -810,7 +832,8 @@ void ImGui_ImplDX12_NewFrame()
|
||||
|
||||
static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataDx12* data = IM_NEW(ImGuiViewportDataDx12)();
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGuiViewportDataDx12* data = IM_NEW(ImGuiViewportDataDx12)(bd->numFramesInFlight);
|
||||
viewport->RendererUserData = data;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
@ -826,23 +849,23 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
HRESULT res = S_OK;
|
||||
res = g_pd3dDevice->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&data->CommandQueue));
|
||||
res = bd->pd3dDevice->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&data->CommandQueue));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
// Create command allocator.
|
||||
for (UINT i = 0; i < g_numFramesInFlight; ++i)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; ++i)
|
||||
{
|
||||
res = g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&data->FrameCtx[i].CommandAllocator));
|
||||
res = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&data->FrameCtx[i].CommandAllocator));
|
||||
IM_ASSERT(res == S_OK);
|
||||
}
|
||||
|
||||
// Create command list.
|
||||
res = g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, data->FrameCtx[0].CommandAllocator, NULL, IID_PPV_ARGS(&data->CommandList));
|
||||
res = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, data->FrameCtx[0].CommandAllocator, NULL, IID_PPV_ARGS(&data->CommandList));
|
||||
IM_ASSERT(res == S_OK);
|
||||
data->CommandList->Close();
|
||||
|
||||
// Create fence.
|
||||
res = g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&data->Fence));
|
||||
res = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&data->Fence));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
data->FenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
@ -852,10 +875,10 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
// FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application.
|
||||
DXGI_SWAP_CHAIN_DESC1 sd1;
|
||||
ZeroMemory(&sd1, sizeof(sd1));
|
||||
sd1.BufferCount = g_numFramesInFlight;
|
||||
sd1.BufferCount = bd->numFramesInFlight;
|
||||
sd1.Width = (UINT)viewport->Size.x;
|
||||
sd1.Height = (UINT)viewport->Size.y;
|
||||
sd1.Format = g_RTVFormat;
|
||||
sd1.Format = bd->RTVFormat;
|
||||
sd1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd1.SampleDesc.Count = 1;
|
||||
sd1.SampleDesc.Quality = 0;
|
||||
@ -884,32 +907,32 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
desc.NumDescriptors = g_numFramesInFlight;
|
||||
desc.NumDescriptors = bd->numFramesInFlight;
|
||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
desc.NodeMask = 1;
|
||||
|
||||
HRESULT hr = g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&data->RtvDescHeap));
|
||||
HRESULT hr = bd->pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&data->RtvDescHeap));
|
||||
IM_ASSERT(hr == S_OK);
|
||||
|
||||
SIZE_T rtv_descriptor_size = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
SIZE_T rtv_descriptor_size = bd->pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = data->RtvDescHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
data->FrameCtx[i].RenderTargetCpuDescriptors = rtv_handle;
|
||||
rtv_handle.ptr += rtv_descriptor_size;
|
||||
}
|
||||
|
||||
ID3D12Resource* back_buffer;
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
IM_ASSERT(data->FrameCtx[i].RenderTarget == NULL);
|
||||
data->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
g_pd3dDevice->CreateRenderTargetView(back_buffer, NULL, data->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, NULL, data->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
data->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&data->FrameRenderBuffers[i]);
|
||||
}
|
||||
|
||||
@ -930,6 +953,7 @@ static void ImGui_WaitForPendingOperations(ImGuiViewportDataDx12* data)
|
||||
static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData)
|
||||
{
|
||||
ImGui_WaitForPendingOperations(data);
|
||||
@ -942,7 +966,7 @@ static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
::CloseHandle(data->FenceEvent);
|
||||
data->FenceEvent = NULL;
|
||||
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
SafeRelease(data->FrameCtx[i].RenderTarget);
|
||||
SafeRelease(data->FrameCtx[i].CommandAllocator);
|
||||
@ -955,21 +979,22 @@ static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
|
||||
static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData;
|
||||
|
||||
ImGui_WaitForPendingOperations(data);
|
||||
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
SafeRelease(data->FrameCtx[i].RenderTarget);
|
||||
|
||||
if (data->SwapChain)
|
||||
{
|
||||
ID3D12Resource* back_buffer = NULL;
|
||||
data->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
for (UINT i = 0; i < g_numFramesInFlight; i++)
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
data->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
g_pd3dDevice->CreateRenderTargetView(back_buffer, NULL, data->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, NULL, data->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
data->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
}
|
||||
@ -977,9 +1002,10 @@ static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
|
||||
static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData;
|
||||
|
||||
ImGui_ImplDX12_FrameContext* frame_context = &data->FrameCtx[data->FrameIndex % g_numFramesInFlight];
|
||||
ImGui_ImplDX12_FrameContext* frame_context = &data->FrameCtx[data->FrameIndex % bd->numFramesInFlight];
|
||||
UINT back_buffer_idx = data->SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
const ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
@ -1000,7 +1026,7 @@ static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
cmd_list->OMSetRenderTargets(1, &data->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, NULL);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
cmd_list->ClearRenderTargetView(data->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (float*)&clear_color, 0, NULL);
|
||||
cmd_list->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap);
|
||||
cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap);
|
||||
|
||||
ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list);
|
||||
|
||||
|
Reference in New Issue
Block a user