From 6340e609a354770e04192b9b44e91fb06aab0159 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathias=20Fr=C3=B6hlich?= Date: Sun, 21 Sep 2014 18:09:21 +0200 Subject: [PATCH] mesa: Refactor viewport transform computation. This is for preparation of ARB_clip_control. v3: Add comments. Reviewed-by: Brian Paul Signed-off-by: Mathias Froehlich --- src/mesa/drivers/dri/i915/i915_state.c | 26 ++++++---------- src/mesa/main/state.c | 9 +++--- src/mesa/main/viewport.c | 52 +++++++++++++++++++++---------- src/mesa/main/viewport.h | 3 ++ src/mesa/math/m_matrix.c | 17 +++++----- src/mesa/math/m_matrix.h | 4 +-- src/mesa/state_tracker/st_atom_viewport.c | 23 ++++++-------- 7 files changed, 73 insertions(+), 61 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index f31b271500f..f9aecba2327 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -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); } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 80287c47062..3dbbfaac76c 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -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); } } diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c index 222ae307b55..afc813dceb7 100644 --- a/src/mesa/main/viewport.c +++ b/src/mesa/main/viewport.c @@ -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); +} diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h index f2311c02b44..514ff1067ff 100644 --- a/src/mesa/main/viewport.h +++ b/src/mesa/main/viewport.h @@ -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 diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c index e512e456fbd..9c9310d939e 100644 --- a/src/mesa/math/m_matrix.c +++ b/src/mesa/math/m_matrix.c @@ -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; } diff --git a/src/mesa/math/m_matrix.h b/src/mesa/math/m_matrix.h index dddce70190f..778d716dce7 100644 --- a/src/mesa/math/m_matrix.h +++ b/src/mesa/math/m_matrix.h @@ -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 ); diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c index 7584f9b3d55..5b992084bd5 100644 --- a/src/mesa/state_tracker/st_atom_viewport.c +++ b/src/mesa/state_tracker/st_atom_viewport.c @@ -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; } -- 2.11.0