[Mesa-dev] [PATCH 08/40] mesa: Update gl_scissor_attrib to support ARB_viewport_array

Ian Romanick idr at freedesktop.org
Fri Jan 10 17:40:09 PST 2014


From: Courtney Goeltzenleuchter <courtney at LunarG.com>

Update Mesa and drivers to access updated gl_scissor_attrib.
Now have an enable bitfield and array of gl_scissor_rects.
Drivers have been updated to the new scissor enable state
attribute (gl_context.scissor.EnableFlags) but still treat it
as a single boolean which is okay as mesa will only use
bit 0 when communicating with a driver that does not support
ARB_viewport_array.

v2 (idr): Rebase fixes.
---
 src/mesa/drivers/common/driverfuncs.c       |  2 +-
 src/mesa/drivers/common/meta.c              |  6 +++---
 src/mesa/drivers/dri/i915/i830_state.c      | 24 ++++++++++++++----------
 src/mesa/drivers/dri/i915/i915_state.c      | 24 ++++++++++++++----------
 src/mesa/drivers/dri/i915/intel_fbo.c       |  2 +-
 src/mesa/drivers/dri/i965/brw_clear.c       | 12 ++++++------
 src/mesa/drivers/dri/i965/brw_sf_state.c    |  2 +-
 src/mesa/drivers/dri/i965/gen6_sf_state.c   |  2 +-
 src/mesa/drivers/dri/i965/gen7_sf_state.c   |  2 +-
 src/mesa/drivers/dri/i965/intel_fbo.c       |  2 +-
 src/mesa/drivers/dri/radeon/radeon_common.c |  6 +++---
 src/mesa/main/attrib.c                      | 22 ++++++++++++++++------
 src/mesa/main/enable.c                      | 29 ++++++++++++++++++++++++-----
 src/mesa/main/framebuffer.c                 | 19 ++++++++++---------
 src/mesa/main/get.c                         | 12 ++++++++----
 src/mesa/main/get_hash_params.py            |  2 +-
 src/mesa/main/mtypes.h                      |  8 ++++++--
 src/mesa/main/scissor.c                     | 26 +++++++++++++-------------
 src/mesa/state_tracker/st_atom_rasterizer.c |  2 +-
 src/mesa/state_tracker/st_atom_scissor.c    | 14 +++++++-------
 src/mesa/state_tracker/st_cb_bitmap.c       |  2 +-
 src/mesa/state_tracker/st_cb_clear.c        | 10 +++++-----
 src/mesa/state_tracker/st_cb_drawpixels.c   |  2 +-
 src/mesa/swrast/s_context.c                 |  2 +-
 24 files changed, 140 insertions(+), 94 deletions(-)

diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index e8dcb24..6d56838 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -274,7 +274,7 @@ _mesa_init_driver_state(struct gl_context *ctx)
    ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled);
    ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag);
    ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag);
-   ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled);
+   ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.EnableFlags);
    ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);
    ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE);
    ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE);
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 1294514..173b45c 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -933,9 +933,9 @@ _mesa_meta_end(struct gl_context *ctx)
    }
 
    if (state & MESA_META_SCISSOR) {
-      _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
-      _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
-                    save->Scissor.Width, save->Scissor.Height);
+      _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.EnableFlags);
+      _mesa_Scissor(save->Scissor.ScissorArray[0].X, save->Scissor.ScissorArray[0].Y,
+                    save->Scissor.ScissorArray[0].Width, save->Scissor.ScissorArray[0].Height);
    }
 
    if (state & MESA_META_SHADER) {
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index a69c7ea..4ae1fed 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -536,23 +536,27 @@ i830Scissor(struct gl_context * ctx)
       return;
 
    DBG("%s %d,%d %dx%d\n", __FUNCTION__,
-       ctx->Scissor.X,     ctx->Scissor.Y,
-       ctx->Scissor.Width, ctx->Scissor.Height);
+       ctx->Scissor.ScissorArray[0].X,     ctx->Scissor.ScissorArray[0].Y,
+       ctx->Scissor.ScissorArray[0].Width, ctx->Scissor.ScissorArray[0].Height);
 
    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      x1 = ctx->Scissor.X;
