summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-11-03 14:13:08 -0700
committerJason Ekstrand <[email protected]>2018-02-28 13:31:42 -0800
commit67da59e320bd5f797f6bdc3ab111f33c64e16811 (patch)
tree91e67f348cf6122b2d1b706b46b1fbee9366d592
parentdebaa822ef12bc9006dcf95ab76ac8e3432bd9a7 (diff)
i965: Be more clever about setting up our viewport clip
Before, we were trusting in the hardware to take the intersection of the viewport clip with the drawing rectangle. Unfortunately, 3DSTATE_DRAWING_RECTANGLE is fairly expensive because it implicitly does a full pipeline stall. If we're a bit more careful with our viewport clipping, we can just re-emit it once at context creation time. Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/genX_state_upload.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c
index 8668abd591f..b38b61a874c 100644
--- a/src/mesa/drivers/dri/i965/genX_state_upload.c
+++ b/src/mesa/drivers/dri/i965/genX_state_upload.c
@@ -2469,24 +2469,28 @@ genX(upload_sf_clip_viewport)(struct brw_context *brw)
#elif GEN_GEN >= 8
/* _NEW_VIEWPORT | _NEW_BUFFERS: Screen Space Viewport
* The hardware will take the intersection of the drawing rectangle,
- * scissor rectangle, and the viewport extents. We don't need to be
- * smart, and can therefore just program the viewport extents.
+ * scissor rectangle, and the viewport extents. However, emitting
+ * 3DSTATE_DRAWING_RECTANGLE is expensive since it requires a full
+ * pipeline stall so we're better off just being a little more clever
+ * with our viewport so we can emit it once at context creation time.
*/
+ const float viewport_Xmin = MAX2(ctx->ViewportArray[i].X, 0);
+ const float viewport_Ymin = MAX2(ctx->ViewportArray[i].Y, 0);
const float viewport_Xmax =
- ctx->ViewportArray[i].X + ctx->ViewportArray[i].Width;
+ MIN2(ctx->ViewportArray[i].X + ctx->ViewportArray[i].Width, fb_width);
const float viewport_Ymax =
- ctx->ViewportArray[i].Y + ctx->ViewportArray[i].Height;
+ MIN2(ctx->ViewportArray[i].Y + ctx->ViewportArray[i].Height, fb_height);
if (render_to_fbo) {
- sfv.XMinViewPort = ctx->ViewportArray[i].X;
+ sfv.XMinViewPort = viewport_Xmin;
sfv.XMaxViewPort = viewport_Xmax - 1;
- sfv.YMinViewPort = ctx->ViewportArray[i].Y;
+ sfv.YMinViewPort = viewport_Ymin;
sfv.YMaxViewPort = viewport_Ymax - 1;
} else {
- sfv.XMinViewPort = ctx->ViewportArray[i].X;
+ sfv.XMinViewPort = viewport_Xmin;
sfv.XMaxViewPort = viewport_Xmax - 1;
sfv.YMinViewPort = fb_height - viewport_Ymax;
- sfv.YMaxViewPort = fb_height - ctx->ViewportArray[i].Y - 1;
+ sfv.YMaxViewPort = fb_height - viewport_Ymin - 1;
}
#endif