mesa: Refactor viewport transform computation.
authorMathias Fröhlich <Mathias.Froehlich@gmx.net>
Sun, 21 Sep 2014 16:09:21 +0000 (18:09 +0200)
committerMathias Fröhlich <Mathias.Froehlich@gmx.net>
Fri, 24 Oct 2014 17:21:20 +0000 (19:21 +0200)
This is for preparation of ARB_clip_control.

v3:
Add comments.

Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Mathias Froehlich <Mathias.Froehlich@web.de>
src/mesa/drivers/dri/i915/i915_state.c
src/mesa/main/state.c
src/mesa/main/viewport.c
src/mesa/main/viewport.h
src/mesa/math/m_matrix.c
src/mesa/math/m_matrix.h
src/mesa/state_tracker/st_atom_viewport.c

index f31b271500f27dcd9ff8c9235a06a7d49621e541..f9aecba2327f716629cc84f58f8509ecbdd047a5 100644 (file)
@@ -34,6 +34,7 @@
 #include "main/dd.h"
 #include "main/state.h"
 #include "main/stencil.h"
+#include "main/viewport.h"
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 
@@ -401,26 +402,17 @@ void
 intelCalcViewport(struct gl_context * ctx)
 {
    struct intel_context *intel = intel_context(ctx);
+   double scale[3], translate[3];
+
+   _mesa_get_viewport_xform(ctx, 0, scale, translate);
 
    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      _math_matrix_viewport(&intel->ViewportMatrix,
-                           ctx->ViewportArray[0].X,
-                           ctx->DrawBuffer->Height - ctx->ViewportArray[0].Y,
-                           ctx->ViewportArray[0].Width,
-                           -ctx->ViewportArray[0].Height,
-                           ctx->ViewportArray[0].Near,
-                           ctx->ViewportArray[0].Far,
-                           1.0);
-   } else {
-      _math_matrix_viewport(&intel->ViewportMatrix,
-                           ctx->ViewportArray[0].X,
-                           ctx->ViewportArray[0].Y,
-                           ctx->ViewportArray[0].Width,
-                           ctx->ViewportArray[0].Height,
-                           ctx->ViewportArray[0].Near,
-                           ctx->ViewportArray[0].Far,
-                           1.0);
+      scale[1] = -scale[1];
+      translate[1] = ctx->DrawBuffer->Height - translate[1];
    }
+
+   _math_matrix_viewport(&intel->ViewportMatrix,
+                         scale, translate, 1.0);
 }
 
 
index 80287c47062177169afa36c72e6ed73e40761cc0..3dbbfaac76c33d23acc1243d5f1539e700b85f3a 100644 (file)
@@ -51,6 +51,7 @@
 #include "texobj.h"
 #include "texstate.h"
 #include "varray.h"
+#include "viewport.h"
 #include "blend.h"
 
 
@@ -281,11 +282,11 @@ update_viewport_matrix(struct gl_context *ctx)
     * NOTE: RasterPos uses this.
     */
    for (i = 0; i < ctx->Const.MaxViewports; i++) {
+      double scale[3], translate[3];
+
+      _mesa_get_viewport_xform(ctx, i, scale, translate);
       _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);
+                            scale, translate, depthMax);
    }
 }
 
index 222ae307b55258ffea1ad3082a7b7fb23231210f..afc813dceb743acb19488199e939fda866ea57ec 100644 (file)
@@ -39,6 +39,8 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
                        GLfloat x, GLfloat y,
                        GLfloat width, GLfloat height)
 {
+   double scale[3], translate[3];
+
    /* clamp width and height to the implementation dependent range */
    width  = MIN2(width, (GLfloat) ctx->Const.MaxViewportWidth);
    height = MIN2(height, (GLfloat) ctx->Const.MaxViewportHeight);
@@ -75,14 +77,9 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
     * the WindowMap matrix being up to date in the driver's Viewport
     * and DepthRange functions.
     */
+   _mesa_get_viewport_xform(ctx, idx, scale, translate);
    _math_matrix_viewport(&ctx->ViewportArray[idx]._WindowMap,
-                         ctx->ViewportArray[idx].X,
-                         ctx->ViewportArray[idx].Y,
-                         ctx->ViewportArray[idx].Width,
-                         ctx->ViewportArray[idx].Height,
-                         ctx->ViewportArray[idx].Near,
-                         ctx->ViewportArray[idx].Far,
-                         ctx->DrawBuffer->_DepthMaxF);
+                         scale, translate, ctx->DrawBuffer->_DepthMaxF);
 #endif
 }
 
