diff options
author | Jason Ekstrand <[email protected]> | 2017-11-03 14:13:08 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2018-02-28 13:31:42 -0800 |
commit | 67da59e320bd5f797f6bdc3ab111f33c64e16811 (patch) | |
tree | 91e67f348cf6122b2d1b706b46b1fbee9366d592 | |
parent | debaa822ef12bc9006dcf95ab76ac8e3432bd9a7 (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.c | 20 |
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 |