diff --git a/backends/imgui_impl_dx10.cpp b/backends/imgui_impl_dx10.cpp index ae6510db2..5650a3c85 100644 --- a/backends/imgui_impl_dx10.cpp +++ b/backends/imgui_impl_dx10.cpp @@ -325,18 +325,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) static void ImGui_ImplDX10_DestroyTexture(ImTextureData* tex) { - ImGui_ImplDX10_Texture* backend_tex = (ImGui_ImplDX10_Texture*)tex->BackendUserData; - if (backend_tex == nullptr) - return; - IM_ASSERT(backend_tex->pTextureView == (ID3D10ShaderResourceView*)(intptr_t)tex->TexID); - backend_tex->pTexture->Release(); - backend_tex->pTextureView->Release(); - IM_DELETE(backend_tex); + if (ImGui_ImplDX10_Texture* backend_tex = (ImGui_ImplDX10_Texture*)tex->BackendUserData) + { + IM_ASSERT(backend_tex->pTextureView == (ID3D10ShaderResourceView*)(intptr_t)tex->TexID); + backend_tex->pTextureView->Release(); + backend_tex->pTexture->Release(); + IM_DELETE(backend_tex); - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + tex->BackendUserData = nullptr; + } tex->SetStatus(ImTextureStatus_Destroyed); - tex->BackendUserData = nullptr; } void ImGui_ImplDX10_UpdateTexture(ImTextureData* tex) diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index 144850faa..878930404 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -341,18 +341,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) static void ImGui_ImplDX11_DestroyTexture(ImTextureData* tex) { - ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData; - if (backend_tex == nullptr) - return; - IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID); - backend_tex->pTextureView->Release(); - backend_tex->pTexture->Release(); - IM_DELETE(backend_tex); + if (ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData) + { + IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID); + backend_tex->pTextureView->Release(); + backend_tex->pTexture->Release(); + IM_DELETE(backend_tex); - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + tex->BackendUserData = nullptr; + } tex->SetStatus(ImTextureStatus_Destroyed); - tex->BackendUserData = nullptr; } void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex) diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 9462ca1fa..1e122a76e 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -345,21 +345,21 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL static void ImGui_ImplDX12_DestroyTexture(ImTextureData* tex) { - ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData; - if (backend_tex == nullptr) - return; - IM_ASSERT(backend_tex->hFontSrvGpuDescHandle.ptr == (UINT64)tex->TexID); - ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); - bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, backend_tex->hFontSrvCpuDescHandle, backend_tex->hFontSrvGpuDescHandle); - SafeRelease(backend_tex->pTextureResource); - backend_tex->hFontSrvCpuDescHandle.ptr = 0; - backend_tex->hFontSrvGpuDescHandle.ptr = 0; - IM_DELETE(backend_tex); + if (ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData) + { + IM_ASSERT(backend_tex->hFontSrvGpuDescHandle.ptr == (UINT64)tex->TexID); + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, backend_tex->hFontSrvCpuDescHandle, backend_tex->hFontSrvGpuDescHandle); + SafeRelease(backend_tex->pTextureResource); + backend_tex->hFontSrvCpuDescHandle.ptr = 0; + backend_tex->hFontSrvGpuDescHandle.ptr = 0; + IM_DELETE(backend_tex); - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + tex->BackendUserData = nullptr; + } tex->SetStatus(ImTextureStatus_Destroyed); - tex->BackendUserData = nullptr; } void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex) diff --git a/backends/imgui_impl_dx9.cpp b/backends/imgui_impl_dx9.cpp index 4a8899a62..37b5815cc 100644 --- a/backends/imgui_impl_dx9.cpp +++ b/backends/imgui_impl_dx9.cpp @@ -431,14 +431,14 @@ void ImGui_ImplDX9_UpdateTexture(ImTextureData* tex) } else if (tex->Status == ImTextureStatus_WantDestroy) { - LPDIRECT3DTEXTURE9 backend_tex = (LPDIRECT3DTEXTURE9)tex->TexID; - if (backend_tex == nullptr) - return; - IM_ASSERT(tex->TexID == (ImTextureID)(intptr_t)backend_tex); - backend_tex->Release(); + if (LPDIRECT3DTEXTURE9 backend_tex = (LPDIRECT3DTEXTURE9)tex->TexID) + { + IM_ASSERT(tex->TexID == (ImTextureID)(intptr_t)backend_tex); + backend_tex->Release(); - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + } tex->SetStatus(ImTextureStatus_Destroyed); } } diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 81e8be6c4..2746efa95 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -338,16 +338,16 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex) { - MetalTexture* backend_tex = (__bridge_transfer MetalTexture*)(tex->BackendUserData); - if (backend_tex == nullptr) - return; - IM_ASSERT(backend_tex.metalTexture == (__bridge id)(void*)(intptr_t)tex->TexID); - backend_tex.metalTexture = nil; + if (MetalTexture* backend_tex = (__bridge_transfer MetalTexture*)(tex->BackendUserData)) + { + IM_ASSERT(backend_tex.metalTexture == (__bridge id)(void*)(intptr_t)tex->TexID); + backend_tex.metalTexture = nil; - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + tex->BackendUserData = nullptr; + } tex->SetStatus(ImTextureStatus_Destroyed); - tex->BackendUserData = nullptr; } void ImGui_ImplMetal_UpdateTexture(ImTextureData* tex) diff --git a/backends/imgui_impl_sdlgpu3.cpp b/backends/imgui_impl_sdlgpu3.cpp index 3afbf3db6..8d8f0a4c4 100644 --- a/backends/imgui_impl_sdlgpu3.cpp +++ b/backends/imgui_impl_sdlgpu3.cpp @@ -307,8 +307,7 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe static void ImGui_ImplSDLGPU3_DestroyTexture(ImTextureData* tex) { ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); - SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID(); - if (raw_tex != nullptr) + if (SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID()) SDL_ReleaseGPUTexture(bd->InitInfo.Device, raw_tex); // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) diff --git a/backends/imgui_impl_sdlrenderer2.cpp b/backends/imgui_impl_sdlrenderer2.cpp index fa1e802b1..e03d13115 100644 --- a/backends/imgui_impl_sdlrenderer2.cpp +++ b/backends/imgui_impl_sdlrenderer2.cpp @@ -267,10 +267,8 @@ void ImGui_ImplSDLRenderer2_UpdateTexture(ImTextureData* tex) } else if (tex->Status == ImTextureStatus_WantDestroy) { - SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID; - if (sdl_texture == nullptr) - return; - SDL_DestroyTexture(sdl_texture); + if (SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID) + SDL_DestroyTexture(sdl_texture); // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) tex->SetTexID(ImTextureID_Invalid); diff --git a/backends/imgui_impl_sdlrenderer3.cpp b/backends/imgui_impl_sdlrenderer3.cpp index abf636b8d..38a4383c2 100644 --- a/backends/imgui_impl_sdlrenderer3.cpp +++ b/backends/imgui_impl_sdlrenderer3.cpp @@ -283,10 +283,8 @@ void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex) } else if (tex->Status == ImTextureStatus_WantDestroy) { - SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID; - if (sdl_texture == nullptr) - return; - SDL_DestroyTexture(sdl_texture); + if (SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID) + SDL_DestroyTexture(sdl_texture); // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) tex->SetTexID(ImTextureID_Invalid); diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 60554368e..a8eb9a8c4 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -663,22 +663,22 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm static void ImGui_ImplVulkan_DestroyTexture(ImTextureData* tex) { - ImGui_ImplVulkan_Texture* backend_tex = (ImGui_ImplVulkan_Texture*)tex->BackendUserData; - if (backend_tex == nullptr) - return; - IM_ASSERT(backend_tex->DescriptorSet == (VkDescriptorSet)tex->TexID); - ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); - ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; - ImGui_ImplVulkan_RemoveTexture(backend_tex->DescriptorSet); - vkDestroyImageView(v->Device, backend_tex->ImageView, v->Allocator); - vkDestroyImage(v->Device, backend_tex->Image, v->Allocator); - vkFreeMemory(v->Device, backend_tex->Memory, v->Allocator); - IM_DELETE(backend_tex); + if (ImGui_ImplVulkan_Texture* backend_tex = (ImGui_ImplVulkan_Texture*)tex->BackendUserData) + { + IM_ASSERT(backend_tex->DescriptorSet == (VkDescriptorSet)tex->TexID); + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + ImGui_ImplVulkan_RemoveTexture(backend_tex->DescriptorSet); + vkDestroyImageView(v->Device, backend_tex->ImageView, v->Allocator); + vkDestroyImage(v->Device, backend_tex->Image, v->Allocator); + vkFreeMemory(v->Device, backend_tex->Memory, v->Allocator); + IM_DELETE(backend_tex); - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + tex->BackendUserData = nullptr; + } tex->SetStatus(ImTextureStatus_Destroyed); - tex->BackendUserData = nullptr; } void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex) diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 1f997a10a..9f731c8f1 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -533,19 +533,18 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder static void ImGui_ImplWGPU_DestroyTexture(ImTextureData* tex) { - ImGui_ImplWGPU_Texture* backend_tex = (ImGui_ImplWGPU_Texture*)tex->BackendUserData; - if (backend_tex == nullptr) - return; + if (ImGui_ImplWGPU_Texture* backend_tex = (ImGui_ImplWGPU_Texture*)tex->BackendUserData) + { + IM_ASSERT(backend_tex->TextureView == (WGPUTextureView)(intptr_t)tex->TexID); + wgpuTextureViewRelease(backend_tex->TextureView); + wgpuTextureRelease(backend_tex->Texture); + IM_DELETE(backend_tex); - IM_ASSERT(backend_tex->TextureView == (WGPUTextureView)(intptr_t)tex->TexID); - wgpuTextureViewRelease(backend_tex->TextureView); - wgpuTextureRelease(backend_tex->Texture); - IM_DELETE(backend_tex); - - // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) - tex->SetTexID(ImTextureID_Invalid); + // Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running) + tex->SetTexID(ImTextureID_Invalid); + tex->BackendUserData = nullptr; + } tex->SetStatus(ImTextureStatus_Destroyed); - tex->BackendUserData = nullptr; } void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 628b909aa..14dc2c8c4 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -99,6 +99,9 @@ Other Changes: XInput's dwPacketNumber has not changed. (#8556) [@MidTerm-CN] - Backends: Vulkan: added a way to specify custom shaders by filling init fields CustomShaderVertCreateInfo and CustomShaderFragCreateInfo. (#8585, #8271) [@johan0A] +- Backends: DX9,DX10,DX11,DX12,Metal,Vulkan,WGPU,SDLRenderer2,SDLRenderer3: + ensure that a texture in _WantDestroy state always turn to _Destroyed even + if your underlying graphics data was already destroyed. - Examples: SDL2+DirectX11: Try WARP software driver if hardware driver is not available. (#5924, #5562) - Examples: SDL3+DirectX11: Added SDL3+DirectX11 example. (#8956, #8957) [@tomaz82]