diff --git a/src/graphics/host_gpu/graphicContext.h b/src/graphics/host_gpu/graphicContext.h index 6b693d87..6c455fb7 100644 --- a/src/graphics/host_gpu/graphicContext.h +++ b/src/graphics/host_gpu/graphicContext.h @@ -89,7 +89,7 @@ struct VulkanImage { static constexpr int VIEW_STENCIL_TEXTURE_ARRAY = 17; static constexpr int VIEW_STORAGE = 18; static constexpr int VIEW_STORAGE_ARRAY = 19; - static constexpr int VIEW_RGBA8_BGRA = 20; + static constexpr int VIEW_BGRA_TO_RGBA = 20; 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 14753f1b..ef42c577 100644 --- a/src/graphics/host_gpu/renderer/imageView.h +++ b/src/graphics/host_gpu/renderer/imageView.h @@ -39,17 +39,25 @@ namespace Libs::Graphics { switch (image_format) { case VK_FORMAT_B8G8R8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; case VK_FORMAT_B8G8R8A8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB; + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return VK_FORMAT_A2B10G10R10_UNORM_PACK32; default: return VK_FORMAT_UNDEFINED; } } -[[nodiscard]] inline bool IsBgraToRgba8SampledView(VkFormat image_format, - VkFormat view_format) noexcept { - const bool bgra8 = - image_format == VK_FORMAT_B8G8R8A8_UNORM || image_format == VK_FORMAT_B8G8R8A8_SRGB; - const bool rgba8 = - view_format == VK_FORMAT_R8G8B8A8_UNORM || view_format == VK_FORMAT_R8G8B8A8_SRGB; - return bgra8 && rgba8; +[[nodiscard]] inline bool IsBgraToRgbaSampledView(VkFormat image_format, + VkFormat view_format) noexcept { + switch (image_format) { + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SRGB: + switch (view_format) { + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SRGB: return true; + default: return false; + } + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + return view_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32; + default: return false; + } } [[nodiscard]] inline VkFormat BgraSrgbStorageViewFormat(VkFormat image_format) noexcept { @@ -72,8 +80,8 @@ namespace Libs::Graphics { default: break; } } - if (IsBgraToRgba8SampledView(image_format, view_format) && swizzle == DstSel(6, 5, 4, 7)) { - return VulkanImage::VIEW_RGBA8_BGRA; + if (IsBgraToRgbaSampledView(image_format, view_format) && swizzle == DstSel(6, 5, 4, 7)) { + return VulkanImage::VIEW_BGRA_TO_RGBA; } UnsupportedColorView("sampled", image_format, view_format, swizzle); } diff --git a/src/graphics/host_gpu/renderer/textureCache.cpp b/src/graphics/host_gpu/renderer/textureCache.cpp index ee4c4763..b6756758 100644 --- a/src/graphics/host_gpu/renderer/textureCache.cpp +++ b/src/graphics/host_gpu/renderer/textureCache.cpp @@ -654,7 +654,10 @@ bool RenderTargetSupportsStorage(GraphicContext* ctx, VkFormat format, VkImageCr } VkImageCreateFlags RenderTargetCreateFlags(VkFormat format) { - return IsRgba8SrgbViewFormat(format) + const bool compatible_format_view = + IsRgba8SrgbViewFormat(format) || + BgraToRgbaSampledViewFormat(format) != VK_FORMAT_UNDEFINED; + return compatible_format_view ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT : VkImageCreateFlags {0}; } @@ -742,7 +745,7 @@ void CreateRenderTargetViews(GraphicContext* ctx, RenderTextureVulkanImage* imag } const auto rgba_view_format = BgraToRgbaSampledViewFormat(image->format); if (rgba_view_format != VK_FORMAT_UNDEFINED) { - CreateRenderTargetView(ctx, image, VulkanImage::VIEW_RGBA8_BGRA, VK_COMPONENT_SWIZZLE_B, + CreateRenderTargetView(ctx, image, VulkanImage::VIEW_BGRA_TO_RGBA, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A, VK_IMAGE_VIEW_TYPE_2D, rgba_view_format, VK_IMAGE_USAGE_SAMPLED_BIT); @@ -1083,14 +1086,14 @@ VkImageView TextureCache::GetRenderTargetSampledView(GraphicContext* c level_count, image != nullptr ? image->mip_levels : 0); } const bool compatible_variant_format = - view_format == image->format || (variant == VulkanImage::VIEW_RGBA8_BGRA && - IsBgraToRgba8SampledView(image->format, view_format)); + view_format == image->format || (variant == VulkanImage::VIEW_BGRA_TO_RGBA && + IsBgraToRgbaSampledView(image->format, view_format)); if (!compatible_variant_format) { EXIT("TextureCache: incompatible render-target sampled view format, image_format=%d" " view_format=%d variant=%d\n", static_cast(image->format), static_cast(view_format), variant); } - const auto default_view_format = variant == VulkanImage::VIEW_RGBA8_BGRA + const auto default_view_format = variant == VulkanImage::VIEW_BGRA_TO_RGBA ? BgraToRgbaSampledViewFormat(image->format) : image->format; if (view_format == default_view_format && base_level == 0 && level_count == image->mip_levels) { @@ -1137,8 +1140,8 @@ VkImageView TextureCache::GetRenderTargetSampledView(GraphicContext* c components = {VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_R}; break; - case VulkanImage::VIEW_RGBA8_BGRA: - if (!IsBgraToRgba8SampledView(image->format, view_format)) { + case VulkanImage::VIEW_BGRA_TO_RGBA: + if (!IsBgraToRgbaSampledView(image->format, view_format)) { EXIT("TextureCache: incompatible mutable render-target sampled view\n"); } components = {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 4fdaf056..f21175b4 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -8699,6 +8699,14 @@ bool CacheFault(void *opaque, PageFaultAccess access, uint64_t vaddr, (void)SelectSampledColorView(VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_UNORM, DstSel(4, 5, 6, 7)); + } else if (std::strcmp(kind, "sampled-rgb10-swizzle") == 0) { + (void)SelectSampledColorView(VK_FORMAT_A2R10G10B10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_UNORM_PACK32, + DstSel(4, 5, 6, 7)); + } else if (std::strcmp(kind, "sampled-rgb10-reverse") == 0) { + (void)SelectSampledColorView(VK_FORMAT_A2B10G10R10_UNORM_PACK32, + VK_FORMAT_A2R10G10B10_UNORM_PACK32, + DstSel(6, 5, 4, 7)); } else if (std::strcmp(kind, "sampled-depth-format") == 0) { (void)SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_R16_UNORM, DstSel(4, 4, 4, 4)); @@ -8762,12 +8770,12 @@ void CheckSampledColorViews() { Require("SampledColorViews", "mutable BGRA target", SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, - DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_RGBA8_BGRA, + DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_BGRA_TO_RGBA, "BGRA target did not select the exact RGBA/BGRA mutable view"); Require("SampledColorViews", "mutable sRGB view of UNORM BGRA target", SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, - DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_RGBA8_BGRA, + DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_BGRA_TO_RGBA, "UNORM BGRA target did not select its compatible sRGB RGBA sampled view"); Require("SampledColorViews", "mutable sRGB BGRA target", BgraToRgbaSampledViewFormat(VK_FORMAT_B8G8R8A8_SRGB) == @@ -8775,8 +8783,16 @@ void CheckSampledColorViews() { SelectSampledColorView(VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_R8G8B8A8_SRGB, DstSel(6, 5, 4, 7)) == - VulkanImage::VIEW_RGBA8_BGRA, + VulkanImage::VIEW_BGRA_TO_RGBA, "sRGB BGRA target did not select its matching mutable RGBA view"); + Require("SampledColorViews", "mutable packed RGB10 view", + BgraToRgbaSampledViewFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32) == + VK_FORMAT_A2B10G10R10_UNORM_PACK32 && + SelectSampledColorView(VK_FORMAT_A2R10G10B10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_UNORM_PACK32, + DstSel(6, 5, 4, 7)) == + VulkanImage::VIEW_BGRA_TO_RGBA, + "packed RGB10 target did not select its matching mutable channel-order view"); Require("SampledColorViews", "D32 depth target", SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_R32_SFLOAT, @@ -8857,8 +8873,9 @@ void CheckSampledColorViews() { for (const char *kind : {"sampled", "sampled-compatible-swizzle", "sampled-compatible-reverse", "sampled-compatible-class", "sampled-compatible-colorspace", - "sampled-compatible-snorm", "sampled-depth-format", - "sampled-depth-swizzle", "storage", "storage-format", + "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", "storage-atomic", "storage-compare", "storage-mip", "storage-dimension"}) {