vulkan: Add support for A2R10G10B10 HDR format (#16435)

This commit is contained in:
Carlo Refice 2024-04-18 16:34:46 +02:00 committed by GitHub
parent 970f404392
commit adaa19cbf7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 50 deletions

View File

@ -1886,6 +1886,17 @@ retry:
vulkan_acquire_wait_fences(vk); vulkan_acquire_wait_fences(vk);
} }
#ifdef VULKAN_HDR_SWAPCHAIN
bool vulkan_is_hdr10_format(VkFormat format)
{
return
(
format == VK_FORMAT_A2B10G10R10_UNORM_PACK32
|| format == VK_FORMAT_A2R10G10B10_UNORM_PACK32
);
}
#endif /* VULKAN_HDR_SWAPCHAIN */
bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
unsigned width, unsigned height, unsigned width, unsigned height,
unsigned swap_interval) unsigned swap_interval)
@ -2067,11 +2078,12 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
for (i = 0; i < format_count; i++) for (i = 0; i < format_count; i++)
{ {
if ( (formats[i].format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) if ( (vulkan_is_hdr10_format(formats[i].format))
&& (formats[i].colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT)) && (formats[i].colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT))
{ {
format = formats[i]; format = formats[i];
video_driver_set_hdr_support(); video_driver_set_hdr_support();
break;
} }
} }

View File

@ -728,6 +728,10 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
void vulkan_debug_mark_image(VkDevice device, VkImage image); void vulkan_debug_mark_image(VkDevice device, VkImage image);
void vulkan_debug_mark_memory(VkDevice device, VkDeviceMemory memory); void vulkan_debug_mark_memory(VkDevice device, VkDeviceMemory memory);
#ifdef VULKAN_HDR_SWAPCHAIN
bool vulkan_is_hdr10_format(VkFormat format);
#endif /* VULKAN_HDR_SWAPCHAIN */
RETRO_END_DECLS RETRO_END_DECLS
#endif #endif

View File

