From d729936c5e6466d5ec336a446f06d9f65bd5cc43 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Thu, 30 Mar 2017 09:52:19 -0700 Subject: [PATCH] i965: Port gen6+ 3DSTATE_SCISSOR_STATE_POINTERS to use genxml. Emit 3DSTATE_SCISSOR_STATE_POINTERS using brw_batch_emit, and pack the scissor states using GENX(SCISSOR_RECT_pack), generated from genxml. v3: - Remove old code (Ken) - Style fixes (Ken) Signed-off-by: Rafael Antognolli Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/Makefile.sources | 1 - src/mesa/drivers/dri/i965/brw_state.h | 1 - .../drivers/dri/i965/gen6_scissor_state.c | 111 ------------------ src/mesa/drivers/dri/i965/genX_state_upload.c | 90 +++++++++++++- 4 files changed, 87 insertions(+), 116 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/gen6_scissor_state.c diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 012391348b1..a63d5762ef6 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -84,7 +84,6 @@ i965_FILES = \ gen6_multisample_state.c \ gen6_queryobj.c \ gen6_sampler_state.c \ - gen6_scissor_state.c \ gen6_sol.c \ gen6_urb.c \ gen6_viewport_state.c \ diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 322d76766a6..6adcf46344f 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -114,7 +114,6 @@ extern const struct brw_tracked_state gen6_gs_binding_table; extern const struct brw_tracked_state gen6_multisample_state; extern const struct brw_tracked_state gen6_renderbuffer_surfaces; extern const struct brw_tracked_state gen6_sampler_state; -extern const struct brw_tracked_state gen6_scissor_state; extern const struct brw_tracked_state gen6_sol_surface; extern const struct brw_tracked_state gen6_sf_vp; extern const struct brw_tracked_state gen6_urb; diff --git a/src/mesa/drivers/dri/i965/gen6_scissor_state.c b/src/mesa/drivers/dri/i965/gen6_scissor_state.c deleted file mode 100644 index 3407f6a93f7..00000000000 --- a/src/mesa/drivers/dri/i965/gen6_scissor_state.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "brw_context.h" -#include "brw_state.h" -#include "brw_defines.h" -#include "intel_batchbuffer.h" -#include "main/fbobject.h" -#include "main/framebuffer.h" - -static void -gen6_upload_scissor_state(struct brw_context *brw) -{ - struct gl_context *ctx = &brw->ctx; - const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); - struct gen6_scissor_rect *scissor; - uint32_t scissor_state_offset; - const unsigned int fb_width= _mesa_geometric_width(ctx->DrawBuffer); - const unsigned int fb_height = _mesa_geometric_height(ctx->DrawBuffer); - - /* BRW_NEW_VIEWPORT_COUNT */ - const unsigned viewport_count = brw->clip.viewport_count; - - scissor = brw_state_batch(brw, sizeof(*scissor) * viewport_count, 32, - &scissor_state_offset); - - /* _NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT */ - - /* The scissor only needs to handle the intersection of drawable and - * scissor rect. Clipping to the boundaries of static shared buffers - * for front/back/depth is covered by looping over cliprects in brw_draw.c. - * - * Note that the hardware's coordinates are inclusive, while Mesa's min is - * inclusive but max is exclusive. - */ - for (unsigned i = 0; i < viewport_count; i++) { - int bbox[4]; - - bbox[0] = MAX2(ctx->ViewportArray[i].X, 0); - bbox[1] = MIN2(bbox[0] + ctx->ViewportArray[i].Width, fb_width); - bbox[2] = MAX2(ctx->ViewportArray[i].Y, 0); - bbox[3] = MIN2(bbox[2] + ctx->ViewportArray[i].Height, fb_height); - _mesa_intersect_scissor_bounding_box(ctx, i, bbox); - - if (bbox[0] == bbox[1] || bbox[2] == bbox[3]) { - /* If the scissor was out of bounds and got clamped to 0 width/height - * at the bounds, the subtraction of 1 from maximums could produce a - * negative number and thus not clip anything. Instead, just provide - * a min > max scissor inside the bounds, which produces the expected - * no rendering. - */ - scissor[i].xmin = 1; - scissor[i].xmax = 0; - scissor[i].ymin = 1; - scissor[i].ymax = 0; - } else if (render_to_fbo) { - /* texmemory: Y=0=bottom */ - scissor[i].xmin = bbox[0]; - scissor[i].xmax = bbox[1] - 1; - scissor[i].ymin = bbox[2]; - scissor[i].ymax = bbox[3] - 1; - } - else { - /* memory: Y=0=top */ - scissor[i].xmin = bbox[0]; - scissor[i].xmax = bbox[1] - 1; - scissor[i].ymin = fb_height - bbox[3]; - scissor[i].ymax = fb_height - bbox[2] - 1; - } - } - BEGIN_BATCH(2); - OUT_BATCH(_3DSTATE_SCISSOR_STATE_POINTERS << 16 | (2 - 2)); - OUT_BATCH(scissor_state_offset); - ADVANCE_BATCH(); -} - -const struct brw_tracked_state gen6_scissor_state = { - .dirty = { - .mesa = _NEW_BUFFERS | - _NEW_SCISSOR | - _NEW_VIEWPORT, - .brw = BRW_NEW_BATCH | - BRW_NEW_BLORP | - BRW_NEW_VIEWPORT_COUNT, - }, - .emit = gen6_upload_scissor_state, -}; diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index 27414eb2480..dfd31e7a3b2 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -1666,6 +1666,90 @@ static const struct brw_tracked_state genX(blend_state) = { .emit = genX(upload_blend_state), }; +/* ---------------------------------------------------------------------- */ + +static void +genX(upload_scissor_state)(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->ctx; + const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); + struct GENX(SCISSOR_RECT) scissor; + uint32_t scissor_state_offset; + const unsigned int fb_width = _mesa_geometric_width(ctx->DrawBuffer); + const unsigned int fb_height = _mesa_geometric_height(ctx->DrawBuffer); + uint32_t *scissor_map; + + /* BRW_NEW_VIEWPORT_COUNT */ + const unsigned viewport_count = brw->clip.viewport_count; + + scissor_map = brw_state_batch( + brw, GENX(SCISSOR_RECT_length) * sizeof(uint32_t) * viewport_count, + 32, &scissor_state_offset); + + /* _NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT */ + + /* The scissor only needs to handle the intersection of drawable and + * scissor rect. Clipping to the boundaries of static shared buffers + * for front/back/depth is covered by looping over cliprects in brw_draw.c. + * + * Note that the hardware's coordinates are inclusive, while Mesa's min is + * inclusive but max is exclusive. + */ + for (unsigned i = 0; i < viewport_count; i++) { + int bbox[4]; + + bbox[0] = MAX2(ctx->ViewportArray[i].X, 0); + bbox[1] = MIN2(bbox[0] + ctx->ViewportArray[i].Width, fb_width); + bbox[2] = MAX2(ctx->ViewportArray[i].Y, 0); + bbox[3] = MIN2(bbox[2] + ctx->ViewportArray[i].Height, fb_height); + _mesa_intersect_scissor_bounding_box(ctx, i, bbox); + + if (bbox[0] == bbox[1] || bbox[2] == bbox[3]) { + /* If the scissor was out of bounds and got clamped to 0 width/height + * at the bounds, the subtraction of 1 from maximums could produce a + * negative number and thus not clip anything. Instead, just provide + * a min > max scissor inside the bounds, which produces the expected + * no rendering. + */ + scissor.ScissorRectangleXMin = 1; + scissor.ScissorRectangleXMax = 0; + scissor.ScissorRectangleYMin = 1; + scissor.ScissorRectangleYMax = 0; + } else if (render_to_fbo) { + /* texmemory: Y=0=bottom */ + scissor.ScissorRectangleXMin = bbox[0]; + scissor.ScissorRectangleXMax = bbox[1] - 1; + scissor.ScissorRectangleYMin = bbox[2]; + scissor.ScissorRectangleYMax = bbox[3] - 1; + } else { + /* memory: Y=0=top */ + scissor.ScissorRectangleXMin = bbox[0]; + scissor.ScissorRectangleXMax = bbox[1] - 1; + scissor.ScissorRectangleYMin = fb_height - bbox[3]; + scissor.ScissorRectangleYMax = fb_height - bbox[2] - 1; + } + + GENX(SCISSOR_RECT_pack)( + NULL, scissor_map + i * GENX(SCISSOR_RECT_length), &scissor); + } + + brw_batch_emit(brw, GENX(3DSTATE_SCISSOR_STATE_POINTERS), ptr) { + ptr.ScissorRectPointer = scissor_state_offset; + } +} + +static const struct brw_tracked_state genX(scissor_state) = { + .dirty = { + .mesa = _NEW_BUFFERS | + _NEW_SCISSOR | + _NEW_VIEWPORT, + .brw = BRW_NEW_BATCH | + BRW_NEW_BLORP | + BRW_NEW_VIEWPORT_COUNT, + }, + .emit = genX(upload_scissor_state), +}; + #endif /* ---------------------------------------------------------------------- */ @@ -2755,7 +2839,7 @@ genX(init_atoms)(struct brw_context *brw) &genX(sf_state), &genX(wm_state), - &gen6_scissor_state, + &genX(scissor_state), &gen6_binding_table_pointers, @@ -2845,7 +2929,7 @@ genX(init_atoms)(struct brw_context *brw) &genX(wm_state), &genX(ps_state), - &gen6_scissor_state, + &genX(scissor_state), &gen7_depthbuffer, @@ -2936,7 +3020,7 @@ genX(init_atoms)(struct brw_context *brw) &genX(depth_stencil_state), &genX(wm_state), - &gen6_scissor_state, + &genX(scissor_state), &gen7_depthbuffer, -- 2.30.2