From 1d3427780a118532d6c74788f4bc7f8fc78d12f4 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Fri, 17 Jan 2025 00:16:03 -0800 Subject: [PATCH] renderer_vulkan: Fix present related validation errors. (#2169) --- src/imgui/renderer/imgui_impl_vulkan.cpp | 5 +---- src/imgui/renderer/imgui_impl_vulkan.h | 1 - src/video_core/renderer_vulkan/vk_instance.cpp | 2 +- src/video_core/renderer_vulkan/vk_presenter.cpp | 10 ++++++++-- src/video_core/renderer_vulkan/vk_swapchain.cpp | 14 +++++++++++++- src/video_core/renderer_vulkan/vk_swapchain.h | 5 +++++ 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/imgui/renderer/imgui_impl_vulkan.cpp b/src/imgui/renderer/imgui_impl_vulkan.cpp index bd98fa004..104ce4b52 100644 --- a/src/imgui/renderer/imgui_impl_vulkan.cpp +++ b/src/imgui/renderer/imgui_impl_vulkan.cpp @@ -687,8 +687,6 @@ void RenderDrawData(ImDrawData& draw_data, vk::CommandBuffer command_buffer, vk::DescriptorSet desc_set[1]{pcmd->TextureId->descriptor_set}; command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, bd->pipeline_layout, 0, {desc_set}, {}); - command_buffer.setColorBlendEnableEXT( - 0, {pcmd->TextureId->disable_blend ? vk::False : vk::True}); // Draw command_buffer.drawIndexed(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, @@ -1058,10 +1056,9 @@ static void CreatePipeline(vk::Device device, const vk::AllocationCallbacks* all .pAttachments = color_attachment, }; - vk::DynamicState dynamic_states[3]{ + vk::DynamicState dynamic_states[2]{ vk::DynamicState::eViewport, vk::DynamicState::eScissor, - vk::DynamicState::eColorBlendEnableEXT, }; vk::PipelineDynamicStateCreateInfo dynamic_state{ .dynamicStateCount = (uint32_t)IM_ARRAYSIZE(dynamic_states), diff --git a/src/imgui/renderer/imgui_impl_vulkan.h b/src/imgui/renderer/imgui_impl_vulkan.h index 05f4489da..9b15dcae6 100644 --- a/src/imgui/renderer/imgui_impl_vulkan.h +++ b/src/imgui/renderer/imgui_impl_vulkan.h @@ -13,7 +13,6 @@ struct ImDrawData; namespace ImGui { struct Texture { vk::DescriptorSet descriptor_set{nullptr}; - bool disable_blend{false}; }; } // namespace ImGui diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 323b30816..1600600b9 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -270,6 +270,7 @@ bool Instance::CreateDevice() { legacy_vertex_attributes = add_extension(VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME); image_load_store_lod = add_extension(VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME); amd_gcn_shader = add_extension(VK_AMD_GCN_SHADER_EXTENSION_NAME); + add_extension(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); // These extensions are promoted by Vulkan 1.3, but for greater compatibility we use Vulkan 1.2 // with extensions. @@ -383,7 +384,6 @@ bool Instance::CreateDevice() { .extendedDynamicState = true, }, vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT{ - .extendedDynamicState3ColorBlendEnable = true, .extendedDynamicState3ColorWriteMask = true, }, vk::PhysicalDeviceDepthClipControlFeaturesEXT{ diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index 95c7c4ea1..0f45574bc 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -380,7 +380,7 @@ void Presenter::RecreateFrame(Frame* frame, u32 width, u32 height) { const vk::ImageViewCreateInfo view_info = { .image = frame->image, .viewType = vk::ImageViewType::e2D, - .format = FormatToUnorm(format), + .format = swapchain.GetViewFormat(), .subresourceRange{ .aspectMask = vk::ImageAspectFlagBits::eColor, .baseMipLevel = 0, @@ -397,7 +397,6 @@ void Presenter::RecreateFrame(Frame* frame, u32 width, u32 height) { frame->height = height; frame->imgui_texture = ImGui::Vulkan::AddTexture(view, vk::ImageLayout::eShaderReadOnlyOptimal); - frame->imgui_texture->disable_blend = true; } Frame* Presenter::PrepareLastFrame() { @@ -615,6 +614,13 @@ Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) VideoCore::ImageViewInfo info{}; info.format = image.info.pixel_format; + // Exclude alpha from output frame to avoid blending with UI. + info.mapping = vk::ComponentMapping{ + .r = vk::ComponentSwizzle::eIdentity, + .g = vk::ComponentSwizzle::eIdentity, + .b = vk::ComponentSwizzle::eIdentity, + .a = vk::ComponentSwizzle::eOne, + }; if (auto view = image.FindView(info)) { image_info.imageView = *texture_cache.GetImageView(view).image_view; } else { diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 556cccd32..438fe30ce 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -17,7 +17,7 @@ Swapchain::Swapchain(const Instance& instance_, const Frontend::WindowSDL& windo FindPresentFormat(); Create(window.GetWidth(), window.GetHeight()); - ImGui::Core::Initialize(instance, window, image_count, surface_format.format); + ImGui::Core::Initialize(instance, window, image_count, view_format); } Swapchain::~Swapchain() { @@ -57,7 +57,17 @@ void Swapchain::Create(u32 width_, u32 height_) { const u32 queue_family_indices_count = exclusive ? 1u : 2u; const vk::SharingMode sharing_mode = exclusive ? vk::SharingMode::eExclusive : vk::SharingMode::eConcurrent; + const vk::Format view_formats[2] = { + surface_format.format, + view_format, + }; + const vk::ImageFormatListCreateInfo format_list = { + .viewFormatCount = 2, + .pViewFormats = view_formats, + }; const vk::SwapchainCreateInfoKHR swapchain_info = { + .pNext = &format_list, + .flags = vk::SwapchainCreateFlagBitsKHR::eMutableFormat, .surface = surface, .minImageCount = image_count, .imageFormat = surface_format.format, @@ -149,6 +159,7 @@ void Swapchain::FindPresentFormat() { if (formats[0].format == vk::Format::eUndefined) { surface_format.format = vk::Format::eR8G8B8A8Srgb; surface_format.colorSpace = vk::ColorSpaceKHR::eSrgbNonlinear; + view_format = FormatToUnorm(surface_format.format); return; } @@ -161,6 +172,7 @@ void Swapchain::FindPresentFormat() { surface_format.format = format; surface_format.colorSpace = sformat.colorSpace; + view_format = FormatToUnorm(surface_format.format); return; } diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index 192271f32..9da75c758 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h @@ -61,6 +61,10 @@ public: return surface_format; } + vk::Format GetViewFormat() const { + return view_format; + } + vk::SwapchainKHR GetHandle() const { return swapchain; } @@ -114,6 +118,7 @@ private: vk::SwapchainKHR swapchain{}; vk::SurfaceKHR surface{}; vk::SurfaceFormatKHR surface_format; + vk::Format view_format; vk::Extent2D extent; vk::SurfaceTransformFlagBitsKHR transform; vk::CompositeAlphaFlagBitsKHR composite_alpha;