-      y1 = ctx->DrawBuffer->Height - (ctx->Scissor.Y + ctx->Scissor.Height);
-      x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
-      y2 = y1 + ctx->Scissor.Height - 1;
+      x1 = ctx->Scissor.ScissorArray[0].X;
+      y1 = ctx->DrawBuffer->Height - (ctx->Scissor.ScissorArray[0].Y
+                                      + ctx->Scissor.ScissorArray[0].Height);
+      x2 = ctx->Scissor.ScissorArray[0].X
+         + ctx->Scissor.ScissorArray[0].Width - 1;
+      y2 = y1 + ctx->Scissor.ScissorArray[0].Height - 1;
       DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2);
    }
    else {
       /* FBO - not inverted
        */
-      x1 = ctx->Scissor.X;
-      y1 = ctx->Scissor.Y;
-      x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
-      y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
+      x1 = ctx->Scissor.ScissorArray[0].X;
+      y1 = ctx->Scissor.ScissorArray[0].Y;
+      x2 = ctx->Scissor.ScissorArray[0].X
+         + ctx->Scissor.ScissorArray[0].Width - 1;
+      y2 = ctx->Scissor.ScissorArray[0].Y
+         + ctx->Scissor.ScissorArray[0].Height - 1;
       DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2);
    }
 
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 9a25b9e..1cc1d5d 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -510,23 +510,27 @@ i915Scissor(struct gl_context * ctx)
       return;
 
    DBG("%s %d,%d %dx%d\n", __FUNCTION__,
-       ctx->Scissor.X,     ctx->Scissor.Y,
-       ctx->Scissor.Width, ctx->Scissor.Height);
+       ctx->Scissor.ScissorArray[0].X,     ctx->Scissor.ScissorArray[0].Y,
+       ctx->Scissor.ScissorArray[0].Width, ctx->Scissor.ScissorArray[0].Height);
 
    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      x1 = ctx->Scissor.X;
-      y1 = ctx->DrawBuffer->Height - (ctx->Scissor.Y + ctx->Scissor.Height);
-      x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
-      y2 = y1 + ctx->Scissor.Height - 1;
+      x1 = ctx->Scissor.ScissorArray[0].X;
+      y1 = ctx->DrawBuffer->Height - (ctx->Scissor.ScissorArray[0].Y
+                                      + ctx->Scissor.ScissorArray[0].Height);
+      x2 = ctx->Scissor.ScissorArray[0].X
+         + ctx->Scissor.ScissorArray[0].Width - 1;
+      y2 = y1 + ctx->Scissor.ScissorArray[0].Height - 1;
       DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2);
    }
    else {
       /* FBO - not inverted
        */
-      x1 = ctx->Scissor.X;
-      y1 = ctx->Scissor.Y;
-      x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
-      y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
+      x1 = ctx->Scissor.ScissorArray[0].X;
+      y1 = ctx->Scissor.ScissorArray[0].Y;
+      x2 = ctx->Scissor.ScissorArray[0].X
+         + ctx->Scissor.ScissorArray[0].Width - 1;
+      y2 = ctx->Scissor.ScissorArray[0].Y
+         + ctx->Scissor.ScissorArray[0].Height - 1;
       DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2);
    }
    
diff --git a/src/mesa/drivers/dri/i915/intel_fbo.c b/src/mesa/drivers/dri/i915/intel_fbo.c
index 36b22ca..d119491 100644
--- a/src/mesa/drivers/dri/i915/intel_fbo.c
+++ b/src/mesa/drivers/dri/i915/intel_fbo.c
@@ -658,7 +658,7 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx,
             srcY0 >= 0 && srcY1 <= readFb->Height &&
             dstX0 >= 0 && dstX1 <= drawFb->Width &&
             dstY0 >= 0 && dstY1 <= drawFb->Height &&
