vk: Fix crash when shuffling between cyclic and non-cyclic Z-buffer in one logical pass

This commit is contained in:
kd-11
2025-12-27 00:07:22 +03:00
committed by kd-11
parent e586986845
commit 316aa44d3e
+16 -2
View File
@@ -65,8 +65,12 @@ namespace vk
case VK_IMAGE_LAYOUT_GENERAL: case VK_IMAGE_LAYOUT_GENERAL:
case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT: case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
ensure(sampler_state->upload_context == rsx::texture_upload_context::framebuffer_storage); ensure(sampler_state->upload_context == rsx::texture_upload_context::framebuffer_storage);
if (!sampler_state->is_cyclic_reference) if (sampler_state->is_cyclic_reference) [[ unlikely ]]
{ {
// Nothing to do
break;
}
// This was used in a cyclic ref before, but is missing a barrier // This was used in a cyclic ref before, but is missing a barrier
// No need for a full stall, use a custom barrier instead // No need for a full stall, use a custom barrier instead
VkPipelineStageFlags src_stage; VkPipelineStageFlags src_stage;
@@ -91,14 +95,23 @@ namespace vk
{ raw->aspect(), 0, 1, 0, 1 }); { raw->aspect(), 0, 1, 0, 1 });
raw->current_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; raw->current_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
break; break;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
ensure(sampler_state->upload_context == rsx::texture_upload_context::framebuffer_storage); ensure(sampler_state->upload_context == rsx::texture_upload_context::framebuffer_storage);
if (!sampler_state->is_cyclic_reference) [[ likely ]]
{
// Standard pre-read barrier.
raw->change_layout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); raw->change_layout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
break; break;
} }
// Normally this shouldn't happen. But that is only guaranteed if the attachment state never changes outside of RTT rebind interrupts.
// If the shader changes between binds to "disable" the cyclic nature, we could end up here.
// Draw 1 (cyllic) -> texture_barrier -> Draw 2 (no textures) -> attachment_optimal -> Draw 3 (cylic again, no new data) -> incorrect layout.
vk::as_rtt(raw)->texture_barrier(cmd);
break;
}
} }
} }
@@ -1051,6 +1064,7 @@ void VKGSRender::end()
// We actually need to end the subpass as a minimum. Without this, early-Z optimiazations in following draws will clobber reads from previous draws and cause flickering. // We actually need to end the subpass as a minimum. Without this, early-Z optimiazations in following draws will clobber reads from previous draws and cause flickering.
// Since we're ending the subpass, might as well restore DCC/HiZ for extra performance // Since we're ending the subpass, might as well restore DCC/HiZ for extra performance
ds->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); ds->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
ds->reset_surface_counters();
} }
} }