- struct pipe_scissor_state scissor;
- const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
-
- scissor.minx = 0;
- scissor.miny = 0;
- scissor.maxx = fb->Width;
- scissor.maxy = fb->Height;
-
- if (st->ctx->Scissor.Enabled) {
- if (st->ctx->Scissor.X > scissor.minx)
- scissor.minx = st->ctx->Scissor.X;
- if (st->ctx->Scissor.Y > scissor.miny)
- scissor.miny = st->ctx->Scissor.Y;
+ struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS];
+ const struct gl_context *ctx = st->ctx;
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+ const unsigned int fb_width = _mesa_geometric_width(fb);
+ const unsigned int fb_height = _mesa_geometric_height(fb);
+ GLint miny, maxy;
+ unsigned i;
+ bool changed = false;
+
+ for (i = 0 ; i < st->state.num_viewports; i++) {
+ scissor[i].minx = 0;
+ scissor[i].miny = 0;
+ scissor[i].maxx = fb_width;
+ scissor[i].maxy = fb_height;
+
+ if (ctx->Scissor.EnableFlags & (1 << i)) {
+ /* need to be careful here with xmax or ymax < 0 */
+ GLint xmax = MAX2(0, ctx->Scissor.ScissorArray[i].X + ctx->Scissor.ScissorArray[i].Width);
+ GLint ymax = MAX2(0, ctx->Scissor.ScissorArray[i].Y + ctx->Scissor.ScissorArray[i].Height);
+
+ if (ctx->Scissor.ScissorArray[i].X > (GLint)scissor[i].minx)
+ scissor[i].minx = ctx->Scissor.ScissorArray[i].X;
+ if (ctx->Scissor.ScissorArray[i].Y > (GLint)scissor[i].miny)
+ scissor[i].miny = ctx->Scissor.ScissorArray[i].Y;
+
+ if (xmax < (GLint) scissor[i].maxx)
+ scissor[i].maxx = xmax;
+ if (ymax < (GLint) scissor[i].maxy)
+ scissor[i].maxy = ymax;
+
+ /* check for null space */
+ if (scissor[i].minx >= scissor[i].maxx || scissor[i].miny >= scissor[i].maxy)
+ scissor[i].minx = scissor[i].miny = scissor[i].maxx = scissor[i].maxy = 0;
+ }
+
+ /* Now invert Y if needed.
+ * Gallium drivers use the convention Y=0=top for surfaces.
+ */
+ if (st->state.fb_orientation == Y_0_TOP) {
+ miny = fb->Height - scissor[i].maxy;
+ maxy = fb->Height - scissor[i].miny;
+ scissor[i].miny = miny;
+ scissor[i].maxy = maxy;
+ }
+
+ if (memcmp(&scissor[i], &st->state.scissor[i], sizeof(scissor[0])) != 0) {
+ /* state has changed */
+ st->state.scissor[i] = scissor[i]; /* struct copy */
+ changed = true;
+ }
+ }