Support packed RGB10 sampled render-target views

This commit is contained in:
nmzik
2026-07-16 19:21:20 +02:00
parent 0d7c7510d7
commit 9bed3bddd6
4 changed files with 50 additions and 22 deletions
+1 -1
View File
@@ -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) {}
+17 -9
View File
@@ -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);
}
@@ -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<int>(image->format), static_cast<int>(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,