From 94ae9ab08315380bb1ea18e2d7325cbe4a9c8f3d Mon Sep 17 00:00:00 2001 From: Iliyan Dinev Date: Thu, 11 Jul 2024 17:05:58 +0100 Subject: [PATCH] pvr: fix pvr_CmdResetQueryPool barriers It was not waiting for previous frag/geom to complete, overwriting their results midway. Subsequent frag/geom were not waiting for the reset-program to complete, so it was resetting the transform-feedback write-index and primitives_written counts midway or after the frag/geom complete. This resulted in incorrect XFB data and query-results. Signed-off-by: Iliyan Dinev Acked-by: Erik Faye-Lund Part-of: --- src/imagination/vulkan/pvr_query.c | 36 +++++++++++++++++++++++++++++- src/imagination/vulkan/pvr_queue.c | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/imagination/vulkan/pvr_query.c b/src/imagination/vulkan/pvr_query.c index 90881808974..7ea7798ee27 100644 --- a/src/imagination/vulkan/pvr_query.c +++ b/src/imagination/vulkan/pvr_query.c @@ -267,6 +267,7 @@ void pvr_CmdResetQueryPool(VkCommandBuffer commandBuffer, { PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer); struct pvr_query_info query_info; + VkResult result; PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer); @@ -276,7 +277,40 @@ void pvr_CmdResetQueryPool(VkCommandBuffer commandBuffer, query_info.reset_query_pool.first_query = firstQuery; query_info.reset_query_pool.query_count = queryCount; - pvr_add_query_program(cmd_buffer, &query_info); + /* make the query-reset program wait for previous geom/frag, + * to not overwrite them + */ + result = pvr_cmd_buffer_start_sub_cmd(cmd_buffer, PVR_SUB_CMD_TYPE_EVENT); + if (result != VK_SUCCESS) + return; + + cmd_buffer->state.current_sub_cmd->event = (struct pvr_sub_cmd_event){ + .type = PVR_EVENT_TYPE_BARRIER, + .barrier = { + .wait_for_stage_mask = PVR_PIPELINE_STAGE_ALL_GRAPHICS_BITS, + .wait_at_stage_mask = PVR_PIPELINE_STAGE_OCCLUSION_QUERY_BIT, + }, + }; + + /* add the query-program itself */ + result = pvr_add_query_program(cmd_buffer, &query_info); + if (result != VK_SUCCESS) + return; + + /* make future geom/frag wait for the query-reset program to + * reset the counters to 0 + */ + result = pvr_cmd_buffer_start_sub_cmd(cmd_buffer, PVR_SUB_CMD_TYPE_EVENT); + if (result != VK_SUCCESS) + return; + + cmd_buffer->state.current_sub_cmd->event = (struct pvr_sub_cmd_event){ + .type = PVR_EVENT_TYPE_BARRIER, + .barrier = { + .wait_for_stage_mask = PVR_PIPELINE_STAGE_OCCLUSION_QUERY_BIT, + .wait_at_stage_mask = PVR_PIPELINE_STAGE_ALL_GRAPHICS_BITS, + }, + }; } void pvr_ResetQueryPool(VkDevice _device, diff --git a/src/imagination/vulkan/pvr_queue.c b/src/imagination/vulkan/pvr_queue.c index 84408ccde2c..52275b9532c 100644 --- a/src/imagination/vulkan/pvr_queue.c +++ b/src/imagination/vulkan/pvr_queue.c @@ -605,7 +605,7 @@ pvr_process_event_cmd_wait(struct pvr_device *device, uint32_t wait_count = 0; for (uint32_t i = 0; i < sub_cmd->count; i++) { - if (sub_cmd->wait_at_stage_masks[i] & stage) { + if (sub_cmd->wait_at_stage_masks[i] & BITFIELD_BIT(stage)) { waits[wait_count++] = (struct vk_sync_wait){ .sync = sub_cmd->events[i]->sync, .stage_mask = ~(VkPipelineStageFlags2)0,