mesa: Initialize all the viewports
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 6 Nov 2013 06:36:38 +0000 (22:36 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 20 Jan 2014 19:31:59 +0000 (11:31 -0800)
v2: Use MAX_VIEWPORTS instead of ctx->Const.MaxViewports because the
driver may not set ctx->Const.MaxViewports yet.

v3: Handle all viewport entries in update_viewport_matrix and
_mesa_copy_context too.  This was previously in an earlier patch.
Having the code in the earlier patch could cause _mesa_copy_context to
access a matrix that hadn't been constructed.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> [v2]
src/mesa/main/context.c
src/mesa/main/state.c
src/mesa/main/viewport.c

index 91fcbd284a69d86335401df3f18dbf5372c51883..1cd006416e1a0064601600e79dfe7fa24da4f7f5 100644 (file)
@@ -1357,14 +1357,17 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
    }
    if (mask & GL_VIEWPORT_BIT) {
       /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
-      dst->ViewportArray[0].X = src->ViewportArray[0].X;
-      dst->ViewportArray[0].Y = src->ViewportArray[0].Y;
-      dst->ViewportArray[0].Width = src->ViewportArray[0].Width;
-      dst->ViewportArray[0].Height = src->ViewportArray[0].Height;
-      dst->ViewportArray[0].Near = src->ViewportArray[0].Near;
-      dst->ViewportArray[0].Far = src->ViewportArray[0].Far;
-      _math_matrix_copy(&dst->ViewportArray[0]._WindowMap,
-                        &src->ViewportArray[0]._WindowMap);
+      unsigned i;
+      for (i = 0; i < src->Const.MaxViewports; i++) {
+         dst->ViewportArray[i].X = src->ViewportArray[i].X;
+         dst->ViewportArray[i].Y = src->ViewportArray[i].Y;
+         dst->ViewportArray[i].Width = src->ViewportArray[i].Width;
+         dst->ViewportArray[i].Height = src->ViewportArray[i].Height;
+         dst->ViewportArray[i].Near = src->ViewportArray[i].Near;
+         dst->ViewportArray[i].Far = src->ViewportArray[i].Far;
+         _math_matrix_copy(&dst->ViewportArray[i]._WindowMap,
+                           &src->ViewportArray[i]._WindowMap);
+      }
    }
 
    /* XXX FIXME:  Call callbacks?
@@ -1433,11 +1436,19 @@ void
 _mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
 {
    if (!ctx->ViewportInitialized && width > 0 && height > 0) {
+      unsigned i;
+
       /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
        * potential infinite recursion.
        */
       ctx->ViewportInitialized = GL_TRUE;
-      _mesa_set_viewport(ctx, 0, 0, 0, width, height);
+
+      /* Note: ctx->Const.MaxViewports may not have been set by the driver
+       * yet, so just initialize all of them.
+       */
+      for (i = 0; i < MAX_VIEWPORTS; i++) {
+         _mesa_set_viewport(ctx, i, 0, 0, width, height);
+      }
       _mesa_set_scissor(ctx, 0, 0, 0, width, height);
    }
 }
index acb2f2073d26f8d290f83df9ba0e8a4b4fd5202a..87f6553a5f9c6a60b7123440de69b78283dd3d2d 100644 (file)
@@ -269,6 +269,7 @@ static void
 update_viewport_matrix(struct gl_context *ctx)
 {
    const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
+   unsigned i;
 
    ASSERT(depthMax > 0);
 
@@ -276,11 +277,13 @@ update_viewport_matrix(struct gl_context *ctx)
     * and should be maintained elsewhere if at all.
     * NOTE: RasterPos uses this.
     */
-   _math_matrix_viewport(&ctx->ViewportArray[0]._WindowMap,
-                         ctx->ViewportArray[0].X, ctx->ViewportArray[0].Y,
-                         ctx->ViewportArray[0].Width, ctx->ViewportArray[0].Height,
-                         ctx->ViewportArray[0].Near, ctx->ViewportArray[0].Far,
-                         depthMax);
+   for (i = 0; i < ctx->Const.MaxViewports; i++) {
+      _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap,
+                            ctx->ViewportArray[i].X, ctx->ViewportArray[i].Y,
+                            ctx->ViewportArray[i].Width, ctx->ViewportArray[i].Height,
+                            ctx->ViewportArray[i].Near, ctx->ViewportArray[i].Far,
+                            depthMax);
+   }
 }
 
 
index ac891c84710a989149522c3efac3d9f53581e8d5..cc031b00a41b9dee2d24714816813fc95110a2c0 100644 (file)
@@ -197,18 +197,24 @@ _mesa_DepthRangef(GLclampf nearval, GLclampf farval)
 void _mesa_init_viewport(struct gl_context *ctx)
 {
    GLfloat depthMax = 65535.0F; /* sorf of arbitrary */
+   unsigned i;
 
-   /* Viewport group */
-   ctx->ViewportArray[0].X = 0;
-   ctx->ViewportArray[0].Y = 0;
-   ctx->ViewportArray[0].Width = 0;
-   ctx->ViewportArray[0].Height = 0;
-   ctx->ViewportArray[0].Near = 0.0;
-   ctx->ViewportArray[0].Far = 1.0;
-   _math_matrix_ctr(&ctx->ViewportArray[0]._WindowMap);
-
-   _math_matrix_viewport(&ctx->ViewportArray[0]._WindowMap, 0, 0, 0, 0,
-                         0.0F, 1.0F, depthMax);
+   /* Note: ctx->Const.MaxViewports may not have been set by the driver yet,
+    * so just initialize all of them.
+    */
+   for (i = 0; i < MAX_VIEWPORTS; i++) {
+      /* Viewport group */
+      ctx->ViewportArray[i].X = 0;
+      ctx->ViewportArray[i].Y = 0;
+      ctx->ViewportArray[i].Width = 0;
+      ctx->ViewportArray[i].Height = 0;
+      ctx->ViewportArray[i].Near = 0.0;
+      ctx->ViewportArray[i].Far = 1.0;
+      _math_matrix_ctr(&ctx->ViewportArray[i]._WindowMap);
+
+      _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap, 0, 0, 0, 0,
+                            0.0F, 1.0F, depthMax);
+   }
 }
 
 
@@ -218,6 +224,9 @@ void _mesa_init_viewport(struct gl_context *ctx)
  */
 void _mesa_free_viewport_data(struct gl_context *ctx)
 {
-   _math_matrix_dtr(&ctx->ViewportArray[0]._WindowMap);
+   unsigned i;
+
+   for (i = 0; i < MAX_VIEWPORTS; i++)
+      _math_matrix_dtr(&ctx->ViewportArray[i]._WindowMap);
 }