From 7dfcf8c0bdff1dfd4ff584ef178de1ae70dcb615 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:43:23 +0300 Subject: [PATCH] vk_pipeline_cache: Add fallbacks for R8Srgb and B5G6R5 --- src/shader_recompiler/runtime_info.h | 1 + .../renderer_vulkan/vk_graphics_pipeline.cpp | 17 ++++++++++++++++- .../renderer_vulkan/vk_graphics_pipeline.h | 1 - src/video_core/renderer_vulkan/vk_instance.cpp | 12 ++++++++++++ .../renderer_vulkan/vk_pipeline_cache.cpp | 15 ++------------- src/video_core/texture_cache/image.cpp | 2 +- src/video_core/texture_cache/image_info.cpp | 11 ----------- src/video_core/texture_cache/image_info.h | 1 - 8 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index 6cede44a8..61954bec2 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h @@ -171,6 +171,7 @@ enum class MrtSwizzle : u8 { static constexpr u32 MaxColorBuffers = 8; struct PsColorBuffer { + AmdGpu::DataFormat data_format : 6; AmdGpu::NumberFormat num_format : 4; AmdGpu::NumberConversion num_conversion : 3; AmdGpu::Liverpool::ShaderExportFormat export_format : 4; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4d89c83b2..8094bc260 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -244,9 +244,24 @@ GraphicsPipeline::GraphicsPipeline( const auto depth_format = instance.GetSupportedFormat(LiverpoolToVK::DepthFormat(key.z_format, key.stencil_format), vk::FormatFeatureFlagBits2::eDepthStencilAttachment); + std::array color_formats; + for (s32 i = 0; i < key.num_color_attachments; ++i) { + const auto& col_buf = key.color_buffers[i]; + const auto format = LiverpoolToVK::SurfaceFormat(col_buf.data_format, col_buf.num_format); + const auto color_format = + instance.GetSupportedFormat(format, vk::FormatFeatureFlagBits2::eColorAttachment); + if (!instance.IsFormatSupported(color_format, + vk::FormatFeatureFlagBits2::eColorAttachment)) { + LOG_WARNING(Render_Vulkan, + "color buffer format {} does not support COLOR_ATTACHMENT_BIT", + vk::to_string(color_format)); + } + color_formats[i] = color_format; + } + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci = { .colorAttachmentCount = key.num_color_attachments, - .pColorAttachmentFormats = key.color_formats.data(), + .pColorAttachmentFormats = color_formats.data(), .depthAttachmentFormat = key.z_format != Liverpool::DepthBuffer::ZFormat::Invalid ? depth_format : vk::Format::eUndefined, diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 75b8c8c73..aaf47ba7d 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -36,7 +36,6 @@ struct GraphicsPipelineKey { std::array vertex_buffer_formats; u32 patch_control_points; u32 num_color_attachments; - std::array color_formats; std::array color_buffers; std::array blend_controls; std::array write_masks; diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 119c0a367..43b92d632 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -70,6 +70,7 @@ std::unordered_map GetFormatProperties( vk::Format::eB8G8R8A8Unorm, vk::Format::eB8G8R8A8Srgb, vk::Format::eD24UnormS8Uint, + vk::Format::eR5G6B5UnormPack16, }; for (const auto& format : misc_formats) { if (!format_properties.contains(format)) { @@ -669,6 +670,17 @@ vk::Format Instance::GetSupportedFormat(const vk::Format format, if (IsFormatSupported(vk::Format::eD32SfloatS8Uint, flags)) { return vk::Format::eD32SfloatS8Uint; } + break; + case vk::Format::eR8Srgb: + if (IsFormatSupported(vk::Format::eR8Unorm, flags)) { + return vk::Format::eR8Unorm; + } + break; + case vk::Format::eB5G6R5UnormPack16: + if (IsFormatSupported(vk::Format::eR5G6B5UnormPack16, flags)) { + return vk::Format::eR5G6B5UnormPack16; + } + break; default: break; } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 4de8fd73b..78af5a14c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -312,7 +312,6 @@ bool PipelineCache::RefreshGraphicsKey() { // attachments. This might be not a case as HW color buffers can be bound in an arbitrary // order. We need to do some arrays compaction at this stage key.num_color_attachments = 0; - key.color_formats.fill(vk::Format::eUndefined); key.color_buffers.fill({}); key.blend_controls.fill({}); key.write_masks.fill({}); @@ -348,16 +347,8 @@ bool PipelineCache::RefreshGraphicsKey() { col_buf.GetDataFmt() == AmdGpu::DataFormat::Format8_8 || col_buf.GetDataFmt() == AmdGpu::DataFormat::Format8_8_8_8); - const auto format = - LiverpoolToVK::SurfaceFormat(col_buf.GetDataFmt(), col_buf.GetNumberFmt()); - key.color_formats[remapped_cb] = format; - if (!instance.IsFormatSupported(format, vk::FormatFeatureFlagBits2::eColorAttachment)) { - LOG_WARNING(Render_Vulkan, - "color buffer format {} does not support COLOR_ATTACHMENT_BIT", - vk::to_string(format)); - } - key.color_buffers[remapped_cb] = Shader::PsColorBuffer{ + .data_format = col_buf.GetDataFmt(), .num_format = col_buf.GetNumberFmt(), .num_conversion = col_buf.GetNumberConversion(), .export_format = regs.color_export_format.GetFormat(cb), @@ -476,9 +467,7 @@ bool PipelineCache::RefreshGraphicsKey() { // Attachment is masked out by either color_target_mask or shader mrt_mask. In the case // of the latter we need to change format to undefined, and either way we need to // increment the index for the null attachment binding. - key.color_formats[remapped_cb] = vk::Format::eUndefined; - key.color_buffers[remapped_cb] = {}; - ++remapped_cb; + key.color_buffers[remapped_cb++] = {}; continue; } diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 7b8ff4403..4ab2e991c 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -21,7 +21,7 @@ static vk::ImageUsageFlags ImageUsageFlags(const ImageInfo& info) { if (info.IsDepthStencil()) { usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; } else { - if (!info.IsBlockCoded() && !info.IsPacked()) { + if (!info.IsBlockCoded()) { usage |= vk::ImageUsageFlagBits::eColorAttachment; } // In cases where an image is created as a render/depth target and cleared with compute, diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 769c4211f..ed10a20bf 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -176,17 +176,6 @@ bool ImageInfo::IsBlockCoded() const { } } -bool ImageInfo::IsPacked() const { - switch (pixel_format) { - case vk::Format::eB5G5R5A1UnormPack16: - [[fallthrough]]; - case vk::Format::eB5G6R5UnormPack16: - return true; - default: - return false; - } -} - bool ImageInfo::IsDepthStencil() const { switch (pixel_format) { case vk::Format::eD16Unorm: diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h index dbd7f7cbb..9fa3b6c3d 100644 --- a/src/video_core/texture_cache/image_info.h +++ b/src/video_core/texture_cache/image_info.h @@ -31,7 +31,6 @@ struct ImageInfo { } bool IsBlockCoded() const; - bool IsPacked() const; bool IsDepthStencil() const; bool HasStencil() const;