From 732cfa525f431b6f5b47e2623645cf14716b4bdf Mon Sep 17 00:00:00 2001 From: Vadym Shovkoplias Date: Thu, 28 Oct 2021 16:03:11 +0300 Subject: [PATCH] anv: Include viewport size in scissor rectangle Prevent drawing outside the viewport when viewport size is smaller than framebuffer size. v2: (Jason Ekstrand) - re-emit scissor on viewport change - do the same calculations for other platforms Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5515 Signed-off-by: Vadym Shovkoplias Reviewed-by: Jason Ekstrand Part-of: --- src/intel/vulkan/genX_cmd_buffer.c | 3 ++- src/intel/vulkan/gfx7_cmd_buffer.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 6b4ff92..8f51f08 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3758,7 +3758,8 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) } if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_SCISSOR | - ANV_CMD_DIRTY_RENDER_TARGETS)) + ANV_CMD_DIRTY_RENDER_TARGETS | + ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)) gfx7_cmd_buffer_emit_scissor(cmd_buffer); genX(cmd_buffer_flush_dynamic_state)(cmd_buffer); diff --git a/src/intel/vulkan/gfx7_cmd_buffer.c b/src/intel/vulkan/gfx7_cmd_buffer.c index b092bd8..5ddc902 100644 --- a/src/intel/vulkan/gfx7_cmd_buffer.c +++ b/src/intel/vulkan/gfx7_cmd_buffer.c @@ -51,6 +51,8 @@ gfx7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer) struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; uint32_t count = cmd_buffer->state.gfx.dynamic.scissor.count; const VkRect2D *scissors = cmd_buffer->state.gfx.dynamic.scissor.scissors; + const VkViewport *viewports = + cmd_buffer->state.gfx.dynamic.viewport.viewports; /* Wa_1409725701: * "The viewport-specific state used by the SF unit (SCISSOR_RECT) is @@ -64,6 +66,7 @@ gfx7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer) for (uint32_t i = 0; i < count; i++) { const VkRect2D *s = &scissors[i]; + const VkViewport *vp = &viewports[i]; /* Since xmax and ymax are inclusive, we have to have xmax < xmin or * ymax < ymin for empty clips. In case clip x, y, width height are all @@ -79,10 +82,12 @@ gfx7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer) const int max = 0xffff; - uint32_t y_min = s->offset.y; - uint32_t x_min = s->offset.x; - uint32_t y_max = s->offset.y + s->extent.height - 1; - uint32_t x_max = s->offset.x + s->extent.width - 1; + uint32_t y_min = MAX2(s->offset.y, MIN2(vp->y, vp->y + vp->height)); + uint32_t x_min = MAX2(s->offset.x, vp->x); + uint32_t y_max = MIN2(s->offset.y + s->extent.height - 1, + MAX2(vp->y, vp->y + vp->height) - 1); + uint32_t x_max = MIN2(s->offset.x + s->extent.width - 1, + vp->x + vp->width - 1); /* Do this math using int64_t so overflow gets clamped correctly. */ if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) { -- 2.7.4