-            !ctx->Scissor.Enabled)) {
+            !ctx->Scissor.EnableFlags)) {
          perf_debug("glBlitFramebuffer(): non-1:1 blit.  "
                     "Falling back to software rendering.\n");
          return mask;
diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c
index fe68d9e..58fd612 100644
--- a/src/mesa/drivers/dri/i965/brw_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_clear.c
@@ -83,10 +83,10 @@ debug_mask(const char *name, GLbitfield mask)
 static bool
 noop_scissor(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
-   return ctx->Scissor.X <= 0 &&
-          ctx->Scissor.Y <= 0 &&
-          ctx->Scissor.Width >= fb->Width &&
-          ctx->Scissor.Height >= fb->Height;
+   return ctx->Scissor.ScissorArray[0].X <= 0 &&
+          ctx->Scissor.ScissorArray[0].Y <= 0 &&
+          ctx->Scissor.ScissorArray[0].Width >= fb->Width &&
+          ctx->Scissor.ScissorArray[0].Height >= fb->Height;
 }
 
 /**
@@ -121,7 +121,7 @@ brw_fast_clear_depth(struct gl_context *ctx)
     * a previous clear had happened at a different clear value and resolve it
     * first.
     */
-   if (ctx->Scissor.Enabled && !noop_scissor(ctx, fb)) {
+   if (ctx->Scissor.EnableFlags && !noop_scissor(ctx, fb)) {
       perf_debug("Failed to fast clear depth due to scissor being enabled.  "
                  "Possible 5%% performance win if avoided.\n");
       return false;
@@ -218,7 +218,7 @@ brw_clear(struct gl_context *ctx, GLbitfield mask)
 {
    struct brw_context *brw = brw_context(ctx);
    struct gl_framebuffer *fb = ctx->DrawBuffer;
-   bool partial_clear = ctx->Scissor.Enabled && !noop_scissor(ctx, fb);
+   bool partial_clear = ctx->Scissor.EnableFlags && !noop_scissor(ctx, fb);
 
    if (!_mesa_check_conditional_render(ctx))
       return;
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index 69093f2..8bd4272 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -179,7 +179,7 @@ static void upload_sf_unit( struct brw_context *brw )
    sf->sf5.viewport_transform = 1;
 
    /* _NEW_SCISSOR */
-   if (ctx->Scissor.Enabled)
+   if (ctx->Scissor.EnableFlags)
       sf->sf6.scissor = 1;
 
    /* _NEW_POLYGON */
diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c b/src/mesa/drivers/dri/i965/gen6_sf_state.c
index ed0b429..ec14be4 100644
--- a/src/mesa/drivers/dri/i965/gen6_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c
@@ -298,7 +298,7 @@ upload_sf_state(struct brw_context *brw)
    }
 
    /* _NEW_SCISSOR */
-   if (ctx->Scissor.Enabled)
+   if (ctx->Scissor.EnableFlags)
       dw3 |= GEN6_SF_SCISSOR_ENABLE;
 
    /* _NEW_POLYGON */
diff --git a/src/mesa/drivers/dri/i965/gen7_sf_state.c b/src/mesa/drivers/dri/i965/gen7_sf_state.c
index 8d86280..7fe1435 100644
--- a/src/mesa/drivers/dri/i965/gen7_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sf_state.c
@@ -186,7 +186,7 @@ upload_sf_state(struct brw_context *brw)
    }
 
    /* _NEW_SCISSOR */
-   if (ctx->Scissor.Enabled)
+   if (ctx->Scissor.EnableFlags)
       dw2 |= GEN6_SF_SCISSOR_ENABLE;
 
    /* _NEW_LINE */
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c
index d3b9dcf..8b1b70b 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.c
+++ b/src/mesa/drivers/dri/i965/intel_fbo.c
@@ -715,7 +715,7 @@ intel_blit_framebuffer_with_blitter(struct gl_context *ctx,
             srcY0 >= 0 && srcY1 <= readFb->Height &&
             dstX0 >= 0 && dstX1 <= drawFb->Width &&
             dstY0 >= 0 && dstY1 <= drawFb->Height &&
-            !ctx->Scissor.Enabled)) {
+            !(ctx->Scissor.EnableFlags))) {
          perf_debug("glBlitFramebuffer(): non-1:1 blit.  "
                     "Falling back to software rendering.\n");
          return mask;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 690e486..5675a36 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -105,8 +105,8 @@ void radeonSetCliprects(radeonContextPtr radeon)
 void radeonUpdateScissor( struct gl_context *ctx )
 {
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-	GLint x = ctx->Scissor.X, y = ctx->Scissor.Y;
-	GLsizei w = ctx->Scissor.Width, h = ctx->Scissor.Height;
+	GLint x = ctx->Scissor.ScissorArray[0].X, y = ctx->Scissor.ScissorArray[0].Y;
+	GLsizei w = ctx->Scissor.ScissorArray[0].Width, h = ctx->Scissor.ScissorArray[0].Height;
 	int x1, y1, x2, y2;
 	int min_x, min_y, max_x, max_y;
 
@@ -145,7 +145,7 @@ void radeonUpdateScissor( struct gl_context *ctx )
 void radeonScissor(struct gl_context *ctx)
 {
 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-	if (ctx->Scissor.Enabled) {
+	if (ctx->Scissor.EnableFlags) {
 		/* We don't pipeline cliprect changes */
 		radeon_firevertices(radeon);
 		radeonUpdateScissor(ctx);
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 30c815d..f571f9f 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -112,7 +112,7 @@ struct gl_enable_attrib
    GLboolean PolygonSmooth;
    GLboolean PolygonStipple;
    GLboolean RescaleNormals;
-   GLboolean Scissor;
+   GLbitfield Scissor;
    GLboolean Stencil;
    GLboolean StencilTwoSide;          /* GL_EXT_stencil_two_side */
    GLboolean MultisampleEnabled;      /* GL_ARB_multisample */
@@ -354,7 +354,7 @@ _mesa_PushAttrib(GLbitfield mask)
       attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
       attr->PolygonStipple = ctx->Polygon.StippleFlag;
       attr->RescaleNormals = ctx->Transform.RescaleNormals;
-      attr->Scissor = ctx->Scissor.Enabled;
+      attr->Scissor = ctx->Scissor.EnableFlags;
       attr->Stencil = ctx->Stencil.Enabled;
       attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
       attr->MultisampleEnabled = ctx->Multisample.Enabled;
@@ -658,7 +658,13 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
                    GL_POLYGON_SMOOTH);
    TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
                    GL_POLYGON_STIPPLE);
-   TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
+   if (ctx->Scissor.EnableFlags != enable->Scissor) {
+      unsigned i;
+
+      for (i = 0; i < ctx->Const.MaxViewports; i++) {
+         _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, (enable->Scissor >> i) & 1);
+      }
+   }
    TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
    if (ctx->Extensions.EXT_stencil_two_side) {
       TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
@@ -1264,9 +1270,13 @@ _mesa_PopAttrib(void)
             {
                const struct gl_scissor_attrib *scissor;
                scissor = (const struct gl_scissor_attrib *) attr->data;
-               _mesa_Scissor(scissor->X, scissor->Y,
-                             scissor->Width, scissor->Height);
-               _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled);
+               _mesa_set_scissor(ctx,
+                                 scissor->ScissorArray[0].X,
+                                 scissor->ScissorArray[0].Y,
+                                 scissor->ScissorArray[0].Width,
+                                 scissor->ScissorArray[0].Height);
+               _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->EnableFlags & 1);
+
             }
             break;
          case GL_STENCIL_BUFFER_BIT:
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index bb4a23c..4841e84 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -659,10 +659,15 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
          ctx->Transform.RescaleNormals = state;
          break;
       case GL_SCISSOR_TEST:
-         if (ctx->Scissor.Enabled == state)
-            return;
-         FLUSH_VERTICES(ctx, _NEW_SCISSOR);
-         ctx->Scissor.Enabled = state;
+         {
+            /* Must expand glEnable to all scissors */
+            GLbitfield newEnabled =
+               state * ((1 << ctx->Const.MaxViewports) - 1);
+            if (newEnabled != ctx->Scissor.EnableFlags) {
+               FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+               ctx->Scissor.EnableFlags = newEnabled;
+            }
+         }
          break;
       case GL_STENCIL_TEST:
          if (ctx->Stencil.Enabled == state)
@@ -1077,6 +1082,20 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
             ctx->Color.BlendEnabled &= ~(1 << index);
       }
       break;
