From 22d632644919ae3d953f1576beed15ff7cd5bc6b Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 1 Apr 2020 10:18:52 +0200 Subject: [PATCH] v3dv: check the render area against the clip window And flag dirty scissor state if the render area is constraining the current clip window, so that we emit a new clip window with the next draw call. Also, remove the early emission of a clip window for the render area if we didn't have any scissor state. TLB clears ignore the clip window, so this was doing nothing for us. Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 30 ++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 9af49c29f86..95b56907b98 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -883,6 +883,22 @@ v3dv_CmdBeginRenderPass(VkCommandBuffer commandBuffer, */ state->render_area = pRenderPassBegin->renderArea; + /* If our render area is smaller than the current clip window we will have + * to emit a new clip window. + */ + uint32_t min_render_x = state->render_area.offset.x; + uint32_t min_render_y = state->render_area.offset.x; + uint32_t max_render_x = min_render_x + state->render_area.extent.width - 1; + uint32_t max_render_y = min_render_y + state->render_area.extent.height - 1; + uint32_t min_clip_x = state->clip_window.offset.x; + uint32_t min_clip_y = state->clip_window.offset.y; + uint32_t max_clip_x = min_clip_x + state->clip_window.extent.width - 1; + uint32_t max_clip_y = min_clip_y + state->clip_window.extent.height - 1; + if (min_render_x > min_clip_x || min_render_y > min_clip_y || + max_render_x < max_clip_x || max_render_y < max_clip_y) { + state->dirty |= V3DV_CMD_DIRTY_SCISSOR; + } + /* Setup for first subpass */ v3dv_cmd_buffer_subpass_start(cmd_buffer, 0); } @@ -1549,20 +1565,6 @@ v3dv_cmd_buffer_subpass_start(struct v3dv_cmd_buffer *cmd_buffer, internal_bpp); } - /* If we don't have a scissor or viewport defined let's just use the render - * area as clip_window, as that would be required for a clear in any - * case. If we have that, it would be emitted as part of the pipeline - * dynamic state flush - * - * FIXME: this is mostly just needed for clear. radv has dedicated paths - * for them, so we could get that idea. In any case, need to revisit if - * this is the place to emit the clip window. - */ - if (cmd_buffer->state.dynamic.scissor.count == 0 && - cmd_buffer->state.dynamic.viewport.count == 0) { - emit_clip_window(job, &state->render_area); - } - return job; }