@ -2776,31 +2776,30 @@ static bool vulkan_init_default_filter_chain(vk_t *vk)
: VK_FORMAT_UNDEFINED; : VK_FORMAT_UNDEFINED;
bool emits_hdr10 = shader_preset && shader_preset->passes && vulkan_filter_chain_emits_hdr10(vk->filter_chain); bool emits_hdr10 = shader_preset && shader_preset->passes && vulkan_filter_chain_emits_hdr10(vk->filter_chain);
switch (rt_format) if (vulkan_is_hdr10_format(rt_format))
{ {
case VK_FORMAT_A2B10G10R10_UNORM_PACK32: /* If the last shader pass uses a RGB10A2 back buffer
/* If the last shader pass uses a RGB10A2 back buffer * and HDR has been enabled, assume we want to skip
* and HDR has been enabled, assume we want to skip * the inverse tonemapper and HDR10 conversion.
* the inverse tonemapper and HDR10 conversion. * If we just inherited HDR10 format based on backbuffer,
* If we just inherited HDR10 format based on backbuffer, * we would have used RGBA8, and thus we should do inverse tonemap as expected. */
* we would have used RGBA8, and thus we should do inverse tonemap as expected. */ vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10);
vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10); vulkan_set_hdr10(vk, !emits_hdr10);
vulkan_set_hdr10(vk, !emits_hdr10); vk->flags |= VK_FLAG_SHOULD_RESIZE;
vk->flags |= VK_FLAG_SHOULD_RESIZE; }
break; else if (rt_format == VK_FORMAT_R16G16B16A16_SFLOAT)
case VK_FORMAT_R16G16B16A16_SFLOAT: {
/* If the last shader pass uses a RGBA16 backbuffer /* If the last shader pass uses a RGBA16 backbuffer
* and HDR has been enabled, assume we want to * and HDR has been enabled, assume we want to
* skip the inverse tonemapper */ * skip the inverse tonemapper */
vulkan_set_hdr_inverse_tonemap(vk, false); vulkan_set_hdr_inverse_tonemap(vk, false);
vulkan_set_hdr10(vk, true); vulkan_set_hdr10(vk, true);
vk->flags |= VK_FLAG_SHOULD_RESIZE; vk->flags |= VK_FLAG_SHOULD_RESIZE;
break; }
case VK_FORMAT_UNDEFINED: else
default: {
vulkan_set_hdr_inverse_tonemap(vk, true); vulkan_set_hdr_inverse_tonemap(vk, true);
vulkan_set_hdr10(vk, true); vulkan_set_hdr10(vk, true);
break;
} }
} }
#endif /* VULKAN_HDR_SWAPCHAIN */ #endif /* VULKAN_HDR_SWAPCHAIN */
@ -2848,31 +2847,30 @@ static bool vulkan_init_filter_chain_preset(vk_t *vk, const char *shader_path)
: VK_FORMAT_UNDEFINED; : VK_FORMAT_UNDEFINED;
bool emits_hdr10 = shader_preset && shader_preset->passes && vulkan_filter_chain_emits_hdr10(vk->filter_chain); bool emits_hdr10 = shader_preset && shader_preset->passes && vulkan_filter_chain_emits_hdr10(vk->filter_chain);
switch (rt_format) if (vulkan_is_hdr10_format(rt_format))
{ {
case VK_FORMAT_A2B10G10R10_UNORM_PACK32: /* If the last shader pass uses a RGB10A2 back buffer
/* If the last shader pass uses a RGB10A2 backbuffer * and HDR has been enabled, assume we want to skip
* and HDR has been enabled, assume we want to * the inverse tonemapper and HDR10 conversion.
* skip the inverse tonemapper and HDR10 conversion * If we just inherited HDR10 format based on backbuffer,
* If we just inherited HDR10 format based on backbuffer, * we would have used RGBA8, and thus we should do inverse tonemap as expected. */
* we would have used RGBA8, and thus we should do inverse tonemap as expected. */ vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10);
vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10); vulkan_set_hdr10(vk, !emits_hdr10);
vulkan_set_hdr10(vk, !emits_hdr10); vk->flags |= VK_FLAG_SHOULD_RESIZE;
vk->flags |= VK_FLAG_SHOULD_RESIZE; }
break; else if (rt_format == VK_FORMAT_R16G16B16A16_SFLOAT)
case VK_FORMAT_R16G16B16A16_SFLOAT: {
/* If the last shader pass uses a RGBA16 backbuffer /* If the last shader pass uses a RGBA16 backbuffer
* and HDR has been enabled, assume we want to * and HDR has been enabled, assume we want to
* skip the inverse tonemapper */ * skip the inverse tonemapper */
vulkan_set_hdr_inverse_tonemap(vk, false); vulkan_set_hdr_inverse_tonemap(vk, false);
vulkan_set_hdr10(vk, true); vulkan_set_hdr10(vk, true);
vk->flags |= VK_FLAG_SHOULD_RESIZE; vk->flags |= VK_FLAG_SHOULD_RESIZE;
break; }
case VK_FORMAT_UNDEFINED: else
default: {
vulkan_set_hdr_inverse_tonemap(vk, true); vulkan_set_hdr_inverse_tonemap(vk, true);
vulkan_set_hdr10(vk, true); vulkan_set_hdr10(vk, true);
break;
} }
} }
#endif /* VULKAN_HDR_SWAPCHAIN */ #endif /* VULKAN_HDR_SWAPCHAIN */

View File

@ -3262,7 +3262,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
VkFormat pass_format = glslang_format_to_vk(output.meta.rt_format); VkFormat pass_format = glslang_format_to_vk(output.meta.rt_format);
/* If final pass explicitly emits RGB10, consider it HDR color space. */ /* If final pass explicitly emits RGB10, consider it HDR color space. */
if (explicit_format && pass_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) if (explicit_format && vulkan_is_hdr10_format(pass_format))
chain->set_hdr10(); chain->set_hdr10();
if (explicit_format && pass_format != pass_info.rt_format) if (explicit_format && pass_format != pass_info.rt_format)