tu: Occlusion query counting should happen after FS that kills

"EARLY_Z + discard" would yield incorrect occlusion query result,
since Vulkan expects occlusion query to happen after fragment shader.

See Vulkan spec "29. Fragment Operations".

Also see https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/5713

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34973>
This commit is contained in:
Danylo Piliaiev 2025-05-16 12:14:42 +02:00 committed by Marge Bot
parent b6cf0b68be
commit 8f5d433840
3 changed files with 15 additions and 0 deletions

View file

@ -3277,6 +3277,9 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
cmd_buffer->inherited_pipeline_statistics =
pBeginInfo->pInheritanceInfo->pipelineStatistics;
cmd_buffer->state.occlusion_query_may_be_running =
pBeginInfo->pInheritanceInfo->occlusionQueryEnable;
vk_foreach_struct_const(ext, pBeginInfo->pInheritanceInfo) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT: {
@ -6271,6 +6274,13 @@ tu6_build_depth_plane_z_mode(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
zmode = A6XX_EARLY_Z_LATE_Z;
}
/* "EARLY_Z + discard" would yield incorrect occlusion query result,
* since Vulkan expects occlusion query to happen after fragment shader.
*/
if (zmode == A6XX_EARLY_Z && fs_kill_fragments &&
cmd->state.occlusion_query_may_be_running)
zmode = A6XX_EARLY_Z_LATE_Z;
if (zmode == A6XX_EARLY_Z_LATE_Z &&
(cmd->state.stencil_written_on_depth_fail || fs->fs.per_samp ||
!vk_format_has_depth(depth_format) || !ds_test_enable)) {

View file

@ -544,6 +544,8 @@ struct tu_cmd_state
bool prim_generated_query_running_before_rp;
bool occlusion_query_may_be_running;
enum tu_suspend_resume_state suspend_resume;
bool suspending, resuming;

View file

@ -1040,6 +1040,7 @@ emit_begin_occlusion_query(struct tu_cmd_buffer *cmdbuf,
* sample counts in slot->result to compute the query result.
*/
struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
cmdbuf->state.occlusion_query_may_be_running = true;
uint64_t begin_iova = occlusion_query_iova(pool, query, begin);
@ -1507,6 +1508,8 @@ emit_end_occlusion_query(struct tu_cmd_buffer *cmdbuf,
tu_cs_emit_pkt7(epilogue_cs, CP_MEM_WRITE, 4);
tu_cs_emit_qw(epilogue_cs, available_iova);
tu_cs_emit_qw(epilogue_cs, 0x1);
cmdbuf->state.occlusion_query_may_be_running = false;
}
/* PRIMITIVE_CTRS is used for two distinct queries: