Skip to content

Commit 4b4d82e

Browse files
Vulkan: Fix HDR render pass mismatch and pipeline barrier
Fix render pass / framebuffer format mismatch when rendering through the SDR offscreen buffer in HDR mode. The filter chain's final pass and the frame render pass were using vk->render_pass (A2B10G10R10) while the offscreen buffer framebuffer was created with vk->sdr_render_pass (B8G8R8A8), causing a Vulkan validation error. Select the correct render pass at frame time based on use_offscreen_buffer, and rebuild the filter chain's final pass pipeline to use the SDR render pass both at shader preset load and at swapchain recreation. Also fix an incorrect srcStageMask in the image layout transition after the HDR pipeline: SHADER_READ_BIT requires FRAGMENT_SHADER_BIT, not COLOR_ATTACHMENT_OUTPUT_BIT.
1 parent a3545af commit 4b4d82e

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

gfx/drivers/vulkan.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3307,6 +3307,20 @@ static bool vulkan_init_filter_chain_preset(vk_t *vk, const char *shader_path)
33073307
vulkan_set_hdr_inverse_tonemap(vk, vk->filter_chain, !emits_hdr10);
33083308
vulkan_set_hdr10(vk, vk->filter_chain, !emits_hdr10);
33093309
vk->flags |= VK_FLAG_SHOULD_RESIZE;
3310+
3311+
if (!emits_hdr10)
3312+
{
3313+
/* Rendering goes through the SDR offscreen buffer;
3314+
* rebuild the filter chain's final pass pipeline
3315+
* to use the SDR render pass. */
3316+
struct vulkan_filter_chain_swapchain_info sdr_swapchain;
3317+
sdr_swapchain.vp = vk->vk_vp;
3318+
sdr_swapchain.format = vk->context->swapchain_format;
3319+
sdr_swapchain.render_pass = vk->sdr_render_pass;
3320+
sdr_swapchain.num_indices = vk->context->num_swapchain_images;
3321+
vulkan_filter_chain_update_swapchain_info(
3322+
vk->filter_chain, &sdr_swapchain);
3323+
}
33103324
}
33113325
else if (rt_format == VK_FORMAT_R16G16B16A16_SFLOAT)
33123326
{
@@ -4032,6 +4046,26 @@ static void vulkan_check_swapchain(vk_t *vk)
40324046
filter_info.format = vk->context->swapchain_format;
40334047
filter_info.render_pass = vk->render_pass;
40344048
filter_info.num_indices = vk->context->num_swapchain_images;
4049+
4050+
#ifdef VULKAN_HDR_SWAPCHAIN
4051+
/* When rendering through the SDR offscreen buffer, the filter chain's
4052+
* final pass must use the SDR render pass to match the framebuffer format. */
4053+
if (vk->context->flags & VK_CTX_FLAG_HDR_ENABLE)
4054+
{
4055+
vulkan_filter_chain_t *chain = vk->filter_chain
4056+
? vk->filter_chain : vk->filter_chain_default;
4057+
struct video_shader *preset = vulkan_filter_chain_get_preset(chain);
4058+
if (preset && preset->passes)
4059+
{
4060+
VkFormat rt_format = vulkan_filter_chain_get_pass_rt_format(
4061+
chain, preset->passes - 1);
4062+
if ( vulkan_is_hdr10_format(rt_format)
4063+
&& !vulkan_filter_chain_emits_hdr10(chain))
4064+
filter_info.render_pass = vk->sdr_render_pass;
4065+
}
4066+
}
4067+
#endif
4068+
40354069
if (
40364070
!vulkan_filter_chain_update_swapchain_info(
40374071
(vk->filter_chain) ? vk->filter_chain : vk->filter_chain_default,
@@ -5115,7 +5149,12 @@ static bool vulkan_frame(void *data, const void *frame,
51155149
{
51165150
rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
51175151
rp_info.pNext = NULL;
5152+
#ifdef VULKAN_HDR_SWAPCHAIN
5153+
rp_info.renderPass = use_offscreen_buffer
5154+
? vk->sdr_render_pass : vk->render_pass;
5155+
#else
51185156
rp_info.renderPass = vk->render_pass;
5157+
#endif
51195158
rp_info.framebuffer = backbuffer->framebuffer;
51205159
rp_info.renderArea.offset.x = 0;
51215160
rp_info.renderArea.offset.y = 0;
@@ -5163,7 +5202,7 @@ static bool vulkan_frame(void *data, const void *frame,
51635202
VULKAN_IMAGE_LAYOUT_TRANSITION(vk->cmd, vk->offscreen_buffer.image,
51645203
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
51655204
VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
5166-
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5205+
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
51675206
VK_PIPELINE_STAGE_TRANSFER_BIT);
51685207

51695208
end_main_pass = false;

0 commit comments

Comments
 (0)