@@ -248,6 +245,8 @@ static void
 set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
                           GLclampd nearval, GLclampd farval)
 {
+   double scale[3], translate[3];
+
    if (ctx->ViewportArray[idx].Near == nearval &&
        ctx->ViewportArray[idx].Far == farval)
       return;
@@ -261,14 +260,9 @@ set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
     * the WindowMap matrix being up to date in the driver's Viewport
     * and DepthRange functions.
     */
+   _mesa_get_viewport_xform(ctx, idx, scale, translate);
    _math_matrix_viewport(&ctx->ViewportArray[idx]._WindowMap,
-                         ctx->ViewportArray[idx].X,
-                         ctx->ViewportArray[idx].Y,
-                         ctx->ViewportArray[idx].Width,
-                         ctx->ViewportArray[idx].Height,
-                         ctx->ViewportArray[idx].Near,
-                         ctx->ViewportArray[idx].Far,
-                         ctx->DrawBuffer->_DepthMaxF);
+                         scale, translate, ctx->DrawBuffer->_DepthMaxF);
 #endif
 }
 
@@ -400,6 +394,8 @@ void _mesa_init_viewport(struct gl_context *ctx)
     * so just initialize all of them.
     */
    for (i = 0; i < MAX_VIEWPORTS; i++) {
+      double scale[3], translate[3];
+
       /* Viewport group */
       ctx->ViewportArray[i].X = 0;
       ctx->ViewportArray[i].Y = 0;
@@ -409,8 +405,9 @@ void _mesa_init_viewport(struct gl_context *ctx)
       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);
+      _mesa_get_viewport_xform(ctx, i, scale, translate);
+      _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap,
+                            scale, translate, depthMax);
    }
 }
 
@@ -427,3 +424,26 @@ void _mesa_free_viewport_data(struct gl_context *ctx)
       _math_matrix_dtr(&ctx->ViewportArray[i]._WindowMap);
 }
 
+/**
+ * Computes the scaling and the translation part of the
+ * viewport transform matrix of the \param i-th viewport
+ * and writes that into \param scale and \param translate.
+ */
+void
+_mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
+                         double scale[3], double translate[3])
+{
+   double x = ctx->ViewportArray[i].X;
+   double y = ctx->ViewportArray[i].Y;
+   double half_width = 0.5*ctx->ViewportArray[i].Width;
+   double half_height = 0.5*ctx->ViewportArray[i].Height;
+   double n = ctx->ViewportArray[i].Near;
+   double f = ctx->ViewportArray[i].Far;
+
+   scale[0] = half_width;
+   translate[0] = half_width + x;
+   scale[1] = half_height;
+   translate[1] = half_height + y;
+   scale[2] = 0.5*(f - n);
+   translate[2] = 0.5*(n + f);
+}
index f2311c02b4478919ef62c292d2d0b7debb6c1904..514ff1067ff1f5455375067e331f4c4ac99889c8 100644 (file)
@@ -71,5 +71,8 @@ _mesa_init_viewport(struct gl_context *ctx);
 extern void 
 _mesa_free_viewport_data(struct gl_context *ctx);
 
+extern void
+_mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
+                         double scale[3], double translate[3]);
 
 #endif
index e512e456fbd054640f6daca3fd9e8438c5866086..9c9310d939e97d4cc92b9b42269a77a1096a3a55 100644 (file)
@@ -1110,16 +1110,15 @@ _math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z )
  * Transforms Normalized Device Coords to window/Z values.
  */
 void
