From 67da59e320bd5f797f6bdc3ab111f33c64e16811 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 3 Nov 2017 14:13:08 -0700 Subject: [PATCH] i965: Be more clever about setting up our viewport clip MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/genX_state_upload.c | 20 +++++++++++-------- 1 file 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 -- 2.30.2