From 1416131a0a98e551adc5d3dad142732e76bc27bf Mon Sep 17 00:00:00 2001 From: nmzik Date: Fri, 17 Jul 2026 12:55:33 +0200 Subject: [PATCH] Support reciprocal ABGR sampled views --- src/graphics/host_gpu/graphicContext.h | 3 ++- src/graphics/host_gpu/renderer/imageView.h | 4 ++++ .../host_gpu/renderer/textureCache.cpp | 4 ++++ tests/ShaderRecompilerComputeTests.cpp | 19 ++++++++++++++++--- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/graphics/host_gpu/graphicContext.h b/src/graphics/host_gpu/graphicContext.h index baec3a4f8..343451a2e 100644 --- a/src/graphics/host_gpu/graphicContext.h +++ b/src/graphics/host_gpu/graphicContext.h @@ -67,7 +67,7 @@ enum class VulkanImageType { }; struct VulkanImage { - static constexpr int VIEW_MAX = 21; + static constexpr int VIEW_MAX = 22; static constexpr int VIEW_DEFAULT = 0; static constexpr int VIEW_BGRA = 1; static constexpr int VIEW_DEPTH_TEXTURE = 2; @@ -89,6 +89,7 @@ struct VulkanImage { static constexpr int VIEW_STORAGE = 18; static constexpr int VIEW_STORAGE_ARRAY = 19; static constexpr int VIEW_BGRA_TO_RGBA = 20; + static constexpr int VIEW_ABGR = 21; explicit VulkanImage(VulkanImageType type): type(type) {} diff --git a/src/graphics/host_gpu/renderer/imageView.h b/src/graphics/host_gpu/renderer/imageView.h index 5a1d8aef5..e80bbe932 100644 --- a/src/graphics/host_gpu/renderer/imageView.h +++ b/src/graphics/host_gpu/renderer/imageView.h @@ -84,6 +84,10 @@ namespace Libs::Graphics { default: break; } } + if (image_format == VK_FORMAT_R16G16B16A16_SFLOAT && view_format == image_format && + swizzle == DstSel(7, 6, 5, 4)) { + return VulkanImage::VIEW_ABGR; + } if (IsBgraToRgbaSampledView(image_format, view_format) && swizzle == DstSel(6, 5, 4, 7)) { return VulkanImage::VIEW_BGRA_TO_RGBA; } diff --git a/src/graphics/host_gpu/renderer/textureCache.cpp b/src/graphics/host_gpu/renderer/textureCache.cpp index 1934f613a..0f0abb6c6 100644 --- a/src/graphics/host_gpu/renderer/textureCache.cpp +++ b/src/graphics/host_gpu/renderer/textureCache.cpp @@ -1437,6 +1437,10 @@ VkImageView TextureCache::GetRenderTargetSampledView(GraphicContext* c components = {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A}; break; + case VulkanImage::VIEW_ABGR: + components = {VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_R}; + break; default: EXIT("TextureCache: unsupported render-target sampled view variant: %d\n", variant); } diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index a12ad5140..e11a64647 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -8754,6 +8754,10 @@ void CheckReverseRenderTargetFormatContract() { (void)SelectSampledColorView(VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32, DstSel(6, 5, 4, 7)); + } else if (std::strcmp(kind, "sampled-abgr-format") == 0) { + (void)SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_UNORM, + DstSel(7, 6, 5, 4)); } else if (std::strcmp(kind, "sampled-depth-format") == 0) { (void)SelectSampledDepthView(VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_R32_SFLOAT, DstSel(4, 4, 4, 4)); @@ -8769,6 +8773,10 @@ void CheckReverseRenderTargetFormatContract() { } else if (std::strcmp(kind, "storage-compatible-swizzle") == 0) { (void)SelectStorageColorView(VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM, DstSel(4, 5, 6, 7)); + } else if (std::strcmp(kind, "storage-abgr") == 0) { + (void)SelectStorageColorView(VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R16G16B16A16_SFLOAT, + DstSel(7, 6, 5, 4)); } else { ShaderRecompiler::IR::ImageResource resource{}; resource.kind = ShaderRecompiler::IR::ResourceKind::StorageImage; @@ -8840,6 +8848,11 @@ void CheckSampledColorViews() { DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_BGRA_TO_RGBA, "packed RGB10 target did not select its matching mutable channel-order view"); + Require("SampledColorViews", "reverse RGBA16F sampled view", + SelectSampledColorView(VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R16G16B16A16_SFLOAT, + DstSel(7, 6, 5, 4)) == VulkanImage::VIEW_ABGR, + "reverse RGBA16F target did not select its reciprocal ABGR sampled view"); Require("SampledColorViews", "D32 depth target", SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_R32_SFLOAT, @@ -8948,9 +8961,9 @@ void CheckSampledColorViews() { {"sampled", "sampled-compatible-swizzle", "sampled-compatible-reverse", "sampled-compatible-class", "sampled-compatible-colorspace", "sampled-compatible-snorm", "sampled-rgb10-swizzle", - "sampled-rgb10-reverse", "sampled-depth-format", "sampled-depth-swizzle", - "storage", "storage-format", - "storage-compatible-swizzle", "storage-kind", "storage-no-write", + "sampled-rgb10-reverse", "sampled-abgr-format", "sampled-depth-format", + "sampled-depth-swizzle", "storage", "storage-format", + "storage-compatible-swizzle", "storage-abgr", "storage-kind", "storage-no-write", "storage-atomic", "storage-compare", "storage-mip", "storage-dimension"}) { std::string command =