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);
}
#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,
unsigned width, unsigned height,
unsigned swap_interval)
@ -2067,11 +2078,12 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
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))
{
format = formats[i];
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_memory(VkDevice device, VkDeviceMemory memory);
#ifdef VULKAN_HDR_SWAPCHAIN
bool vulkan_is_hdr10_format(VkFormat format);
#endif /* VULKAN_HDR_SWAPCHAIN */
RETRO_END_DECLS
#endif

View file

@ -2776,31 +2776,30 @@ static bool vulkan_init_default_filter_chain(vk_t *vk)
: VK_FORMAT_UNDEFINED;
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
* and HDR has been enabled, assume we want to skip
* the inverse tonemapper and HDR10 conversion.
* If we just inherited HDR10 format based on backbuffer,
* we would have used RGBA8, and thus we should do inverse tonemap as expected. */
vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10);
vulkan_set_hdr10(vk, !emits_hdr10);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
break;
case VK_FORMAT_R16G16B16A16_SFLOAT:
/* If the last shader pass uses a RGBA16 backbuffer
* and HDR has been enabled, assume we want to
* skip the inverse tonemapper */
vulkan_set_hdr_inverse_tonemap(vk, false);
vulkan_set_hdr10(vk, true);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
break;
case VK_FORMAT_UNDEFINED:
default:
vulkan_set_hdr_inverse_tonemap(vk, true);
vulkan_set_hdr10(vk, true);
break;
/* If the last shader pass uses a RGB10A2 back buffer
* and HDR has been enabled, assume we want to skip
* the inverse tonemapper and HDR10 conversion.
* If we just inherited HDR10 format based on backbuffer,
* we would have used RGBA8, and thus we should do inverse tonemap as expected. */
vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10);
vulkan_set_hdr10(vk, !emits_hdr10);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
}
else if (rt_format == VK_FORMAT_R16G16B16A16_SFLOAT)
{
/* If the last shader pass uses a RGBA16 backbuffer
* and HDR has been enabled, assume we want to
* skip the inverse tonemapper */
vulkan_set_hdr_inverse_tonemap(vk, false);
vulkan_set_hdr10(vk, true);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
}
else
{
vulkan_set_hdr_inverse_tonemap(vk, true);
vulkan_set_hdr10(vk, true);
}
}
#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;
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 backbuffer
* and HDR has been enabled, assume we want to
* skip the inverse tonemapper and HDR10 conversion
* If we just inherited HDR10 format based on backbuffer,
* we would have used RGBA8, and thus we should do inverse tonemap as expected. */
vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10);
vulkan_set_hdr10(vk, !emits_hdr10);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
break;
case VK_FORMAT_R16G16B16A16_SFLOAT:
/* If the last shader pass uses a RGBA16 backbuffer
* and HDR has been enabled, assume we want to
* skip the inverse tonemapper */
vulkan_set_hdr_inverse_tonemap(vk, false);
vulkan_set_hdr10(vk, true);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
break;
case VK_FORMAT_UNDEFINED:
default:
vulkan_set_hdr_inverse_tonemap(vk, true);
vulkan_set_hdr10(vk, true);
break;
/* If the last shader pass uses a RGB10A2 back buffer
* and HDR has been enabled, assume we want to skip
* the inverse tonemapper and HDR10 conversion.
* If we just inherited HDR10 format based on backbuffer,
* we would have used RGBA8, and thus we should do inverse tonemap as expected. */
vulkan_set_hdr_inverse_tonemap(vk, !emits_hdr10);
vulkan_set_hdr10(vk, !emits_hdr10);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
}
else if (rt_format == VK_FORMAT_R16G16B16A16_SFLOAT)
{
/* If the last shader pass uses a RGBA16 backbuffer
* and HDR has been enabled, assume we want to
* skip the inverse tonemapper */
vulkan_set_hdr_inverse_tonemap(vk, false);
vulkan_set_hdr10(vk, true);
vk->flags |= VK_FLAG_SHOULD_RESIZE;
}
else
{
vulkan_set_hdr_inverse_tonemap(vk, true);
vulkan_set_hdr10(vk, true);
}
}
#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);
/* 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();
if (explicit_format && pass_format != pass_info.rt_format)