2
2
// This needs to be used along with a Platform Backend (e.g. Win32)
3
3
4
4
// Implemented features:
5
- // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID . Read the FAQ about ImTextureID!
5
+ // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier . Read the FAQ about ImTextureID/ImTextureRef !
6
6
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
7
+ // [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
7
8
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
8
9
9
10
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
19
20
20
21
// CHANGELOG
21
22
// (minor and older changes stripped away, please see git history for details)
23
+ // 2025-06-11: DirectX12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
22
24
// 2025-05-07: DirectX12: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
23
25
// 2025-02-24: DirectX12: Fixed an issue where ImGui_ImplDX12_Init() signature change from 2024-11-15 combined with change from 2025-01-15 made legacy ImGui_ImplDX12_Init() crash. (#8429)
24
26
// 2025-01-15: DirectX12: Texture upload use the command queue provided in ImGui_ImplDX12_InitInfo instead of creating its own.
@@ -184,6 +186,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
184
186
if (draw_data->DisplaySize .x <= 0 .0f || draw_data->DisplaySize .y <= 0 .0f )
185
187
return ;
186
188
189
+ // Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
190
+ // (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
191
+ if (draw_data->Textures != nullptr )
192
+ for (ImTextureData* tex : *draw_data->Textures )
193
+ if (tex->Status != ImTextureStatus_OK)
194
+ ImGui_ImplDX12_UpdateTexture (tex);
195
+
187
196
// FIXME: We are assuming that this only gets called once per frame!
188
197
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData ();
189
198
bd->frameIndex = bd->frameIndex + 1 ;
@@ -316,18 +325,39 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
316
325
platform_io.Renderer_RenderState = nullptr ;
317
326
}
318
327
319
- static void ImGui_ImplDX12_CreateFontsTexture ()
328
+ static void ImGui_ImplDX12_DestroyTexture (ImTextureData* tex)
329
+ {
330
+ ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData ;
331
+ if (backend_tex == nullptr )
332
+ return ;
333
+ IM_ASSERT (backend_tex->hFontSrvGpuDescHandle .ptr == (UINT64)tex->TexID );
334
+ ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData ();
335
+ bd->InitInfo .SrvDescriptorFreeFn (&bd->InitInfo , backend_tex->hFontSrvCpuDescHandle , backend_tex->hFontSrvGpuDescHandle );
336
+ SafeRelease (backend_tex->pTextureResource );
337
+ backend_tex->hFontSrvCpuDescHandle .ptr = 0 ;
338
+ backend_tex->hFontSrvGpuDescHandle .ptr = 0 ;
339
+ IM_DELETE (backend_tex);
340
+
341
+ // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
342
+ tex->SetTexID (ImTextureID_Invalid);
343
+ tex->SetStatus (ImTextureStatus_Destroyed);
344
+ tex->BackendUserData = nullptr ;
345
+ }
346
+
347
+ void ImGui_ImplDX12_UpdateTexture (ImTextureData* tex)
320
348
{
321
- // Build texture atlas
322
- ImGuiIO& io = ImGui::GetIO ();
323
349
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData ();
324
- unsigned char * pixels;
325
- int width, height;
326
- io.Fonts ->GetTexDataAsRGBA32 (&pixels, &width, &height);
350
+ bool need_barrier_before_copy = true ; // Do we need a resource barrier before we copy new data in?
327
351
328
- // Upload texture to graphics system
329
- ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture ;
352
+ if (tex->Status == ImTextureStatus_WantCreate)
330
353
{
354
+ // Create and upload new texture to graphics system
355
+ // IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
356
+ IM_ASSERT (tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr );
357
+ IM_ASSERT (tex->Format == ImTextureFormat_RGBA32);
358
+ ImGui_ImplDX12_Texture* backend_tex = IM_NEW (ImGui_ImplDX12_Texture)();
359
+ bd->InitInfo .SrvDescriptorAllocFn (&bd->InitInfo , &backend_tex->hFontSrvCpuDescHandle , &backend_tex->hFontSrvGpuDescHandle ); // Allocate a desctriptor handle
360
+
331
361
D3D12_HEAP_PROPERTIES props = {};
332
362
props.Type = D3D12_HEAP_TYPE_DEFAULT;
333
363
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
@@ -337,8 +367,8 @@ static void ImGui_ImplDX12_CreateFontsTexture()
337
367
ZeroMemory (&desc, sizeof (desc));
338
368
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
339
369
desc.Alignment = 0 ;
340
- desc.Width = width ;
341
- desc.Height = height ;
370
+ desc.Width = tex-> Width ;
371
+ desc.Height = tex-> Height ;
342
372
desc.DepthOrArraySize = 1 ;
343
373
desc.MipLevels = 1 ;
344
374
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
@@ -351,8 +381,47 @@ static void ImGui_ImplDX12_CreateFontsTexture()
351
381
bd->pd3dDevice ->CreateCommittedResource (&props, D3D12_HEAP_FLAG_NONE, &desc,
352
382
D3D12_RESOURCE_STATE_COPY_DEST, nullptr , IID_PPV_ARGS (&pTexture));
353
383
354
- UINT upload_pitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u ) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u );
355
- UINT upload_size = height * upload_pitch;
384
+ // Create SRV
385
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
386
+ ZeroMemory (&srvDesc, sizeof (srvDesc));
387
+ srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
388
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
389
+ srvDesc.Texture2D .MipLevels = desc.MipLevels ;
390
+ srvDesc.Texture2D .MostDetailedMip = 0 ;
391
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
392
+ bd->pd3dDevice ->CreateShaderResourceView (pTexture, &srvDesc, backend_tex->hFontSrvCpuDescHandle );
393
+ SafeRelease (backend_tex->pTextureResource );
394
+ backend_tex->pTextureResource = pTexture;
395
+
396
+ // Store identifiers
397
+ tex->SetTexID ((ImTextureID)backend_tex->hFontSrvGpuDescHandle .ptr );
398
+ tex->BackendUserData = backend_tex;
399
+ need_barrier_before_copy = false ; // Because this is a newly-created texture it will be in D3D12_RESOURCE_STATE_COMMON and thus we don't need a barrier
400
+ // We don't set tex->Status to ImTextureStatus_OK to let the code fallthrough below.
401
+ }
402
+
403
+ if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
404
+ {
405
+ ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData ;
406
+ IM_ASSERT (tex->Format == ImTextureFormat_RGBA32);
407
+
408
+ // We could use the smaller rect on _WantCreate but using the full rect allows us to clear the texture.
409
+ // FIXME-OPT: Uploading single box even when using ImTextureStatus_WantUpdates. Could use tex->Updates[]
410
+ // - Copy all blocks contiguously in upload buffer.
411
+ // - Barrier before copy, submit all CopyTextureRegion(), barrier after copy.
412
+ const int upload_x = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect .x ;
413
+ const int upload_y = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect .y ;
414
+ const int upload_w = (tex->Status == ImTextureStatus_WantCreate) ? tex->Width : tex->UpdateRect .w ;
415
+ const int upload_h = (tex->Status == ImTextureStatus_WantCreate) ? tex->Height : tex->UpdateRect .h ;
416
+
417
+ // Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
418
+ // This backend choose to use tex->UpdateRect but you can use tex->Updates[] to upload individual regions.
419
+ UINT upload_pitch_src = upload_w * tex->BytesPerPixel ;
420
+ UINT upload_pitch_dst = (upload_pitch_src + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u ) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u );
421
+ UINT upload_size = upload_pitch_dst * upload_h;
422
+
423
+ D3D12_RESOURCE_DESC desc;
424
+ ZeroMemory (&desc, sizeof (desc));
356
425
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
357
426
desc.Alignment = 0 ;
358
427
desc.Width = upload_size;
@@ -365,64 +434,83 @@ static void ImGui_ImplDX12_CreateFontsTexture()
365
434
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
366
435
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
367
436
437
+ D3D12_HEAP_PROPERTIES props;
438
+ memset (&props, 0 , sizeof (D3D12_HEAP_PROPERTIES));
368
439
props.Type = D3D12_HEAP_TYPE_UPLOAD;
369
440
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
370
441
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
371
442
443
+ // FIXME-OPT: Can upload buffer be reused?
372
444
ID3D12Resource* uploadBuffer = nullptr ;
373
445
HRESULT hr = bd->pd3dDevice ->CreateCommittedResource (&props, D3D12_HEAP_FLAG_NONE, &desc,
374
446
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr , IID_PPV_ARGS (&uploadBuffer));
375
447
IM_ASSERT (SUCCEEDED (hr));
376
448
449
+ // Create temporary command list and execute immediately
450
+ ID3D12Fence* fence = nullptr ;
451
+ hr = bd->pd3dDevice ->CreateFence (0 , D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS (&fence));
452
+ IM_ASSERT (SUCCEEDED (hr));
453
+
454
+ HANDLE event = ::CreateEvent (0 , 0 , 0 , 0 );
455
+ IM_ASSERT (event != nullptr );
456
+
457
+ // FIXME-OPT: Create once and reuse?
458
+ ID3D12CommandAllocator* cmdAlloc = nullptr ;
459
+ hr = bd->pd3dDevice ->CreateCommandAllocator (D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS (&cmdAlloc));
460
+ IM_ASSERT (SUCCEEDED (hr));
461
+
462
+ // FIXME-OPT: Can be use the one from user? (pass ID3D12GraphicsCommandList* to ImGui_ImplDX12_UpdateTextures)
463
+ ID3D12GraphicsCommandList* cmdList = nullptr ;
464
+ hr = bd->pd3dDevice ->CreateCommandList (0 , D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr , IID_PPV_ARGS (&cmdList));
465
+ IM_ASSERT (SUCCEEDED (hr));
466
+
467
+ // Copy to upload buffer
377
468
void * mapped = nullptr ;
378
469
D3D12_RANGE range = { 0 , upload_size };
379
470
hr = uploadBuffer->Map (0 , &range, &mapped);
380
471
IM_ASSERT (SUCCEEDED (hr));
381
- for (int y = 0 ; y < height ; y++)
382
- memcpy ((void *) ((uintptr_t ) mapped + y * upload_pitch ), pixels + y * width * 4 , width * 4 );
472
+ for (int y = 0 ; y < upload_h ; y++)
473
+ memcpy ((void *)((uintptr_t )mapped + y * upload_pitch_dst ), tex-> GetPixelsAt (upload_x, upload_y + y), upload_pitch_src );
383
474
uploadBuffer->Unmap (0 , &range);
384
475
476
+ if (need_barrier_before_copy)
477
+ {
478
+ D3D12_RESOURCE_BARRIER barrier = {};
479
+ barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
480
+ barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
481
+ barrier.Transition .pResource = backend_tex->pTextureResource ;
482
+ barrier.Transition .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
483
+ barrier.Transition .StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
484
+ barrier.Transition .StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
485
+ cmdList->ResourceBarrier (1 , &barrier);
486
+ }
487
+
385
488
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
386
489
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
387
490
{
388
491
srcLocation.pResource = uploadBuffer;
389
492
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
390
493
srcLocation.PlacedFootprint .Footprint .Format = DXGI_FORMAT_R8G8B8A8_UNORM;
391
- srcLocation.PlacedFootprint .Footprint .Width = width ;
392
- srcLocation.PlacedFootprint .Footprint .Height = height ;
494
+ srcLocation.PlacedFootprint .Footprint .Width = upload_w ;
495
+ srcLocation.PlacedFootprint .Footprint .Height = upload_h ;
393
496
srcLocation.PlacedFootprint .Footprint .Depth = 1 ;
394
- srcLocation.PlacedFootprint .Footprint .RowPitch = upload_pitch;
395
-
396
- dstLocation.pResource = pTexture;
497
+ srcLocation.PlacedFootprint .Footprint .RowPitch = upload_pitch_dst;
498
+ dstLocation.pResource = backend_tex->pTextureResource ;
397
499
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
398
500
dstLocation.SubresourceIndex = 0 ;
399
501
}
502
+ cmdList->CopyTextureRegion (&dstLocation, upload_x, upload_y, 0 , &srcLocation, nullptr );
400
503
401
- D3D12_RESOURCE_BARRIER barrier = {};
402
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
403
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
404
- barrier.Transition .pResource = pTexture;
405
- barrier.Transition .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
406
- barrier.Transition .StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
407
- barrier.Transition .StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
408
-
409
- ID3D12Fence* fence = nullptr ;
410
- hr = bd->pd3dDevice ->CreateFence (0 , D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS (&fence));
411
- IM_ASSERT (SUCCEEDED (hr));
412
-
413
- HANDLE event = ::CreateEvent (0 , 0 , 0 , 0 );
414
- IM_ASSERT (event != nullptr );
415
-
416
- ID3D12CommandAllocator* cmdAlloc = nullptr ;
417
- hr = bd->pd3dDevice ->CreateCommandAllocator (D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS (&cmdAlloc));
418
- IM_ASSERT (SUCCEEDED (hr));
419
-
420
- ID3D12GraphicsCommandList* cmdList = nullptr ;
421
- hr = bd->pd3dDevice ->CreateCommandList (0 , D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr , IID_PPV_ARGS (&cmdList));
422
- IM_ASSERT (SUCCEEDED (hr));
423
-
424
- cmdList->CopyTextureRegion (&dstLocation, 0 , 0 , 0 , &srcLocation, nullptr );
425
- cmdList->ResourceBarrier (1 , &barrier);
504
+ {
505
+ D3D12_RESOURCE_BARRIER barrier = {};
506
+ barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
507
+ barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
508
+ barrier.Transition .pResource = backend_tex->pTextureResource ;
509
+ barrier.Transition .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
510
+ barrier.Transition .StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
511
+ barrier.Transition .StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
512
+ cmdList->ResourceBarrier (1 , &barrier);
513
+ }
426
514
427
515
hr = cmdList->Close ();
428
516
IM_ASSERT (SUCCEEDED (hr));
@@ -432,6 +520,10 @@ static void ImGui_ImplDX12_CreateFontsTexture()
432
520
hr = cmdQueue->Signal (fence, 1 );
433
521
IM_ASSERT (SUCCEEDED (hr));
434
522
523
+ // FIXME-OPT: Suboptimal?
524
+ // - To remove this may need to create NumFramesInFlight x ImGui_ImplDX12_FrameContext in backend data (mimick docking version)
525
+ // - Store per-frame in flight: upload buffer?
526
+ // - Where do cmdList and cmdAlloc fit?
435
527
fence->SetEventOnCompletion (1 , event);
436
528
::WaitForSingleObject (event, INFINITE);
437
529
@@ -440,22 +532,11 @@ static void ImGui_ImplDX12_CreateFontsTexture()
440
532
::CloseHandle (event);
441
533
fence->Release ();
442
534
uploadBuffer->Release ();
443
-
444
- // Create texture view
445
- D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
446
- ZeroMemory (&srvDesc, sizeof (srvDesc));
447
- srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
448
- srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
449
- srvDesc.Texture2D .MipLevels = desc.MipLevels ;
450
- srvDesc.Texture2D .MostDetailedMip = 0 ;
451
- srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
452
- bd->pd3dDevice ->CreateShaderResourceView (pTexture, &srvDesc, font_tex->hFontSrvCpuDescHandle );
453
- SafeRelease (font_tex->pTextureResource );
454
- font_tex->pTextureResource = pTexture;
535
+ tex->SetStatus (ImTextureStatus_OK);
455
536
}
456
537
457
- // Store our identifier
458
- io. Fonts -> SetTexID ((ImTextureID)font_tex-> hFontSrvGpuDescHandle . ptr );
538
+ if (tex-> Status == ImTextureStatus_WantDestroy && tex-> UnusedFrames >= ( int )bd-> numFramesInFlight )
539
+ ImGui_ImplDX12_DestroyTexture (tex );
459
540
}
460
541
461
542
bool ImGui_ImplDX12_CreateDeviceObjects ()
@@ -687,8 +768,6 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
687
768
if (result_pipeline_state != S_OK)
688
769
return false ;
689
770
690
- ImGui_ImplDX12_CreateFontsTexture ();
691
-
692
771
return true ;
693
772
}
694
773
@@ -704,12 +783,10 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
704
783
SafeRelease (bd->pRootSignature );
705
784
SafeRelease (bd->pPipelineState );
706
785
707
- // Free SRV descriptor used by texture
708
- ImGuiIO& io = ImGui::GetIO ();
709
- ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture ;
710
- bd->InitInfo .SrvDescriptorFreeFn (&bd->InitInfo , font_tex->hFontSrvCpuDescHandle , font_tex->hFontSrvGpuDescHandle );
711
- SafeRelease (font_tex->pTextureResource );
712
- io.Fonts ->SetTexID (0 ); // We copied bd->hFontSrvGpuDescHandle to io.Fonts->TexID so let's clear that as well.
786
+ // Destroy all textures
787
+ for (ImTextureData* tex : ImGui::GetPlatformIO ().Textures )
788
+ if (tex->RefCount == 1 )
789
+ ImGui_ImplDX12_DestroyTexture (tex);
713
790
714
791
for (UINT i = 0 ; i < bd->numFramesInFlight ; i++)
715
792
{
@@ -741,6 +818,16 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
741
818
io.BackendRendererUserData = (void *)bd;
742
819
io.BackendRendererName = " imgui_impl_dx12" ;
743
820
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
821
+ io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
822
+
823
+ if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
824
+ ImGui_ImplDX12_InitPlatformInterface ();
825
+
826
+ // Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
827
+ // Since this is created and managed by the application, we will only use the ->Resources[] fields.
828
+ ImGuiViewport* main_viewport = ImGui::GetMainViewport ();
829
+ main_viewport->RendererUserData = IM_NEW (ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight );
830
+ >>>>>>> dda12fbd9a (Backends: DirectX12: added ImGuiBackendFlags_RendererHasTextures support.)
744
831
745
832
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
746
833
if (init_info->SrvDescriptorAllocFn == nullptr )
@@ -763,10 +850,7 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
763
850
};
764
851
}
765
852
#endif
766
-
767
- // Allocate 1 SRV descriptor for the font texture
768
853
IM_ASSERT (init_info->SrvDescriptorAllocFn != nullptr && init_info->SrvDescriptorFreeFn != nullptr );
769
- init_info->SrvDescriptorAllocFn (&bd->InitInfo , &bd->FontTexture .hFontSrvCpuDescHandle , &bd->FontTexture .hFontSrvGpuDescHandle );
770
854
771
855
// Create buffers with a default size (they will later be grown as needed)
772
856
bd->frameIndex = UINT_MAX;
@@ -806,6 +890,9 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
806
890
bool ret = ImGui_ImplDX12_Init (&init_info);
807
891
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData ();
808
892
bd->commandQueueOwned = true ;
893
+ ImGuiIO& io = ImGui::GetIO ();
894
+ io.BackendFlags &= ~ImGuiBackendFlags_RendererHasTextures; // Using legacy ImGui_ImplDX12_Init() call with 1 SRV descriptor we cannot support multiple textures.
895
+
809
896
return ret;
810
897
}
811
898
#endif
@@ -822,7 +909,7 @@ void ImGui_ImplDX12_Shutdown()
822
909
823
910
io.BackendRendererName = nullptr ;
824
911
io.BackendRendererUserData = nullptr ;
825
- io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
912
+ io.BackendFlags &= ~( ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures) ;
826
913
IM_DELETE (bd);
827
914
}
828
915
0 commit comments