-_math_matrix_viewport(GLmatrix *m, GLfloat x, GLfloat y,
-                      GLfloat width, GLfloat height,
-                      GLdouble zNear, GLdouble zFar, GLdouble depthMax)
+_math_matrix_viewport(GLmatrix *m, const double scale[3],
+                      const double translate[3], double depthMax)
 {
-   m->m[MAT_SX] = width / 2.0F;
-   m->m[MAT_TX] = m->m[MAT_SX] + x;
-   m->m[MAT_SY] = height / 2.0F;
-   m->m[MAT_TY] = m->m[MAT_SY] + y;
-   m->m[MAT_SZ] = (GLfloat) (depthMax * ((zFar - zNear) / 2.0));
-   m->m[MAT_TZ] = (GLfloat) (depthMax * ((zFar - zNear) / 2.0 + zNear));
+   m->m[MAT_SX] = scale[0];
+   m->m[MAT_TX] = translate[0];
+   m->m[MAT_SY] = scale[1];
+   m->m[MAT_TY] = translate[1];
+   m->m[MAT_SZ] = depthMax*scale[2];
+   m->m[MAT_TZ] = depthMax*translate[2];
    m->flags = MAT_FLAG_GENERAL_SCALE | MAT_FLAG_TRANSLATION;
    m->type = MATRIX_3D_NO_ROT;
 }
index dddce70190fa3e7b830dc4bd29d07e7afce8f540..778d716dce739f663df9ee09daa482c9bee8c0dc 100644 (file)
@@ -122,8 +122,8 @@ _math_matrix_frustum( GLmatrix *mat,
                      GLfloat nearval, GLfloat farval );
 
 extern void
-_math_matrix_viewport(GLmatrix *m, GLfloat x, GLfloat y, GLfloat width, GLfloat height,
-                      GLdouble zNear, GLdouble zFar, GLdouble depthMax);
+_math_matrix_viewport( GLmatrix *m, const double scale[3],
+                       const double translate[3], double depthMax );
 
 extern void
 _math_matrix_set_identity( GLmatrix *dest );
index 7584f9b3d55837e018e36b59c250fc0faffa3b96..5b992084bd5c8ef6951e8cecf69642eb6a73a986 100644 (file)
@@ -27,6 +27,7 @@
 
 
 #include "main/context.h"
+#include "main/viewport.h"
 #include "st_context.h"
 #include "st_atom.h"
 #include "pipe/p_context.h"
@@ -63,21 +64,17 @@ update_viewport( struct st_context *st )
     */
    for (i = 0; i < ctx->Const.MaxViewports; i++)
    {
-      GLfloat x = ctx->ViewportArray[i].X;
-      GLfloat y = ctx->ViewportArray[i].Y;
-      GLfloat z = ctx->ViewportArray[i].Near;
-      GLfloat half_width = ctx->ViewportArray[i].Width * 0.5f;
-      GLfloat half_height = ctx->ViewportArray[i].Height * 0.5f;
-      GLfloat half_depth = (GLfloat)(ctx->ViewportArray[i].Far - ctx->ViewportArray[i].Near) * 0.5f;
-      
-      st->state.viewport[i].scale[0] = half_width;
-      st->state.viewport[i].scale[1] = half_height * yScale;
-      st->state.viewport[i].scale[2] = half_depth;
+      double scale[3], translate[3];
+      _mesa_get_viewport_xform(ctx, i, scale, translate);
+
+      st->state.viewport[i].scale[0] = scale[0];
+      st->state.viewport[i].scale[1] = scale[1] * yScale;
+      st->state.viewport[i].scale[2] = scale[2];
       st->state.viewport[i].scale[3] = 1.0;
 
-      st->state.viewport[i].translate[0] = half_width + x;
-      st->state.viewport[i].translate[1] = (half_height + y) * yScale + yBias;
-      st->state.viewport[i].translate[2] = half_depth + z;
+      st->state.viewport[i].translate[0] = translate[0];
+      st->state.viewport[i].translate[1] = translate[1] * yScale + yBias;
+      st->state.viewport[i].translate[2] = translate[2];
       st->state.viewport[i].translate[3] = 0.0;
    }