vk: Implement SNORM and SRGB format overrides

This commit is contained in:
kd-11 2026-02-22 18:14:27 +03:00 committed by kd-11
parent 4c20bdcc9f
commit 3f174b2a97
3 changed files with 104 additions and 9 deletions

View file

@ -321,23 +321,53 @@ void VKGSRender::load_texture_env()
continue;
}
sampler_state->format_ex = tex.format_ex();
if (sampler_state->is_cyclic_reference)
{
check_for_cyclic_refs |= true;
}
if (!is_sampler_dirty && sampler_state->format_class != previous_format_class)
if (!is_sampler_dirty)
{
// Host details changed but RSX is not aware
m_graphics_state |= rsx::fragment_program_state_dirty;
if (sampler_state->format_class != previous_format_class)
{
// Host details changed but RSX is not aware
m_graphics_state |= rsx::fragment_program_state_dirty;
}
if (fs_sampler_handles[i])
{
// Nothing to change, use cached sampler
continue;
}
}
if (!is_sampler_dirty && fs_sampler_handles[i])
sampler_state->format_ex = tex.format_ex();
if (sampler_state->format_ex.texel_remap_control &&
sampler_state->image_handle &&
sampler_state->upload_context == rsx::texture_upload_context::shader_read) [[ unlikely ]]
{
// Nothing to change, use cached sampler
continue;
// Check if we need to override the view format
const auto vk_format = sampler_state->image_handle->format();
VkFormat format_override = vk_format;;
rsx::flags32_t flags_to_erase = 0u;
if (sampler_state->format_ex.hw_SNORM_possible())
{
format_override = vk::get_compatible_snorm_format(vk_format);
flags_to_erase = rsx::texture_control_bits::SEXT_MASK;
}
else if (sampler_state->format_ex.hw_SRGB_possible())
{
format_override = vk::get_compatible_srgb_format(vk_format);
flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK;
}
if (format_override != VK_FORMAT_UNDEFINED && format_override != vk_format)
{
sampler_state->image_handle = sampler_state->image_handle->as(format_override);
sampler_state->format_ex.texel_remap_control &= (~flags_to_erase);
}
}
VkFilter mag_filter;

View file

@ -244,16 +244,80 @@ namespace vk
{
switch (rgb_format)
{
// 8-bit
case VK_FORMAT_R8_UNORM:
return VK_FORMAT_R8_SRGB;
case VK_FORMAT_R8G8_UNORM:
return VK_FORMAT_R8G8_SRGB;
case VK_FORMAT_R8G8B8A8_UNORM:
return VK_FORMAT_R8G8B8A8_SRGB;
case VK_FORMAT_B8G8R8A8_UNORM:
return VK_FORMAT_B8G8R8A8_SRGB;
// 16-bit
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16G16_UNORM:
return VK_FORMAT_UNDEFINED; // No match
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
return VK_FORMAT_UNDEFINED; // No match
// DXT
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
case VK_FORMAT_BC2_UNORM_BLOCK:
return VK_FORMAT_BC2_SRGB_BLOCK;
case VK_FORMAT_BC3_UNORM_BLOCK:
return VK_FORMAT_BC3_SRGB_BLOCK;
// Depth
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
return VK_FORMAT_UNDEFINED; // Unsupported
default:
return rgb_format;
rsx_log.error("[SRGB_FMT] Unexpected VkFormat 0x%x", static_cast<int>(rgb_format));
return VK_FORMAT_UNDEFINED;
}
}
VkFormat get_compatible_snorm_format(VkFormat rgb_format)
{
switch (rgb_format)
{
// 8-bit
case VK_FORMAT_R8_UNORM:
return VK_FORMAT_R8_SNORM;
case VK_FORMAT_R8G8_UNORM:
return VK_FORMAT_R8G8_SNORM;
case VK_FORMAT_R8G8B8A8_UNORM:
return VK_FORMAT_R8G8B8A8_SNORM;
case VK_FORMAT_B8G8R8A8_UNORM:
return VK_FORMAT_B8G8R8A8_SNORM;
// 16-bit
case VK_FORMAT_R16_UNORM:
return VK_FORMAT_R16_SNORM;
case VK_FORMAT_R16G16_UNORM:
return VK_FORMAT_R16G16_SNORM;
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
return VK_FORMAT_UNDEFINED; // No match
// DXT
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
return VK_FORMAT_UNDEFINED; // No match
// Depth
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
return VK_FORMAT_UNDEFINED; // Unsupported
default:
rsx_log.error("[SEXT_FMT] Unexpected VkFormat 0x%x", static_cast<int>(rgb_format));
return VK_FORMAT_UNDEFINED;
}
}

View file

@ -19,6 +19,7 @@ namespace vk
VkFormat get_compatible_depth_surface_format(const gpu_formats_support& support, rsx::surface_depth_format2 format);
VkFormat get_compatible_sampler_format(const gpu_formats_support& support, u32 format);
VkFormat get_compatible_srgb_format(VkFormat rgb_format);
VkFormat get_compatible_snorm_format(VkFormat rgb_format);
u8 get_format_texel_width(VkFormat format);
std::pair<u8, u8> get_format_element_size(VkFormat format);
std::pair<bool, u32> get_format_convert_flags(VkFormat format);