From b474d8e858bbceb43dff2a9e601efbe02e2d63ce Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Wed, 25 Jun 2025 22:06:00 +0200 Subject: [PATCH] lavapipe: Suspend conditional rendering around ray tracing dispatches cc: mesa-stable Reviewed-by: Mike Blumenkrantz Part-of: (cherry picked from commit 131b917246a6ced2f4172d0f9edb1d199ae5dfee) --- .pick_status.json | 2 +- src/gallium/frontends/lavapipe/lvp_execute.c | 88 +++++++++++++------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 2b1c4b5a9c5..edeb09a4c94 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2414,7 +2414,7 @@ "description": "lavapipe: Suspend conditional rendering around ray tracing dispatches", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 23e3b86c785..b298732a38a 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -80,6 +80,13 @@ struct lvp_render_attachment { bool read_only; }; +struct lvp_conditional_rendering_state { + struct pipe_resource *buffer; + uint32_t offset; + bool condition; + bool enabled; +}; + struct rendering_state { struct pipe_context *pctx; struct lvp_device *device; @@ -171,7 +178,6 @@ struct rendering_state { VkRect2D render_area; bool suspending; - bool render_cond; uint32_t color_att_count; struct lvp_render_attachment color_att[PIPE_MAX_COLOR_BUFS]; struct lvp_render_attachment depth_att; @@ -205,6 +211,8 @@ struct rendering_state { struct lvp_pipeline *exec_graph; + struct lvp_conditional_rendering_state conditional_rendering; + struct { struct lvp_shader *compute_shader; uint8_t push_constants[128 * 4]; @@ -1392,7 +1400,7 @@ static void render_clear_fast(struct rendering_state *state) if (state->framebuffer.viewmask) goto slow_clear; - if (state->render_cond) + if (state->conditional_rendering.enabled) goto slow_clear; uint32_t buffers = 0; @@ -3401,21 +3409,35 @@ static void handle_draw_indirect_byte_count(struct vk_cmd_queue_entry *cmd, state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1); } +static void +lvp_emit_conditional_rendering(struct rendering_state *state) +{ + if (state->conditional_rendering.enabled) { + state->pctx->render_condition_mem( + state->pctx, + state->conditional_rendering.buffer, + state->conditional_rendering.offset, + state->conditional_rendering.condition); + } else { + state->pctx->render_condition_mem(state->pctx, NULL, 0, false); + } +} + static void handle_begin_conditional_rendering(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) { struct VkConditionalRenderingBeginInfoEXT *bcr = cmd->u.begin_conditional_rendering_ext.conditional_rendering_begin; - state->render_cond = true; - state->pctx->render_condition_mem(state->pctx, - lvp_buffer_from_handle(bcr->buffer)->bo, - bcr->offset, - bcr->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT); + state->conditional_rendering.buffer = lvp_buffer_from_handle(bcr->buffer)->bo; + state->conditional_rendering.offset = bcr->offset; + state->conditional_rendering.condition = bcr->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT; + state->conditional_rendering.enabled = true; + lvp_emit_conditional_rendering(state); } static void handle_end_conditional_rendering(struct rendering_state *state) { - state->render_cond = false; - state->pctx->render_condition_mem(state->pctx, NULL, 0, false); + state->conditional_rendering.enabled = false; + lvp_emit_conditional_rendering(state); } static void handle_set_vertex_input(struct vk_cmd_queue_entry *cmd, @@ -4532,8 +4554,10 @@ handle_write_acceleration_structures_properties(struct vk_cmd_queue_entry *cmd, } } -static void emit_ray_tracing_state(struct rendering_state *state) +static void +lvp_trace_rays(struct rendering_state *state, VkTraceRaysIndirectCommand2KHR *command) { + /* Emit ray tracing state. */ bool pcbuf_dirty = state->pcbuf_dirty[MESA_SHADER_RAYGEN]; if (pcbuf_dirty) update_pcbuf(state, MESA_SHADER_COMPUTE, MESA_SHADER_RAYGEN); @@ -4550,6 +4574,26 @@ static void emit_ray_tracing_state(struct rendering_state *state) state->pcbuf_dirty[MESA_SHADER_COMPUTE] = true; state->constbuf_dirty[MESA_SHADER_COMPUTE] = true; state->compute_shader_dirty = true; + + /* Dispatch. The spec states that conditional rendering only affects compute dispatches + * so ray tracing dispatches have to suspend it. + */ + state->trace_rays_info.grid[0] = DIV_ROUND_UP(command->width, state->trace_rays_info.block[0]); + state->trace_rays_info.grid[1] = DIV_ROUND_UP(command->height, state->trace_rays_info.block[1]); + state->trace_rays_info.grid[2] = DIV_ROUND_UP(command->depth, state->trace_rays_info.block[2]); + + bool conditional_rendering_enabled = state->conditional_rendering.enabled; + if (conditional_rendering_enabled) { + state->conditional_rendering.enabled = false; + lvp_emit_conditional_rendering(state); + } + + state->pctx->launch_grid(state->pctx, &state->trace_rays_info); + + if (conditional_rendering_enabled) { + state->conditional_rendering.enabled = true; + lvp_emit_conditional_rendering(state); + } } static void @@ -4557,8 +4601,6 @@ handle_trace_rays(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) { struct vk_cmd_trace_rays_khr *trace = &cmd->u.trace_rays_khr; - emit_ray_tracing_state(state); - VkTraceRaysIndirectCommand2KHR *command = lvp_push_internal_buffer( state, MESA_SHADER_COMPUTE, sizeof(VkTraceRaysIndirectCommand2KHR)); @@ -4579,11 +4621,7 @@ handle_trace_rays(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) .depth = trace->depth, }; - state->trace_rays_info.grid[0] = DIV_ROUND_UP(trace->width, state->trace_rays_info.block[0]); - state->trace_rays_info.grid[1] = DIV_ROUND_UP(trace->height, state->trace_rays_info.block[1]); - state->trace_rays_info.grid[2] = DIV_ROUND_UP(trace->depth, state->trace_rays_info.block[2]); - - state->pctx->launch_grid(state->pctx, &state->trace_rays_info); + lvp_trace_rays(state, command); } static void @@ -4591,8 +4629,6 @@ handle_trace_rays_indirect(struct vk_cmd_queue_entry *cmd, struct rendering_stat { struct vk_cmd_trace_rays_indirect_khr *trace = &cmd->u.trace_rays_indirect_khr; - emit_ray_tracing_state(state); - size_t indirect_offset; VkBuffer _indirect = get_buffer(state, (void *)(uintptr_t)trace->indirect_device_address, &indirect_offset); VK_FROM_HANDLE(lvp_buffer, indirect, _indirect); @@ -4622,13 +4658,9 @@ handle_trace_rays_indirect(struct vk_cmd_queue_entry *cmd, struct rendering_stat .depth = src->depth, }; - state->trace_rays_info.grid[0] = DIV_ROUND_UP(src->width, state->trace_rays_info.block[0]); - state->trace_rays_info.grid[1] = DIV_ROUND_UP(src->height, state->trace_rays_info.block[1]); - state->trace_rays_info.grid[2] = DIV_ROUND_UP(src->depth, state->trace_rays_info.block[2]); - state->pctx->buffer_unmap(state->pctx, transfer); - state->pctx->launch_grid(state->pctx, &state->trace_rays_info); + lvp_trace_rays(state, command); } static void @@ -4636,8 +4668,6 @@ handle_trace_rays_indirect2(struct vk_cmd_queue_entry *cmd, struct rendering_sta { struct vk_cmd_trace_rays_indirect2_khr *trace = &cmd->u.trace_rays_indirect2_khr; - emit_ray_tracing_state(state); - size_t indirect_offset; VkBuffer _indirect = get_buffer(state, (void *)(uintptr_t)trace->indirect_device_address, &indirect_offset); VK_FROM_HANDLE(lvp_buffer, indirect, _indirect); @@ -4651,13 +4681,9 @@ handle_trace_rays_indirect2(struct vk_cmd_queue_entry *cmd, struct rendering_sta state, MESA_SHADER_COMPUTE, sizeof(VkTraceRaysIndirectCommand2KHR)); *command = *src; - state->trace_rays_info.grid[0] = DIV_ROUND_UP(src->width, state->trace_rays_info.block[0]); - state->trace_rays_info.grid[1] = DIV_ROUND_UP(src->height, state->trace_rays_info.block[1]); - state->trace_rays_info.grid[2] = DIV_ROUND_UP(src->depth, state->trace_rays_info.block[2]); - state->pctx->buffer_unmap(state->pctx, transfer); - state->pctx->launch_grid(state->pctx, &state->trace_rays_info); + lvp_trace_rays(state, command); } static void