diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index 808abde7c..5f1a31dcc 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -99,13 +99,6 @@ void GPU_HW_Vulkan::ResetGraphicsAPIState() GPU_HW::ResetGraphicsAPIState(); EndRenderPass(); - - // vram texture is probably going to be displayed now - if (!IsDisplayDisabled()) - { - m_vram_texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - } } void GPU_HW_Vulkan::RestoreGraphicsAPIState() @@ -928,9 +921,12 @@ void GPU_HW_Vulkan::ClearDisplay() void GPU_HW_Vulkan::UpdateDisplay() { GPU_HW::UpdateDisplay(); + EndRenderPass(); if (g_settings.debugging.show_vram) { + m_vram_texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); m_host_display->SetDisplayTexture(&m_vram_texture, m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight()); m_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, @@ -956,6 +952,8 @@ void GPU_HW_Vulkan::UpdateDisplay() (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() && (scaled_vram_offset_y + scaled_display_height) <= m_vram_texture.GetHeight()) { + m_vram_texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); m_host_display->SetDisplayTexture(&m_vram_texture, m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width, scaled_display_height); diff --git a/src/frontend-common/imgui_impl_vulkan.cpp b/src/frontend-common/imgui_impl_vulkan.cpp index 3fb10d235..50c12ef75 100644 --- a/src/frontend-common/imgui_impl_vulkan.cpp +++ b/src/frontend-common/imgui_impl_vulkan.cpp @@ -46,6 +46,7 @@ #include "imgui.h" #include "imgui_impl_vulkan.h" +#include "common/vulkan/texture.h" #include // Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData() @@ -76,16 +77,15 @@ static VkDeviceSize g_BufferMemoryAlignment = 256; static VkPipelineCreateFlags g_PipelineCreateFlags = 0x00; static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE; static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE; -static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE; static VkPipeline g_Pipeline = VK_NULL_HANDLE; // Font data static VkSampler g_FontSampler = VK_NULL_HANDLE; static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE; static VkImage g_FontImage = VK_NULL_HANDLE; -static VkImageView g_FontView = VK_NULL_HANDLE; static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; +static Vulkan::Texture g_FontTexture; // Render buffers static ImGui_ImplVulkanH_WindowRenderBuffers g_MainWindowRenderBuffers; @@ -269,8 +269,6 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBu // Bind pipeline and descriptor sets: { vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline); - VkDescriptorSet desc_set[1] = { g_DescriptorSet }; - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL); } // Bind Vertex And Index Buffer: @@ -307,6 +305,33 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBu } } +static void ImGui_ImplVulkan_UpdateAndBindDescriptors(const ImDrawCmd* pcmd, VkCommandBuffer command_buffer) +{ + const Vulkan::Texture* tex = static_cast(pcmd->TextureId); + + VkDescriptorSet desc_set; + VkDescriptorSetAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.descriptorPool = g_VulkanInitInfo.DescriptorPool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = &g_DescriptorSetLayout; + VkResult err = vkAllocateDescriptorSets(g_VulkanInitInfo.Device, &alloc_info, &desc_set); + check_vk_result(err); + + VkDescriptorImageInfo desc_image[1] = {}; + desc_image[0].sampler = g_FontSampler; + desc_image[0].imageView = tex->GetView(); + desc_image[0].imageLayout = tex->GetLayout(); + VkWriteDescriptorSet write_desc[1] = {}; + write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_desc[0].dstSet = desc_set; + write_desc[0].descriptorCount = 1; + write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_desc[0].pImageInfo = desc_image; + vkUpdateDescriptorSets(g_VulkanInitInfo.Device, 1, write_desc, 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, &desc_set, 0, NULL); +} + // Render function // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer) @@ -407,6 +432,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { + ImGui_ImplVulkan_UpdateAndBindDescriptors(pcmd, command_buffer); + // Negative offsets are illegal for vkCmdSetScissor if (clip_rect.x < 0.0f) clip_rect.x = 0.0f; @@ -475,31 +502,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) // Create the Image View: { - VkImageViewCreateInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - info.image = g_FontImage; - info.viewType = VK_IMAGE_VIEW_TYPE_2D; - info.format = VK_FORMAT_R8G8B8A8_UNORM; - info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - info.subresourceRange.levelCount = 1; - info.subresourceRange.layerCount = 1; - err = vkCreateImageView(v->Device, &info, v->Allocator, &g_FontView); - check_vk_result(err); - } - - // Update the Descriptor Set: - { - VkDescriptorImageInfo desc_image[1] = {}; - desc_image[0].sampler = g_FontSampler; - desc_image[0].imageView = g_FontView; - desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - VkWriteDescriptorSet write_desc[1] = {}; - write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_desc[0].dstSet = g_DescriptorSet; - write_desc[0].descriptorCount = 1; - write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - write_desc[0].pImageInfo = desc_image; - vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, NULL); + g_FontTexture.Adopt(g_FontImage, VK_IMAGE_VIEW_TYPE_2D, width, height, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT); } // Create the Upload Buffer: @@ -578,7 +581,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) } // Store our identifier - io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontImage; + io.Fonts->TexID = (ImTextureID)(intptr_t)&g_FontTexture; return true; } @@ -639,17 +642,6 @@ bool ImGui_ImplVulkan_CreateDeviceObjects() check_vk_result(err); } - // Create Descriptor Set: - { - VkDescriptorSetAllocateInfo alloc_info = {}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = v->DescriptorPool; - alloc_info.descriptorSetCount = 1; - alloc_info.pSetLayouts = &g_DescriptorSetLayout; - err = vkAllocateDescriptorSets(v->Device, &alloc_info, &g_DescriptorSet); - check_vk_result(err); - } - if (!g_PipelineLayout) { // Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix @@ -795,7 +787,7 @@ void ImGui_ImplVulkan_DestroyDeviceObjects() ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &g_MainWindowRenderBuffers, v->Allocator); ImGui_ImplVulkan_DestroyFontUploadObjects(); - if (g_FontView) { vkDestroyImageView(v->Device, g_FontView, v->Allocator); g_FontView = VK_NULL_HANDLE; } + g_FontTexture.Destroy(false); if (g_FontImage) { vkDestroyImage(v->Device, g_FontImage, v->Allocator); g_FontImage = VK_NULL_HANDLE; } if (g_FontMemory) { vkFreeMemory(v->Device, g_FontMemory, v->Allocator); g_FontMemory = VK_NULL_HANDLE; } if (g_FontSampler) { vkDestroySampler(v->Device, g_FontSampler, v->Allocator); g_FontSampler = VK_NULL_HANDLE; } @@ -832,8 +824,9 @@ void ImGui_ImplVulkan_Shutdown() ImGui_ImplVulkan_DestroyDeviceObjects(); } -void ImGui_ImplVulkan_NewFrame() +void ImGui_ImplVulkan_NewFrame(VkDescriptorPool DescriptorPool) { + g_VulkanInitInfo.DescriptorPool = DescriptorPool; } void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count) diff --git a/src/frontend-common/imgui_impl_vulkan.h b/src/frontend-common/imgui_impl_vulkan.h index 8ad8180eb..6ee263a9b 100644 --- a/src/frontend-common/imgui_impl_vulkan.h +++ b/src/frontend-common/imgui_impl_vulkan.h @@ -45,7 +45,7 @@ struct ImGui_ImplVulkan_InitInfo // Called by user code IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass); IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(VkDescriptorPool DescriptorPool); IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer); IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects(); diff --git a/src/frontend-common/vulkan_host_display.cpp b/src/frontend-common/vulkan_host_display.cpp index 971c80876..fd6f5dd29 100644 --- a/src/frontend-common/vulkan_host_display.cpp +++ b/src/frontend-common/vulkan_host_display.cpp @@ -466,7 +466,7 @@ bool VulkanHostDisplay::CreateImGuiContext() return false; } - ImGui_ImplVulkan_NewFrame(); + ImGui_ImplVulkan_NewFrame(g_vulkan_context->GetCurrentDescriptorPool()); #endif return true; @@ -532,7 +532,7 @@ bool VulkanHostDisplay::Render() #ifdef WITH_IMGUI if (ImGui::GetCurrentContext()) - ImGui_ImplVulkan_NewFrame(); + ImGui_ImplVulkan_NewFrame(g_vulkan_context->GetCurrentDescriptorPool()); #endif return true;