diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 0096d34b..9a80f9ca 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -276,7 +276,13 @@ vk::BorderColor BorderColor(AmdGpu::BorderColor color) { } } -vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) { +vk::Format SurfaceFormat( + AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format, + Liverpool::ColorBuffer::SwapMode comp_swap /*= Liverpool::ColorBuffer::SwapMode::Standard*/) { + ASSERT_MSG(comp_swap == Liverpool::ColorBuffer::SwapMode::Standard || + comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate, + "Unsupported component swap mode {}", static_cast(comp_swap)); + if (data_format == AmdGpu::DataFormat::Format32_32_32_32 && num_format == AmdGpu::NumberFormat::Float) { return vk::Format::eR32G32B32A32Sfloat; @@ -287,11 +293,14 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu } if (data_format == AmdGpu::DataFormat::Format8_8_8_8 && num_format == AmdGpu::NumberFormat::Unorm) { - return vk::Format::eR8G8B8A8Unorm; + return comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate + ? vk::Format::eB8G8R8A8Unorm + : vk::Format::eR8G8B8A8Unorm; } if (data_format == AmdGpu::DataFormat::Format8_8_8_8 && num_format == AmdGpu::NumberFormat::Srgb) { - return vk::Format::eB8G8R8A8Srgb; + return comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate ? vk::Format::eB8G8R8A8Srgb + : vk::Format::eR8G8B8A8Srgb; } if (data_format == AmdGpu::DataFormat::Format32_32_32 && num_format == AmdGpu::NumberFormat::Float) { diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.h b/src/video_core/renderer_vulkan/liverpool_to_vk.h index 27569c4f..4146f2e8 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.h +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.h @@ -38,7 +38,9 @@ vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter); vk::BorderColor BorderColor(AmdGpu::BorderColor color); -vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format); +vk::Format SurfaceFormat( + AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format, + Liverpool::ColorBuffer::SwapMode comp_swap = Liverpool::ColorBuffer::SwapMode::Standard); vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format, Liverpool::DepthBuffer::StencilFormat stencil_format); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index d8992e6e..425465c0 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -129,8 +129,8 @@ void PipelineCache::RefreshGraphicsKey() { if (!col_buf) { continue; } - key.color_formats[remapped_cb] = - LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat()); + key.color_formats[remapped_cb] = LiverpoolToVK::SurfaceFormat( + col_buf.info.format, col_buf.NumFormat(), col_buf.info.comp_swap.Value()); key.blend_controls[remapped_cb] = regs.blend_control[cb]; key.blend_controls[remapped_cb].enable.Assign(key.blend_controls[remapped_cb].enable && !col_buf.info.blend_bypass); diff --git a/src/video_core/texture_cache/image_view.cpp b/src/video_core/texture_cache/image_view.cpp index 59fb47b5..dbe93888 100644 --- a/src/video_core/texture_cache/image_view.cpp +++ b/src/video_core/texture_cache/image_view.cpp @@ -62,6 +62,11 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexce } } +ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept { + format = Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.info.format, col_buffer.NumFormat(), + col_buffer.info.comp_swap.Value()); +} + ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, Image& image, std::optional usage_override /*= {}*/) : info{info_} { diff --git a/src/video_core/texture_cache/image_view.h b/src/video_core/texture_cache/image_view.h index 83936acc..403e074e 100644 --- a/src/video_core/texture_cache/image_view.h +++ b/src/video_core/texture_cache/image_view.h @@ -3,6 +3,7 @@ #pragma once +#include "video_core/amdgpu/liverpool.h" #include "video_core/amdgpu/resource.h" #include "video_core/renderer_vulkan/vk_common.h" #include "video_core/texture_cache/types.h" @@ -19,6 +20,7 @@ namespace VideoCore { struct ImageViewInfo { explicit ImageViewInfo() = default; explicit ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexcept; + explicit ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept; vk::ImageViewType type = vk::ImageViewType::e2D; vk::Format format = vk::Format::eR8G8B8A8Unorm; diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 8c910c03..09094c65 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -183,8 +183,7 @@ ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buff vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead); - ImageViewInfo view_info; - view_info.format = info.pixel_format; + ImageViewInfo view_info{buffer}; return RegisterImageView(image, view_info); } diff --git a/src/video_core/texture_cache/tile_manager.cpp b/src/video_core/texture_cache/tile_manager.cpp index 723487a6..3d1cc5c5 100644 --- a/src/video_core/texture_cache/tile_manager.cpp +++ b/src/video_core/texture_cache/tile_manager.cpp @@ -178,8 +178,12 @@ vk::Format DemoteImageFormatForDetiling(vk::Format format) { switch (format) { case vk::Format::eR8Unorm: return vk::Format::eR8Uint; + case vk::Format::eR8G8B8A8Srgb: + [[fallthrough]]; case vk::Format::eB8G8R8A8Srgb: [[fallthrough]]; + case vk::Format::eB8G8R8A8Unorm: + [[fallthrough]]; case vk::Format::eR8G8B8A8Unorm: return vk::Format::eR32Uint; case vk::Format::eBc1RgbaUnormBlock: