|
8 | 8 | // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
9 | 9 | // FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
|
10 | 10 |
|
| 11 | +// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification. |
| 12 | +// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ |
| 13 | + |
11 | 14 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
12 | 15 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
13 | 16 | // Learn about Dear ImGui:
|
|
19 | 22 | // CHANGELOG
|
20 | 23 | // (minor and older changes stripped away, please see git history for details)
|
21 | 24 | // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
| 25 | +// 2024-11-15: DirectX12: *BREAKING CHANGE* Changed ImGui_ImplDX12_Init() signature to take a ImGui_ImplDX12_InitInfo struct. Legacy ImGui_ImplDX12_Init() signature is still supported (will obsolete). |
| 26 | +// 2024-11-15: DirectX12: *BREAKING CHANGE* User is now required to pass function pointers to allocate/free SRV Descriptors. We provide convenience legacy fields to pass a single descriptor, matching the old API, but upcoming features will want multiple. |
22 | 27 | // 2024-10-23: DirectX12: Unmap() call specify written range. The range is informational and may be used by debug tools.
|
23 | 28 | // 2024-10-07: DirectX12: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
24 | 29 | // 2024-10-07: DirectX12: Expose selected render state in ImGui_ImplDX12_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
|
53 | 58 | #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
54 | 59 | #endif
|
55 | 60 |
|
56 |
| -// DirectX data |
| 61 | +// DirectX12 data |
| 62 | +struct ImGui_ImplDX12_RenderBuffers; |
| 63 | + |
| 64 | +struct ImGui_ImplDX12_Texture |
| 65 | +{ |
| 66 | + ID3D12Resource* pTextureResource; |
| 67 | + D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle; |
| 68 | + D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle; |
| 69 | + |
| 70 | + ImGui_ImplDX12_Texture() { memset((void*)this, 0, sizeof(*this)); } |
| 71 | +}; |
| 72 | + |
57 | 73 | struct ImGui_ImplDX12_Data
|
58 | 74 | {
|
| 75 | + ImGui_ImplDX12_InitInfo InitInfo; |
59 | 76 | ID3D12Device* pd3dDevice;
|
60 | 77 | ID3D12RootSignature* pRootSignature;
|
61 | 78 | ID3D12PipelineState* pPipelineState;
|
62 | 79 | DXGI_FORMAT RTVFormat;
|
63 |
| - ID3D12Resource* pFontTextureResource; |
64 |
| - D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle; |
65 |
| - D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle; |
66 | 80 | ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
67 | 81 | UINT numFramesInFlight;
|
| 82 | + ImGui_ImplDX12_Texture FontTexture; |
| 83 | + bool LegacySingleDescriptorUsed; |
68 | 84 |
|
69 | 85 | ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
70 | 86 | };
|
@@ -385,6 +401,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
385 | 401 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
386 | 402 |
|
387 | 403 | // Upload texture to graphics system
|
| 404 | + ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture; |
388 | 405 | {
|
389 | 406 | D3D12_HEAP_PROPERTIES props;
|
390 | 407 | memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
@@ -515,13 +532,13 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
515 | 532 | srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
516 | 533 | srvDesc.Texture2D.MostDetailedMip = 0;
|
517 | 534 | srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
518 |
| - bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle); |
519 |
| - SafeRelease(bd->pFontTextureResource); |
520 |
| - bd->pFontTextureResource = pTexture; |
| 535 | + bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, font_tex->hFontSrvCpuDescHandle); |
| 536 | + SafeRelease(font_tex->pTextureResource); |
| 537 | + font_tex->pTextureResource = pTexture; |
521 | 538 | }
|
522 | 539 |
|
523 | 540 | // Store our identifier
|
524 |
| - io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr); |
| 541 | + io.Fonts->SetTexID((ImTextureID)font_tex->hFontSrvGpuDescHandle.ptr); |
525 | 542 | }
|
526 | 543 |
|
527 | 544 | bool ImGui_ImplDX12_CreateDeviceObjects()
|
@@ -774,41 +791,87 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
774 | 791 | ImGuiIO& io = ImGui::GetIO();
|
775 | 792 | SafeRelease(bd->pRootSignature);
|
776 | 793 | SafeRelease(bd->pPipelineState);
|
777 |
| - SafeRelease(bd->pFontTextureResource); |
778 |
| - io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well. |
| 794 | + |
| 795 | + // Free SRV descriptor used by texture |
| 796 | + ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture; |
| 797 | + bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, font_tex->hFontSrvCpuDescHandle, font_tex->hFontSrvGpuDescHandle); |
| 798 | + SafeRelease(font_tex->pTextureResource); |
| 799 | + io.Fonts->SetTexID(0); // We copied bd->hFontSrvGpuDescHandle to io.Fonts->TexID so let's clear that as well. |
779 | 800 | }
|
780 | 801 |
|
781 |
| -bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap, |
782 |
| - D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) |
| 802 | +bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info) |
783 | 803 | {
|
784 | 804 | ImGuiIO& io = ImGui::GetIO();
|
785 | 805 | IMGUI_CHECKVERSION();
|
786 | 806 | IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
787 | 807 |
|
788 | 808 | // Setup backend capabilities flags
|
789 | 809 | ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
| 810 | + bd->InitInfo = *init_info; // Deep copy |
| 811 | + init_info = &bd->InitInfo; |
| 812 | + |
| 813 | + bd->pd3dDevice = init_info->Device; |
| 814 | + bd->RTVFormat = init_info->RTVFormat; |
| 815 | + bd->numFramesInFlight = init_info->NumFramesInFlight; |
| 816 | + bd->pd3dSrvDescHeap = init_info->SrvDescriptorHeap; |
| 817 | + |
790 | 818 | io.BackendRendererUserData = (void*)bd;
|
791 | 819 | io.BackendRendererName = "imgui_impl_dx12";
|
792 | 820 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
793 | 821 | io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
794 | 822 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
795 | 823 | ImGui_ImplDX12_InitPlatformInterface();
|
796 | 824 |
|
797 |
| - bd->pd3dDevice = device; |
798 |
| - bd->RTVFormat = rtv_format; |
799 |
| - bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle; |
800 |
| - bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle; |
801 |
| - bd->numFramesInFlight = num_frames_in_flight; |
802 |
| - bd->pd3dSrvDescHeap = cbv_srv_heap; |
803 |
| - |
804 | 825 | // Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
|
805 | 826 | // Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
806 | 827 | ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
807 | 828 | main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
808 | 829 |
|
| 830 | +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS |
| 831 | + if (init_info->SrvDescriptorAllocFn == NULL) |
| 832 | + { |
| 833 | + // Wrap legacy behavior of passing space for a single descriptor |
| 834 | + IM_ASSERT(init_info->LegacySingleSrvCpuDescriptor.ptr != 0 && init_info->LegacySingleSrvGpuDescriptor.ptr != 0); |
| 835 | + init_info->SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle) |
| 836 | + { |
| 837 | + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); |
| 838 | + IM_ASSERT(bd->LegacySingleDescriptorUsed == false); |
| 839 | + *out_cpu_handle = bd->InitInfo.LegacySingleSrvCpuDescriptor; |
| 840 | + *out_gpu_handle = bd->InitInfo.LegacySingleSrvGpuDescriptor; |
| 841 | + bd->LegacySingleDescriptorUsed = true; |
| 842 | + }; |
| 843 | + init_info->SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE) |
| 844 | + { |
| 845 | + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); |
| 846 | + IM_ASSERT(bd->LegacySingleDescriptorUsed == true); |
| 847 | + bd->LegacySingleDescriptorUsed = false; |
| 848 | + }; |
| 849 | + } |
| 850 | +#endif |
| 851 | + |
| 852 | + // Allocate 1 SRV descriptor for the font texture |
| 853 | + IM_ASSERT(init_info->SrvDescriptorAllocFn != NULL && init_info->SrvDescriptorFreeFn != NULL); |
| 854 | + init_info->SrvDescriptorAllocFn(&bd->InitInfo, &bd->FontTexture.hFontSrvCpuDescHandle, &bd->FontTexture.hFontSrvGpuDescHandle); |
| 855 | + |
809 | 856 | return true;
|
810 | 857 | }
|
811 | 858 |
|
| 859 | +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS |
| 860 | +// Legacy initialization API Obsoleted in 1.91.5 |
| 861 | +// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap' |
| 862 | +bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) |
| 863 | +{ |
| 864 | + ImGui_ImplDX12_InitInfo init_info; |
| 865 | + init_info.Device = device; |
| 866 | + init_info.NumFramesInFlight = num_frames_in_flight; |
| 867 | + init_info.RTVFormat = rtv_format; |
| 868 | + init_info.SrvDescriptorHeap = srv_descriptor_heap; |
| 869 | + init_info.LegacySingleSrvCpuDescriptor = font_srv_cpu_desc_handle; |
| 870 | + init_info.LegacySingleSrvGpuDescriptor = font_srv_gpu_desc_handle;; |
| 871 | + return ImGui_ImplDX12_Init(&init_info); |
| 872 | +} |
| 873 | +#endif |
| 874 | + |
812 | 875 | void ImGui_ImplDX12_Shutdown()
|
813 | 876 | {
|
814 | 877 | ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
|
0 commit comments