summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2018-08-21 20:43:57 -0500
committerJason Ekstrand <[email protected]>2018-09-07 15:19:02 -0500
commit465e5a868cd58ca7c4ff7476e98231ffd4f3d2bf (patch)
tree23c07757a02c1a6c1fc285e3121da7c5991aa46b
parentb08b4b2b25b201df2d667cf70d7f99475e5c7aec (diff)
anv: Clamp scissors to the framebuffer boundary
The Vulkan 1.1.81 spec says: "It is legal for offset.x + extent.width or offset.y + extent.height to exceed the dimensions of the framebuffer - the scissor test still applies as defined above. Rasterization does not produce fragments outside of the framebuffer, so such fragments never have the scissor test performed on them." Elsewhere, the Vulkan 1.1.81 spec says: "The application must ensure (using scissor if necessary) that all rendering is contained within the render area, otherwise the pixels outside of the render area become undefined and shader side effects may occur for fragments outside the render area. The render area must be contained within the framebuffer dimensions." Unfortunately, there's some room for interpretation here as to what the consequences are of having the render area set to exactly the framebuffer dimensions and having a scissor that is larger than the framebuffer. Given that GL and other APIs provide automatic clipping to the framebuffer, it makes sense that applications would assume that Vulkan does this as well. It costs us very little to play it safe and just clamp client-provided scissors to the framebuffer dimensions. Fortunately, the user is required to provide us with at least one scissor so we don't need to handle the case where they don't. Fixes: fb2a5ceb3264 "anv: Emit DRAWING_RECTANGLE once at driver..." Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/intel/vulkan/gen7_cmd_buffer.c5
-rw-r--r--src/intel/vulkan/genX_cmd_buffer.c3
2 files changed, 5 insertions, 3 deletions
diff --git a/src/intel/vulkan/gen7_cmd_buffer.c b/src/intel/vulkan/gen7_cmd_buffer.c
index 3acfbb710c0..cf1f8ee2829 100644
--- a/src/intel/vulkan/gen7_cmd_buffer.c
+++ b/src/intel/vulkan/gen7_cmd_buffer.c
@@ -48,6 +48,7 @@ clamp_int64(int64_t x, int64_t min, int64_t max)
void
gen7_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;
struct anv_state scissor_state =
@@ -73,8 +74,8 @@ gen7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
/* Do this math using int64_t so overflow gets clamped correctly. */
.ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
.ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
- .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
- .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
+ .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, fb->height - 1),
+ .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, fb->width - 1)
};
if (s->extent.width <= 0 || s->extent.height <= 0) {
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 817e8510e3b..80bebf5a12c 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -2637,7 +2637,8 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
pipeline->depth_clamp_enable);
}
- if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SCISSOR)
+ if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_SCISSOR |
+ ANV_CMD_DIRTY_RENDER_TARGETS))
gen7_cmd_buffer_emit_scissor(cmd_buffer);
genX(cmd_buffer_flush_dynamic_state)(cmd_buffer);