+   case GL_SCISSOR_TEST:
+      if (index >= ctx->Const.MaxViewports) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
+                     state ? "glEnablei" : "glDisablei", index);
+         return;
+      }
+      if (((ctx->Scissor.EnableFlags >> index) & 1) != state) {
+         FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+         if (state)
+            ctx->Scissor.EnableFlags |= (1 << index);
+         else
+            ctx->Scissor.EnableFlags &= ~(1 << index);
+      }
+      break;
    default:
       goto invalid_enum_error;
    }
@@ -1350,7 +1369,7 @@ _mesa_IsEnabled( GLenum cap )
             goto invalid_enum_error;
          return ctx->Transform.RescaleNormals;
       case GL_SCISSOR_TEST:
-	 return ctx->Scissor.Enabled;
+	 return ctx->Scissor.EnableFlags & 1;  /* return state for index 0 */
       case GL_STENCIL_TEST:
 	 return ctx->Stencil.Enabled;
       case GL_TEXTURE_1D:
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 2fad458..f14f7a4 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -380,18 +380,19 @@ _mesa_update_draw_buffer_bounds(struct gl_context *ctx)
    buffer->_Xmax = buffer->Width;
    buffer->_Ymax = buffer->Height;
 
-   if (ctx->Scissor.Enabled) {
-      if (ctx->Scissor.X > buffer->_Xmin) {
-	 buffer->_Xmin = ctx->Scissor.X;
+   /* Default to the first scissor as that's always valid */
+   if (ctx->Scissor.EnableFlags & 1) {
+      if (ctx->Scissor.ScissorArray[0].X > buffer->_Xmin) {
+	 buffer->_Xmin = ctx->Scissor.ScissorArray[0].X;
       }
-      if (ctx->Scissor.Y > buffer->_Ymin) {
-	 buffer->_Ymin = ctx->Scissor.Y;
+      if (ctx->Scissor.ScissorArray[0].Y > buffer->_Ymin) {
+	 buffer->_Ymin = ctx->Scissor.ScissorArray[0].Y;
       }
-      if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
-	 buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
+      if (ctx->Scissor.ScissorArray[0].X + ctx->Scissor.ScissorArray[0].Width < buffer->_Xmax) {
+	 buffer->_Xmax = ctx->Scissor.ScissorArray[0].X + ctx->Scissor.ScissorArray[0].Width;
       }
-      if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
-	 buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
+      if (ctx->Scissor.ScissorArray[0].Y + ctx->Scissor.ScissorArray[0].Height < buffer->_Ymax) {
+	 buffer->_Ymax = ctx->Scissor.ScissorArray[0].Y + ctx->Scissor.ScissorArray[0].Height;
       }
       /* finally, check for empty region */
       if (buffer->_Xmin > buffer->_Xmax) {
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 6e55e99..e5240b1 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -658,10 +658,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
       break;
 
    case GL_SCISSOR_BOX:
-      v->value_int_4[0] = ctx->Scissor.X;
-      v->value_int_4[1] = ctx->Scissor.Y;
-      v->value_int_4[2] = ctx->Scissor.Width;
-      v->value_int_4[3] = ctx->Scissor.Height;
+      v->value_int_4[0] = ctx->Scissor.ScissorArray[0].X;
+      v->value_int_4[1] = ctx->Scissor.ScissorArray[0].Y;
+      v->value_int_4[2] = ctx->Scissor.ScissorArray[0].Width;
+      v->value_int_4[3] = ctx->Scissor.ScissorArray[0].Height;
+      break;
+
+   case GL_SCISSOR_TEST:
+      v->value_bool = ctx->Scissor.EnableFlags & 1;
       break;
 
    case GL_LIST_INDEX:
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 7f025a9..52458b8 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -30,7 +30,7 @@ descriptor=[
   [ "POLYGON_OFFSET_FILL", "CONTEXT_BOOL(Polygon.OffsetFill), NO_EXTRA" ],
   [ "RED_BITS", "BUFFER_INT(Visual.redBits), extra_new_buffers" ],
   [ "SCISSOR_BOX", "LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA" ],
-  [ "SCISSOR_TEST", "CONTEXT_BOOL(Scissor.Enabled), NO_EXTRA" ],
+  [ "SCISSOR_TEST", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ],
   [ "STENCIL_BITS", "BUFFER_INT(Visual.stencilBits), extra_new_buffers" ],
   [ "STENCIL_CLEAR_VALUE", "CONTEXT_INT(Stencil.Clear), NO_EXTRA" ],
   [ "STENCIL_FAIL", "LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA" ],
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 6e2f6f7..da65d15 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1009,12 +1009,16 @@ struct gl_polygon_attrib
 /**
  * Scissor attributes (GL_SCISSOR_BIT).
  */
-struct gl_scissor_attrib
+struct gl_scissor_rect
 {
-   GLboolean Enabled;		/**< Scissor test enabled? */
    GLint X, Y;			/**< Lower left corner of box */
    GLsizei Width, Height;	/**< Size of box */
 };
+struct gl_scissor_attrib
+{
+   GLbitfield EnableFlags;	/**< Scissor test enabled? */
+   struct gl_scissor_rect ScissorArray[MAX_VIEWPORTS];
+};
 
 
 /**
diff --git a/src/mesa/main/scissor.c b/src/mesa/main/scissor.c
index ac86bd5..7ec927e 100644
--- a/src/mesa/main/scissor.c
+++ b/src/mesa/main/scissor.c
@@ -66,17 +66,17 @@ void
 _mesa_set_scissor(struct gl_context *ctx, 
                   GLint x, GLint y, GLsizei width, GLsizei height)
 {
-   if (x == ctx->Scissor.X &&
-       y == ctx->Scissor.Y &&
-       width == ctx->Scissor.Width &&
-       height == ctx->Scissor.Height)
+   if (x == ctx->Scissor.ScissorArray[0].X &&
+       y == ctx->Scissor.ScissorArray[0].Y &&
+       width == ctx->Scissor.ScissorArray[0].Width &&
+       height == ctx->Scissor.ScissorArray[0].Height)
       return;
 
    FLUSH_VERTICES(ctx, _NEW_SCISSOR);
-   ctx->Scissor.X = x;
-   ctx->Scissor.Y = y;
-   ctx->Scissor.Width = width;
-   ctx->Scissor.Height = height;
+   ctx->Scissor.ScissorArray[0].X = x;
+   ctx->Scissor.ScissorArray[0].Y = y;
+   ctx->Scissor.ScissorArray[0].Width = width;
+   ctx->Scissor.ScissorArray[0].Height = height;
 
    if (ctx->Driver.Scissor)
       ctx->Driver.Scissor(ctx);
@@ -91,9 +91,9 @@ void
 _mesa_init_scissor(struct gl_context *ctx)
 {
    /* Scissor group */
-   ctx->Scissor.Enabled = GL_FALSE;
-   ctx->Scissor.X = 0;
-   ctx->Scissor.Y = 0;
-   ctx->Scissor.Width = 0;
-   ctx->Scissor.Height = 0;
+   ctx->Scissor.EnableFlags = GL_FALSE;
+   ctx->Scissor.ScissorArray[0].X = 0;
+   ctx->Scissor.ScissorArray[0].Y = 0;
+   ctx->Scissor.ScissorArray[0].Width = 0;
+   ctx->Scissor.ScissorArray[0].Height = 0;
 }
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index f4d0cab..1a4f4d7 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -223,7 +223,7 @@ static void update_raster_state( struct st_context *st )
    raster->multisample = ctx->Multisample._Enabled;
 
    /* _NEW_SCISSOR */
-   raster->scissor = ctx->Scissor.Enabled;
+   raster->scissor = ctx->Scissor.EnableFlags;
 
    /* _NEW_FRAG_CLAMP */
    raster->clamp_fragment_color = !st->clamp_frag_color_in_shader &&
diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
index 19c2cd2..a62b770 100644
--- a/src/mesa/state_tracker/st_atom_scissor.c
+++ b/src/mesa/state_tracker/st_atom_scissor.c
@@ -53,15 +53,15 @@ update_scissor( struct st_context *st )
    scissor.maxx = fb->Width;
    scissor.maxy = fb->Height;
 
-   if (ctx->Scissor.Enabled) {
+   if (ctx->Scissor.EnableFlags & 1) {
       /* need to be careful here with xmax or ymax < 0 */
-      GLint xmax = MAX2(0, ctx->Scissor.X + ctx->Scissor.Width);
-      GLint ymax = MAX2(0, ctx->Scissor.Y + ctx->Scissor.Height);
+      GLint xmax = MAX2(0, ctx->Scissor.ScissorArray[0].X + ctx->Scissor.ScissorArray[0].Width);
+      GLint ymax = MAX2(0, ctx->Scissor.ScissorArray[0].Y + ctx->Scissor.ScissorArray[0].Height);
 
-      if (ctx->Scissor.X > (GLint)scissor.minx)
-         scissor.minx = ctx->Scissor.X;
-      if (ctx->Scissor.Y > (GLint)scissor.miny)
-         scissor.miny = ctx->Scissor.Y;
+      if (ctx->Scissor.ScissorArray[0].X > (GLint)scissor.minx)
+         scissor.minx = ctx->Scissor.ScissorArray[0].X;
+      if (ctx->Scissor.ScissorArray[0].Y > (GLint)scissor.miny)
+         scissor.miny = ctx->Scissor.ScissorArray[0].Y;
 
       if (xmax < (GLint) scissor.maxx)
          scissor.maxx = xmax;
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index e96f4b3..bfbc542 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -457,7 +457,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_save_aux_vertex_buffer_slot(cso);
 
    /* rasterizer state: just scissor */
-   st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled;
+   st->bitmap.rasterizer.scissor = ctx->Scissor.EnableFlags & 1;
    cso_set_rasterizer(cso, &st->bitmap.rasterizer);
 
    /* fragment shader state: TEX lookup program */
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 887e58b..1094f3b 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -364,11 +364,11 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
 static INLINE GLboolean
 is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
-   return ctx->Scissor.Enabled &&
-          (ctx->Scissor.X > 0 ||
-           ctx->Scissor.Y > 0 ||
-           (unsigned) ctx->Scissor.Width < rb->Width ||
-           (unsigned) ctx->Scissor.Height < rb->Height);
+   return (ctx->Scissor.EnableFlags & 1) &&
+          (ctx->Scissor.ScissorArray[0].X > 0 ||
+           ctx->Scissor.ScissorArray[0].Y > 0 ||
+           (unsigned) ctx->Scissor.ScissorArray[0].Width < rb->Width ||
+           (unsigned) ctx->Scissor.ScissorArray[0].Height < rb->Height);
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 3058dfb..7cf6264 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -713,7 +713,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
       rasterizer.half_pixel_center = 1;
       rasterizer.bottom_edge_rule = 1;
       rasterizer.depth_clip = !ctx->Transform.DepthClamp;
-      rasterizer.scissor = ctx->Scissor.Enabled;
+      rasterizer.scissor = ctx->Scissor.EnableFlags;
       cso_set_rasterizer(cso, &rasterizer);
    }
 
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index fdf9b37..9e1faa9 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -61,7 +61,7 @@ _swrast_update_rasterflags( struct gl_context *ctx )
    if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;
    if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;
    if (swrast->_FogEnabled)               rasterMask |= FOG_BIT;
-   if (ctx->Scissor.Enabled)              rasterMask |= CLIP_BIT;
+   if (ctx->Scissor.EnableFlags)              rasterMask |= CLIP_BIT;
    if (ctx->Stencil._Enabled)             rasterMask |= STENCIL_BIT;
    for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
       if (!ctx->Color.ColorMask[i][0] ||
-- 
1.8.1.4



More information about the mesa-dev mailing list