diff options
author | David Li <davidxli@google.com> | 2011-02-04 12:25:22 -0800 |
---|---|---|
committer | David Li <davidxli@google.com> | 2011-02-04 12:25:22 -0800 |
commit | f9ad8a790398513a845d486f58566854f7eceee4 (patch) | |
tree | 14d4b8919fe6f854f275dc99a27ec4d18c3fa1ac | |
parent | dae46b97fe53adc7b6c26341dc9d39bf786c8f58 (diff) |
Checkpoint: work on test
Signed-off-by: David Li <davidxli@google.com>
37 files changed, 2405 insertions, 7688 deletions
diff --git a/libMesa.project b/libMesa.project index b8aec92..08a7dd4 100644 --- a/libMesa.project +++ b/libMesa.project @@ -219,8 +219,6 @@ </VirtualDirectory> <Description/> <Dependencies/> - <Dependencies Name="Release"/> - <Dependencies Name="Debug"/> <Settings Type="Static Library"> <Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Static Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append"> <Compiler Options="-g;-D__STDC_LIMIT_MACROS;-D__STDC_CONSTANT_MACROS;-m32 -march=i686;-DDEBUG;-UNDEBUG;-O0" Required="yes" PreCompiledHeader=""> @@ -317,4 +315,6 @@ <ResourceCompiler Options=""/> </GlobalSettings> </Settings> + <Dependencies Name="Debug"/> + <Dependencies Name="Release"/> </CodeLite_Project> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 1f0359c..f727952 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1707,8 +1707,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { - //demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX], - // ir_var_out); for testing, don't demote + demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX], + ir_var_out); } if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { @@ -1722,7 +1722,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; - //demote_shader_inputs_and_outputs(sh, ir_var_in); for testing, don't demote + demote_shader_inputs_and_outputs(sh, ir_var_in); foreach_list(node, sh->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 5614907..573dae2 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -38,7 +38,7 @@ #include "main/config.h" #include "main/mfeatures.h" #include "glapi/glapi.h" -#include "math/m_matrix.h" /* GLmatrix */ +//#include "math/m_matrix.h" /* GLmatrix */ #include "main/simple_list.h" /* struct simple_node */ @@ -1480,13 +1480,13 @@ struct gl_transform_attrib /** * Viewport attribute group (GL_VIEWPORT_BIT). */ -struct gl_viewport_attrib -{ - GLint X, Y; /**< position */ - GLsizei Width, Height; /**< size */ - GLfloat Near, Far; /**< Depth buffer range */ - GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */ -}; +//struct gl_viewport_attrib +//{ +// GLint X, Y; /**< position */ +// GLsizei Width, Height; /**< size */ +// GLfloat Near, Far; /**< Depth buffer range */ +// GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */ +//}; /** @@ -2828,14 +2828,14 @@ struct gl_extensions /** * A stack of matrices (projection, modelview, color, texture, etc). */ -struct gl_matrix_stack -{ - GLmatrix *Top; /**< points into Stack */ - GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */ - GLuint Depth; /**< 0 <= Depth < MaxDepth */ - GLuint MaxDepth; /**< size of Stack[] array */ - GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */ -}; +//struct gl_matrix_stack +//{ +// GLmatrix *Top; /**< points into Stack */ +// GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */ +// GLuint Depth; /**< 0 <= Depth < MaxDepth */ +// GLuint MaxDepth; /**< size of Stack[] array */ +// GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */ +//}; /** diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h deleted file mode 100644 index 2e30964..0000000 --- a/src/mesa/math/m_clip_tmp.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.2 - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -/* KW: a clever asm implementation would nestle integer versions - * of the outcode calculation underneath the division. Gcc won't - * do this, strangely enough, so I only do the divide in - * the case where the cliptest passes. This isn't essential, - * and an asm implementation needn't replicate that behaviour. - * - * \param clip_vec vector of incoming clip-space coords - * \param proj_vec vector of resultant NDC-space projected coords - * \param clipMask resulting array of clip flags - * \param orMask bitwise-OR of clipMask values - * \param andMask bitwise-AND of clipMask values - * \return proj_vec pointer - */ -static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLfloat *from = (GLfloat *)clip_vec->start; - const GLuint count = clip_vec->count; - GLuint c = 0; - GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; - GLubyte tmpAndMask = *andMask; - GLubyte tmpOrMask = *orMask; - GLuint i; - STRIDE_LOOP { - const GLfloat cx = from[0]; - const GLfloat cy = from[1]; - const GLfloat cz = from[2]; - const GLfloat cw = from[3]; -#if defined(macintosh) || defined(__powerpc__) - /* on powerpc cliptest is 17% faster in this way. */ - GLuint mask; - mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); - mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); - mask |= (((cw < cy) << CLIP_TOP_SHIFT)); - mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); - if (viewport_z_clip) { - mask |= (((cw < cz) << CLIP_FAR_SHIFT)); - mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); - } -#else /* !defined(macintosh)) */ - GLubyte mask = 0; - if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; - if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; - if (-cy + cw < 0) mask |= CLIP_TOP_BIT; - if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if (-cz + cw < 0) mask |= CLIP_FAR_BIT; - if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; - } -#endif /* defined(macintosh) */ - - clipMask[i] = mask; - if (mask) { - c++; - tmpAndMask &= mask; - tmpOrMask |= mask; - vProj[i][0] = 0; - vProj[i][1] = 0; - vProj[i][2] = 0; - vProj[i][3] = 1; - } else { - GLfloat oow = 1.0F / cw; - vProj[i][0] = cx * oow; - vProj[i][1] = cy * oow; - vProj[i][2] = cz * oow; - vProj[i][3] = oow; - } - } - - *orMask = tmpOrMask; - *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); - - proj_vec->flags |= VEC_SIZE_4; - proj_vec->size = 4; - proj_vec->count = clip_vec->count; - return proj_vec; -} - - - -/* - * \param clip_vec vector of incoming clip-space coords - * \param proj_vec vector of resultant NDC-space projected coords - * \param clipMask resulting array of clip flags - * \param orMask bitwise-OR of clipMask values - * \param andMask bitwise-AND of clipMask values - * \return clip_vec pointer - */ -static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLuint c = 0; - GLubyte tmpAndMask = *andMask; - GLubyte tmpOrMask = *orMask; - GLuint i; - (void) proj_vec; - STRIDE_LOOP { - const GLfloat cx = from[0]; - const GLfloat cy = from[1]; - const GLfloat cz = from[2]; - const GLfloat cw = from[3]; -#if defined(macintosh) || defined(__powerpc__) - /* on powerpc cliptest is 17% faster in this way. */ - GLuint mask; - mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); - mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); - mask |= (((cw < cy) << CLIP_TOP_SHIFT)); - mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); - if (viewport_z_clip) { - mask |= (((cw < cz) << CLIP_FAR_SHIFT)); - mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); - } -#else /* !defined(macintosh)) */ - GLubyte mask = 0; - if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; - if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; - if (-cy + cw < 0) mask |= CLIP_TOP_BIT; - if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if (-cz + cw < 0) mask |= CLIP_FAR_BIT; - if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; - } -#endif /* defined(macintosh) */ - - clipMask[i] = mask; - if (mask) { - c++; - tmpAndMask &= mask; - tmpOrMask |= mask; - } - } - - *orMask = tmpOrMask; - *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); - return clip_vec; -} - - -static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLubyte tmpOrMask = *orMask; - GLubyte tmpAndMask = *andMask; - GLuint i; - (void) proj_vec; - STRIDE_LOOP { - const GLfloat cx = from[0], cy = from[1], cz = from[2]; - GLubyte mask = 0; - if (cx > 1.0) mask |= CLIP_RIGHT_BIT; - else if (cx < -1.0) mask |= CLIP_LEFT_BIT; - if (cy > 1.0) mask |= CLIP_TOP_BIT; - else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if (cz > 1.0) mask |= CLIP_FAR_BIT; - else if (cz < -1.0) mask |= CLIP_NEAR_BIT; - } - clipMask[i] = mask; - tmpOrMask |= mask; - tmpAndMask &= mask; - } - - *orMask = tmpOrMask; - *andMask = tmpAndMask; - return clip_vec; -} - - -static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLubyte tmpOrMask = *orMask; - GLubyte tmpAndMask = *andMask; - GLuint i; - (void) proj_vec; - STRIDE_LOOP { - const GLfloat cx = from[0], cy = from[1]; - GLubyte mask = 0; - if (cx > 1.0) mask |= CLIP_RIGHT_BIT; - else if (cx < -1.0) mask |= CLIP_LEFT_BIT; - if (cy > 1.0) mask |= CLIP_TOP_BIT; - else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; - clipMask[i] = mask; - tmpOrMask |= mask; - tmpAndMask &= mask; - } - - *orMask = tmpOrMask; - *andMask = tmpAndMask; - return clip_vec; -} - - -void TAG(init_c_cliptest)( void ) -{ - _mesa_clip_tab[4] = TAG(cliptest_points4); - _mesa_clip_tab[3] = TAG(cliptest_points3); - _mesa_clip_tab[2] = TAG(cliptest_points2); - - _mesa_clip_np_tab[4] = TAG(cliptest_np_points4); - _mesa_clip_np_tab[3] = TAG(cliptest_points3); - _mesa_clip_np_tab[2] = TAG(cliptest_points2); -} diff --git a/src/mesa/math/m_copy_tmp.h b/src/mesa/math/m_copy_tmp.h deleted file mode 100644 index 07ab1f7..0000000 --- a/src/mesa/math/m_copy_tmp.h +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -#define COPY_FUNC( BITS ) \ -static void TAG2(copy, BITS)( GLvector4f *to, const GLvector4f *f ) \ -{ \ - GLfloat (*t)[4] = (GLfloat (*)[4])to->start; \ - GLfloat *from = f->start; \ - GLuint stride = f->stride; \ - GLuint count = to->count; \ - GLuint i; \ - \ - if (BITS) \ - STRIDE_LOOP { \ - if (BITS&1) t[i][0] = from[0]; \ - if (BITS&2) t[i][1] = from[1]; \ - if (BITS&4) t[i][2] = from[2]; \ - if (BITS&8) t[i][3] = from[3]; \ - } \ -} - -/* We got them all here: - */ -COPY_FUNC( 0x0 ) /* noop */ -COPY_FUNC( 0x1 ) -COPY_FUNC( 0x2 ) -COPY_FUNC( 0x3 ) -COPY_FUNC( 0x4 ) -COPY_FUNC( 0x5 ) -COPY_FUNC( 0x6 ) -COPY_FUNC( 0x7 ) -COPY_FUNC( 0x8 ) -COPY_FUNC( 0x9 ) -COPY_FUNC( 0xa ) -COPY_FUNC( 0xb ) -COPY_FUNC( 0xc ) -COPY_FUNC( 0xd ) -COPY_FUNC( 0xe ) -COPY_FUNC( 0xf ) - -static void TAG2(init_copy, 0)( void ) -{ - _mesa_copy_tab[0x0] = TAG2(copy, 0x0); - _mesa_copy_tab[0x1] = TAG2(copy, 0x1); - _mesa_copy_tab[0x2] = TAG2(copy, 0x2); - _mesa_copy_tab[0x3] = TAG2(copy, 0x3); - _mesa_copy_tab[0x4] = TAG2(copy, 0x4); - _mesa_copy_tab[0x5] = TAG2(copy, 0x5); - _mesa_copy_tab[0x6] = TAG2(copy, 0x6); - _mesa_copy_tab[0x7] = TAG2(copy, 0x7); - _mesa_copy_tab[0x8] = TAG2(copy, 0x8); - _mesa_copy_tab[0x9] = TAG2(copy, 0x9); - _mesa_copy_tab[0xa] = TAG2(copy, 0xa); - _mesa_copy_tab[0xb] = TAG2(copy, 0xb); - _mesa_copy_tab[0xc] = TAG2(copy, 0xc); - _mesa_copy_tab[0xd] = TAG2(copy, 0xd); - _mesa_copy_tab[0xe] = TAG2(copy, 0xe); - _mesa_copy_tab[0xf] = TAG2(copy, 0xf); -} diff --git a/src/mesa/math/m_debug.h b/src/mesa/math/m_debug.h deleted file mode 100644 index 6476b6d..0000000 --- a/src/mesa/math/m_debug.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#ifndef __M_DEBUG_H__ -#define __M_DEBUG_H__ - -extern void _math_test_all_transform_functions( char *description ); -extern void _math_test_all_normal_transform_functions( char *description ); -extern void _math_test_all_cliptest_functions( char *description ); - -/* Deprecated? - */ -extern void _math_test_all_vertex_functions( char *description ); - -extern char *mesa_profile; - -#endif diff --git a/src/mesa/math/m_debug_clip.c b/src/mesa/math/m_debug_clip.c deleted file mode 100644 index bbad6ef..0000000 --- a/src/mesa/math/m_debug_clip.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "main/imports.h" - -#include "m_matrix.h" -#include "m_xform.h" - -#include "m_debug.h" -#include "m_debug_util.h" - -#ifdef __UNIXOS2__ -/* The linker doesn't like empty files */ -static char dummy; -#endif - -#ifdef DEBUG_MATH /* This code only used for debugging */ - -static clip_func *clip_tab[2] = { - _mesa_clip_tab, - _mesa_clip_np_tab -}; -static char *cnames[2] = { - "_mesa_clip_tab", - "_mesa_clip_np_tab" -}; -#ifdef RUN_DEBUG_BENCHMARK -static char *cstrings[2] = { - "clip, perspective divide", - "clip, no divide" -}; -#endif - - -/* ============================================================= - * Reference cliptests - */ - -static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLuint c = 0; - GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; - GLubyte tmpAndMask = *andMask; - GLubyte tmpOrMask = *orMask; - GLuint i; - for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) { - const GLfloat cx = from[0]; - const GLfloat cy = from[1]; - const GLfloat cz = from[2]; - const GLfloat cw = from[3]; - GLubyte mask = 0; - if ( -cx + cw < 0 ) mask |= CLIP_RIGHT_BIT; - if ( cx + cw < 0 ) mask |= CLIP_LEFT_BIT; - if ( -cy + cw < 0 ) mask |= CLIP_TOP_BIT; - if ( cy + cw < 0 ) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT; - if ( cz + cw < 0 ) mask |= CLIP_NEAR_BIT; - } - clipMask[i] = mask; - if ( mask ) { - c++; - tmpAndMask &= mask; - tmpOrMask |= mask; - vProj[i][0] = 0; - vProj[i][1] = 0; - vProj[i][2] = 0; - vProj[i][3] = 1; - } else { - GLfloat oow = 1.0F / cw; - vProj[i][0] = cx * oow; - vProj[i][1] = cy * oow; - vProj[i][2] = cz * oow; - vProj[i][3] = oow; - } - } - - *orMask = tmpOrMask; - *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); - - proj_vec->flags |= VEC_SIZE_4; - proj_vec->size = 4; - proj_vec->count = clip_vec->count; - return proj_vec; -} - -/* Keep these here for now, even though we don't use them... - */ -static GLvector4f *ref_cliptest_points3( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - - GLubyte tmpOrMask = *orMask; - GLubyte tmpAndMask = *andMask; - GLuint i; - for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) { - const GLfloat cx = from[0], cy = from[1], cz = from[2]; - GLubyte mask = 0; - if ( cx > 1.0 ) mask |= CLIP_RIGHT_BIT; - else if ( cx < -1.0 ) mask |= CLIP_LEFT_BIT; - if ( cy > 1.0 ) mask |= CLIP_TOP_BIT; - else if ( cy < -1.0 ) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if ( cz > 1.0 ) mask |= CLIP_FAR_BIT; - else if ( cz < -1.0 ) mask |= CLIP_NEAR_BIT; - } - clipMask[i] = mask; - tmpOrMask |= mask; - tmpAndMask &= mask; - } - - *orMask = tmpOrMask; - *andMask = tmpAndMask; - return clip_vec; -} - -static GLvector4f * ref_cliptest_points2( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - - GLubyte tmpOrMask = *orMask; - GLubyte tmpAndMask = *andMask; - GLuint i; - - (void) viewport_z_clip; - - for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) { - const GLfloat cx = from[0], cy = from[1]; - GLubyte mask = 0; - if ( cx > 1.0 ) mask |= CLIP_RIGHT_BIT; - else if ( cx < -1.0 ) mask |= CLIP_LEFT_BIT; - if ( cy > 1.0 ) mask |= CLIP_TOP_BIT; - else if ( cy < -1.0 ) mask |= CLIP_BOTTOM_BIT; - clipMask[i] = mask; - tmpOrMask |= mask; - tmpAndMask &= mask; - } - - *orMask = tmpOrMask; - *andMask = tmpAndMask; - return clip_vec; -} - -static clip_func ref_cliptest[5] = { - 0, - 0, - ref_cliptest_points2, - ref_cliptest_points3, - ref_cliptest_points4 -}; - - -/* ============================================================= - * Cliptest tests - */ - -ALIGN16(static GLfloat, s[TEST_COUNT][4]); -ALIGN16(static GLfloat, d[TEST_COUNT][4]); -ALIGN16(static GLfloat, r[TEST_COUNT][4]); - - -/** - * Check if X, Y or Z component of the coordinate is close to W, in terms - * of the clip test. - */ -static GLboolean -xyz_close_to_w(const GLfloat c[4]) -{ - float k = 0.0001; - return (fabs(c[0] - c[3]) < k || - fabs(c[1] - c[3]) < k || - fabs(c[2] - c[3]) < k || - fabs(-c[0] - c[3]) < k || - fabs(-c[1] - c[3]) < k || - fabs(-c[2] - c[3]) < k); -} - - - -static int test_cliptest_function( clip_func func, int np, - int psize, long *cycles ) -{ - GLvector4f source[1], dest[1], ref[1]; - GLubyte dm[TEST_COUNT], dco, dca; - GLubyte rm[TEST_COUNT], rco, rca; - int i, j; -#ifdef RUN_DEBUG_BENCHMARK - int cycle_i; /* the counter for the benchmarks we run */ -#endif - GLboolean viewport_z_clip = GL_TRUE; - - (void) cycles; - - if ( psize > 4 ) { - _mesa_problem( NULL, "test_cliptest_function called with psize > 4\n" ); - return 0; - } - - for ( i = 0 ; i < TEST_COUNT ; i++) { - ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 ); - ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 ); - for ( j = 0 ; j < psize ; j++ ) - s[i][j] = rnd(); - } - - source->data = (GLfloat(*)[4])s; - source->start = (GLfloat *)s; - source->count = TEST_COUNT; - source->stride = sizeof(s[0]); - source->size = 4; - source->flags = 0; - - dest->data = (GLfloat(*)[4])d; - dest->start = (GLfloat *)d; - dest->count = TEST_COUNT; - dest->stride = sizeof(float[4]); - dest->size = 0; - dest->flags = 0; - - ref->data = (GLfloat(*)[4])r; - ref->start = (GLfloat *)r; - ref->count = TEST_COUNT; - ref->stride = sizeof(float[4]); - ref->size = 0; - ref->flags = 0; - - dco = rco = 0; - dca = rca = CLIP_FRUSTUM_BITS; - - ref_cliptest[psize]( source, ref, rm, &rco, &rca, viewport_z_clip ); - - if ( mesa_profile ) { - BEGIN_RACE( *cycles ); - func( source, dest, dm, &dco, &dca, viewport_z_clip ); - END_RACE( *cycles ); - } - else { - func( source, dest, dm, &dco, &dca, viewport_z_clip ); - } - - if ( dco != rco ) { - printf( "\n-----------------------------\n" ); - printf( "dco = 0x%02x rco = 0x%02x\n", dco, rco ); - return 0; - } - if ( dca != rca ) { - printf( "\n-----------------------------\n" ); - printf( "dca = 0x%02x rca = 0x%02x\n", dca, rca ); - return 0; - } - for ( i = 0 ; i < TEST_COUNT ; i++ ) { - if ( dm[i] != rm[i] ) { - GLfloat *c = source->start; - STRIDE_F(c, source->stride * i); - if (psize == 4 && xyz_close_to_w(c)) { - /* The coordinate is very close to the clip plane. The clipmask - * may vary depending on code path, but that's OK. - */ - continue; - } - printf( "\n-----------------------------\n" ); - printf( "mask[%d] = 0x%02x ref mask[%d] = 0x%02x\n", i, dm[i], i,rm[i] ); - printf(" coord = %f, %f, %f, %f\n", - c[0], c[1], c[2], c[3]); - return 0; - } - } - - /* Only verify output on projected points4 case. FIXME: Do we need - * to test other cases? - */ - if ( np || psize < 4 ) - return 1; - - for ( i = 0 ; i < TEST_COUNT ; i++ ) { - for ( j = 0 ; j < 4 ; j++ ) { - if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { - printf( "\n-----------------------------\n" ); - printf( "(i = %i, j = %i) dm = 0x%02x rm = 0x%02x\n", - i, j, dm[i], rm[i] ); - printf( "%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][0], r[i][0], r[i][0]-d[i][0], - MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); - printf( "%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][1], r[i][1], r[i][1]-d[i][1], - MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); - printf( "%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][2], r[i][2], r[i][2]-d[i][2], - MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); - printf( "%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][3], r[i][3], r[i][3]-d[i][3], - MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); - return 0; - } - } - } - - return 1; -} - -void _math_test_all_cliptest_functions( char *description ) -{ - int np, psize; - long benchmark_tab[2][4]; - static int first_time = 1; - - if ( first_time ) { - first_time = 0; - mesa_profile = _mesa_getenv( "MESA_PROFILE" ); - } - -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - if ( !counter_overhead ) { - INIT_COUNTER(); - printf( "counter overhead: %ld cycles\n\n", counter_overhead ); - } - printf( "cliptest results after hooking in %s functions:\n", description ); - } -#endif - -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - printf( "\n\t" ); - for ( psize = 2 ; psize <= 4 ; psize++ ) { - printf( " p%d\t", psize ); - } - printf( "\n--------------------------------------------------------\n\t" ); - } -#endif - - for ( np = 0 ; np < 2 ; np++ ) { - for ( psize = 2 ; psize <= 4 ; psize++ ) { - clip_func func = clip_tab[np][psize]; - long *cycles = &(benchmark_tab[np][psize-1]); - - if ( test_cliptest_function( func, np, psize, cycles ) == 0 ) { - char buf[100]; - sprintf( buf, "%s[%d] failed test (%s)", - cnames[np], psize, description ); - _mesa_problem( NULL, "%s", buf ); - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) - printf( " %li\t", benchmark_tab[np][psize-1] ); -#endif - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) - printf( " | [%s]\n\t", cstrings[np] ); -#endif - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) - printf( "\n" ); -#endif -} - - -#endif /* DEBUG_MATH */ diff --git a/src/mesa/math/m_debug_norm.c b/src/mesa/math/m_debug_norm.c deleted file mode 100644 index 02eb1f9..0000000 --- a/src/mesa/math/m_debug_norm.c +++ /dev/null @@ -1,383 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "main/imports.h" - -#include "m_matrix.h" -#include "m_xform.h" - -#include "m_debug.h" -#include "m_debug_util.h" - - -#ifdef __UNIXOS2__ -/* The linker doesn't like empty files */ -static char dummy; -#endif - -#ifdef DEBUG_MATH /* This code only used for debugging */ - - -static int m_norm_identity[16] = { - ONE, NIL, NIL, NIL, - NIL, ONE, NIL, NIL, - NIL, NIL, ONE, NIL, - NIL, NIL, NIL, NIL -}; -static int m_norm_general[16] = { - VAR, VAR, VAR, NIL, - VAR, VAR, VAR, NIL, - VAR, VAR, VAR, NIL, - NIL, NIL, NIL, NIL -}; -static int m_norm_no_rot[16] = { - VAR, NIL, NIL, NIL, - NIL, VAR, NIL, NIL, - NIL, NIL, VAR, NIL, - NIL, NIL, NIL, NIL -}; -static int *norm_templates[8] = { - m_norm_no_rot, - m_norm_no_rot, - m_norm_no_rot, - m_norm_general, - m_norm_general, - m_norm_general, - m_norm_identity, - m_norm_identity -}; -static int norm_types[8] = { - NORM_TRANSFORM_NO_ROT, - NORM_TRANSFORM_NO_ROT | NORM_RESCALE, - NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE, - NORM_TRANSFORM, - NORM_TRANSFORM | NORM_RESCALE, - NORM_TRANSFORM | NORM_NORMALIZE, - NORM_RESCALE, - NORM_NORMALIZE -}; -static int norm_scale_types[8] = { /* rescale factor */ - NIL, /* NIL disables rescaling */ - VAR, - NIL, - NIL, - VAR, - NIL, - VAR, - NIL -}; -static int norm_normalize_types[8] = { /* normalizing ?? (no = 0) */ - 0, - 0, - 1, - 0, - 0, - 1, - 0, - 1 -}; -static char *norm_strings[8] = { - "NORM_TRANSFORM_NO_ROT", - "NORM_TRANSFORM_NO_ROT | NORM_RESCALE", - "NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE", - "NORM_TRANSFORM", - "NORM_TRANSFORM | NORM_RESCALE", - "NORM_TRANSFORM | NORM_NORMALIZE", - "NORM_RESCALE", - "NORM_NORMALIZE" -}; - - -/* ============================================================= - * Reference transformations - */ - -static void ref_norm_transform_rescale( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLuint i; - const GLfloat *s = in->start; - const GLfloat *m = mat->inv; - GLfloat (*out)[4] = (GLfloat (*)[4]) dest->start; - - (void) lengths; - - for ( i = 0 ; i < in->count ; i++ ) { - GLfloat t[3]; - - TRANSFORM_NORMAL( t, s, m ); - SCALE_SCALAR_3V( out[i], scale, t ); - - s = (GLfloat *)((char *)s + in->stride); - } -} - -static void ref_norm_transform_normalize( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLuint i; - const GLfloat *s = in->start; - const GLfloat *m = mat->inv; - GLfloat (*out)[4] = (GLfloat (*)[4]) dest->start; - - for ( i = 0 ; i < in->count ; i++ ) { - GLfloat t[3]; - - TRANSFORM_NORMAL( t, s, m ); - - if ( !lengths ) { - GLfloat len = LEN_SQUARED_3FV( t ); - if ( len > 1e-20 ) { - /* Hmmm, don't know how we could test the precalculated - * length case... - */ - scale = 1.0 / SQRTF( len ); - SCALE_SCALAR_3V( out[i], scale, t ); - } else { - out[i][0] = out[i][1] = out[i][2] = 0; - } - } else { - scale = lengths[i];; - SCALE_SCALAR_3V( out[i], scale, t ); - } - - s = (GLfloat *)((char *)s + in->stride); - } -} - - -/* ============================================================= - * Normal transformation tests - */ - -static void init_matrix( GLfloat *m ) -{ - m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; - m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; - m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; - m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; -} - - -static int test_norm_function( normal_func func, int mtype, long *cycles ) -{ - GLvector4f source[1], dest[1], dest2[1], ref[1], ref2[1]; - GLmatrix mat[1]; - GLfloat s[TEST_COUNT][5], d[TEST_COUNT][4], r[TEST_COUNT][4]; - GLfloat d2[TEST_COUNT][4], r2[TEST_COUNT][4], length[TEST_COUNT]; - GLfloat scale; - GLfloat *m; - int i, j; -#ifdef RUN_DEBUG_BENCHMARK - int cycle_i; /* the counter for the benchmarks we run */ -#endif - - (void) cycles; - - mat->m = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 ); - mat->inv = m = mat->m; - - init_matrix( m ); - - scale = 1.0F + rnd () * norm_scale_types[mtype]; - - for ( i = 0 ; i < 4 ; i++ ) { - for ( j = 0 ; j < 4 ; j++ ) { - switch ( norm_templates[mtype][i * 4 + j] ) { - case NIL: - m[j * 4 + i] = 0.0; - break; - case ONE: - m[j * 4 + i] = 1.0; - break; - case NEG: - m[j * 4 + i] = -1.0; - break; - case VAR: - break; - default: - exit(1); - } - } - } - - for ( i = 0 ; i < TEST_COUNT ; i++ ) { - ASSIGN_3V( d[i], 0.0, 0.0, 0.0 ); - ASSIGN_3V( s[i], 0.0, 0.0, 0.0 ); - ASSIGN_3V( d2[i], 0.0, 0.0, 0.0 ); - for ( j = 0 ; j < 3 ; j++ ) - s[i][j] = rnd(); - length[i] = 1 / SQRTF( LEN_SQUARED_3FV( s[i] ) ); - } - - source->data = (GLfloat(*)[4]) s; - source->start = (GLfloat *) s; - source->count = TEST_COUNT; - source->stride = sizeof(s[0]); - source->flags = 0; - - dest->data = d; - dest->start = (GLfloat *) d; - dest->count = TEST_COUNT; - dest->stride = sizeof(float[4]); - dest->flags = 0; - - dest2->data = d2; - dest2->start = (GLfloat *) d2; - dest2->count = TEST_COUNT; - dest2->stride = sizeof(float[4]); - dest2->flags = 0; - - ref->data = r; - ref->start = (GLfloat *) r; - ref->count = TEST_COUNT; - ref->stride = sizeof(float[4]); - ref->flags = 0; - - ref2->data = r2; - ref2->start = (GLfloat *) r2; - ref2->count = TEST_COUNT; - ref2->stride = sizeof(float[4]); - ref2->flags = 0; - - if ( norm_normalize_types[mtype] == 0 ) { - ref_norm_transform_rescale( mat, scale, source, NULL, ref ); - } else { - ref_norm_transform_normalize( mat, scale, source, NULL, ref ); - ref_norm_transform_normalize( mat, scale, source, length, ref2 ); - } - - if ( mesa_profile ) { - BEGIN_RACE( *cycles ); - func( mat, scale, source, NULL, dest ); - END_RACE( *cycles ); - func( mat, scale, source, length, dest2 ); - } else { - func( mat, scale, source, NULL, dest ); - func( mat, scale, source, length, dest2 ); - } - - for ( i = 0 ; i < TEST_COUNT ; i++ ) { - for ( j = 0 ; j < 3 ; j++ ) { - if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { - printf( "-----------------------------\n" ); - printf( "(i = %i, j = %i)\n", i, j ); - printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", - d[i][0], r[i][0], r[i][0]/d[i][0], - MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); - printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", - d[i][1], r[i][1], r[i][1]/d[i][1], - MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); - printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", - d[i][2], r[i][2], r[i][2]/d[i][2], - MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); - return 0; - } - - if ( norm_normalize_types[mtype] != 0 ) { - if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) { - printf( "------------------- precalculated length case ------\n" ); - printf( "(i = %i, j = %i)\n", i, j ); - printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", - d2[i][0], r2[i][0], r2[i][0]/d2[i][0], - MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) ); - printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", - d2[i][1], r2[i][1], r2[i][1]/d2[i][1], - MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) ); - printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", - d2[i][2], r2[i][2], r2[i][2]/d2[i][2], - MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) ); - return 0; - } - } - } - } - - _mesa_align_free( mat->m ); - return 1; -} - -void _math_test_all_normal_transform_functions( char *description ) -{ - int mtype; - long benchmark_tab[0xf]; - static int first_time = 1; - - if ( first_time ) { - first_time = 0; - mesa_profile = _mesa_getenv( "MESA_PROFILE" ); - } - -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - if ( !counter_overhead ) { - INIT_COUNTER(); - printf( "counter overhead: %ld cycles\n\n", counter_overhead ); - } - printf( "normal transform results after hooking in %s functions:\n", - description ); - printf( "\n-------------------------------------------------------\n" ); - } -#endif - - for ( mtype = 0 ; mtype < 8 ; mtype++ ) { - normal_func func = _mesa_normal_tab[norm_types[mtype]]; - long *cycles = &benchmark_tab[mtype]; - - if ( test_norm_function( func, mtype, cycles ) == 0 ) { - char buf[100]; - sprintf( buf, "_mesa_normal_tab[0][%s] failed test (%s)", - norm_strings[mtype], description ); - _mesa_problem( NULL, "%s", buf ); - } - -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - printf( " %li\t", benchmark_tab[mtype] ); - printf( " | [%s]\n", norm_strings[mtype] ); - } -#endif - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - printf( "\n" ); - } -#endif -} - - -#endif /* DEBUG_MATH */ diff --git a/src/mesa/math/m_debug_util.h b/src/mesa/math/m_debug_util.h deleted file mode 100644 index ed11c84..0000000 --- a/src/mesa/math/m_debug_util.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#ifndef __M_DEBUG_UTIL_H__ -#define __M_DEBUG_UTIL_H__ - - -#ifdef DEBUG_MATH /* This code only used for debugging */ - - -/* Comment this out to deactivate the cycle counter. - * NOTE: it works only on CPUs which know the 'rdtsc' command (586 or higher) - * (hope, you don't try to debug Mesa on a 386 ;) - */ -#if defined(__GNUC__) && \ - ((defined(__i386__) && defined(USE_X86_ASM)) || \ - (defined(__sparc__) && defined(USE_SPARC_ASM))) -#define RUN_DEBUG_BENCHMARK -#endif - -#define TEST_COUNT 128 /* size of the tested vector array */ - -#define REQUIRED_PRECISION 10 /* allow 4 bits to miss */ -#define MAX_PRECISION 24 /* max. precision possible */ - - -#ifdef RUN_DEBUG_BENCHMARK -/* Overhead of profiling counter in cycles. Automatically adjusted to - * your machine at run time - counter initialization should give very - * consistent results. - */ -extern long counter_overhead; - -/* This is the value of the environment variable MESA_PROFILE, and is - * used to determine if we should benchmark the functions as well as - * verify their correctness. - */ -extern char *mesa_profile; - -/* Modify the number of tests if you like. - * We take the minimum of all results, because every error should be - * positive (time used by other processes, task switches etc). - * It is assumed that all calculations are done in the cache. - */ - -#if defined(__i386__) - -#if 1 /* PPro, PII, PIII version */ - -/* Profiling on the P6 architecture requires a little more work, due to - * the internal out-of-order execution. We must perform a serializing - * 'cpuid' instruction before and after the 'rdtsc' instructions to make - * sure no other uops are executed when we sample the timestamp counter. - */ -#define INIT_COUNTER() \ - do { \ - int cycle_i; \ - counter_overhead = LONG_MAX; \ - for ( cycle_i = 0 ; cycle_i < 8 ; cycle_i++ ) { \ - long cycle_tmp1 = 0, cycle_tmp2 = 0; \ - __asm__ __volatile__ ( "push %%ebx \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "rdtsc \n" \ - "mov %%eax, %0 \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "pop %%ebx \n" \ - "push %%ebx \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "rdtsc \n" \ - "mov %%eax, %1 \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "pop %%ebx \n" \ - : "=m" (cycle_tmp1), "=m" (cycle_tmp2) \ - : : "eax", "ecx", "edx" ); \ - if ( counter_overhead > (cycle_tmp2 - cycle_tmp1) ) { \ - counter_overhead = cycle_tmp2 - cycle_tmp1; \ - } \ - } \ - } while (0) - -#define BEGIN_RACE(x) \ - x = LONG_MAX; \ - for ( cycle_i = 0 ; cycle_i < 10 ; cycle_i++ ) { \ - long cycle_tmp1 = 0, cycle_tmp2 = 0; \ - __asm__ __volatile__ ( "push %%ebx \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "rdtsc \n" \ - "mov %%eax, %0 \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "pop %%ebx \n" \ - : "=m" (cycle_tmp1) \ - : : "eax", "ecx", "edx" ); - -#define END_RACE(x) \ - __asm__ __volatile__ ( "push %%ebx \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "rdtsc \n" \ - "mov %%eax, %0 \n" \ - "xor %%eax, %%eax \n" \ - "cpuid \n" \ - "pop %%ebx \n" \ - : "=m" (cycle_tmp2) \ - : : "eax", "ecx", "edx" ); \ - if ( x > (cycle_tmp2 - cycle_tmp1) ) { \ - x = cycle_tmp2 - cycle_tmp1; \ - } \ - } \ - x -= counter_overhead; - -#else /* PPlain, PMMX version */ - -/* To ensure accurate results, we stall the pipelines with the - * non-pairable 'cdq' instruction. This ensures all the code being - * profiled is complete when the 'rdtsc' instruction executes. - */ -#define INIT_COUNTER(x) \ - do { \ - int cycle_i; \ - x = LONG_MAX; \ - for ( cycle_i = 0 ; cycle_i < 32 ; cycle_i++ ) { \ - long cycle_tmp1, cycle_tmp2, dummy; \ - __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) ); \ - __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) ); \ - if ( x > (cycle_tmp2 - cycle_tmp1) ) \ - x = cycle_tmp2 - cycle_tmp1; \ - } \ - } while (0) - -#define BEGIN_RACE(x) \ - x = LONG_MAX; \ - for ( cycle_i = 0 ; cycle_i < 16 ; cycle_i++ ) { \ - long cycle_tmp1, cycle_tmp2, dummy; \ - __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) ); \ - __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) ); - - -#define END_RACE(x) \ - __asm__ ( "cdq" ); \ - __asm__ ( "cdq" ); \ - __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) ); \ - if ( x > (cycle_tmp2 - cycle_tmp1) ) \ - x = cycle_tmp2 - cycle_tmp1; \ - } \ - x -= counter_overhead; - -#endif - -#elif defined(__x86_64__) - -#define rdtscll(val) do { \ - unsigned int a,d; \ - __asm__ volatile("rdtsc" : "=a" (a), "=d" (d)); \ - (val) = ((unsigned long)a) | (((unsigned long)d)<<32); \ -} while(0) - -/* Copied from i386 PIII version */ -#define INIT_COUNTER() \ - do { \ - int cycle_i; \ - counter_overhead = LONG_MAX; \ - for ( cycle_i = 0 ; cycle_i < 16 ; cycle_i++ ) { \ - unsigned long cycle_tmp1, cycle_tmp2; \ - rdtscll(cycle_tmp1); \ - rdtscll(cycle_tmp2); \ - if ( counter_overhead > (cycle_tmp2 - cycle_tmp1) ) { \ - counter_overhead = cycle_tmp2 - cycle_tmp1; \ - } \ - } \ - } while (0) - - -#define BEGIN_RACE(x) \ - x = LONG_MAX; \ - for ( cycle_i = 0 ; cycle_i < 10 ; cycle_i++ ) { \ - unsigned long cycle_tmp1, cycle_tmp2; \ - rdtscll(cycle_tmp1); \ - -#define END_RACE(x) \ - rdtscll(cycle_tmp2); \ - if ( x > (cycle_tmp2 - cycle_tmp1) ) { \ - x = cycle_tmp2 - cycle_tmp1; \ - } \ - } \ - x -= counter_overhead; - -#elif defined(__sparc__) - -#define INIT_COUNTER() \ - do { counter_overhead = 5; } while(0) - -#define BEGIN_RACE(x) \ -x = LONG_MAX; \ -for (cycle_i = 0; cycle_i <10; cycle_i++) { \ - register long cycle_tmp1 __asm__("l0"); \ - register long cycle_tmp2 __asm__("l1"); \ - /* rd %tick, %l0 */ \ - __asm__ __volatile__ (".word 0xa1410000" : "=r" (cycle_tmp1)); /* save timestamp */ - -#define END_RACE(x) \ - /* rd %tick, %l1 */ \ - __asm__ __volatile__ (".word 0xa3410000" : "=r" (cycle_tmp2)); \ - if (x > (cycle_tmp2-cycle_tmp1)) x = cycle_tmp2 - cycle_tmp1; \ -} \ -x -= counter_overhead; - -#else -#error Your processor is not supported for RUN_XFORM_BENCHMARK -#endif - -#else - -#define BEGIN_RACE(x) -#define END_RACE(x) - -#endif - - -/* ============================================================= - * Helper functions - */ - -static GLfloat rnd( void ) -{ - GLfloat f = (GLfloat)rand() / (GLfloat)RAND_MAX; - GLfloat gran = (GLfloat)(1 << 13); - - f = (GLfloat)(GLint)(f * gran) / gran; - - return f * 2.0 - 1.0; -} - -static int significand_match( GLfloat a, GLfloat b ) -{ - GLfloat d = a - b; - int a_ex, b_ex, d_ex; - - if ( d == 0.0F ) { - return MAX_PRECISION; /* Exact match */ - } - - if ( a == 0.0F || b == 0.0F ) { - /* It would probably be better to check if the - * non-zero number is denormalized and return - * the index of the highest set bit here. - */ - return 0; - } - - FREXPF( a, &a_ex ); - FREXPF( b, &b_ex ); - FREXPF( d, &d_ex ); - - if ( a_ex < b_ex ) { - return a_ex - d_ex; - } else { - return b_ex - d_ex; - } -} - -enum { NIL = 0, ONE = 1, NEG = -1, VAR = 2 }; - -/* Ensure our arrays are correctly aligned. - */ -#if defined(__GNUC__) -# define ALIGN16(type, array) type array __attribute__ ((aligned (16))) -#elif defined(_MSC_VER) -# define ALIGN16(type, array) type array __declspec(align(16)) /* GH: Does this work? */ -#elif defined(__WATCOMC__) -# define ALIGN16(type, array) /* Watcom does not support this */ -#elif defined(__xlC__) -# define ALIGN16(type, array) type __align (16) array -#else -# warning "ALIGN16 will not 16-byte align!\n" -# define ALIGN16 -#endif - - -#endif /* DEBUG_MATH */ - -#endif /* __M_DEBUG_UTIL_H__ */ diff --git a/src/mesa/math/m_debug_xform.c b/src/mesa/math/m_debug_xform.c deleted file mode 100644 index 7d81566..0000000 --- a/src/mesa/math/m_debug_xform.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Updated for P6 architecture by Gareth Hughes. - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "main/imports.h" - -#include "m_matrix.h" -#include "m_xform.h" - -#include "m_debug.h" -#include "m_debug_util.h" - -#ifdef __UNIXOS2__ -/* The linker doesn't like empty files */ -static char dummy; -#endif - -#ifdef DEBUG_MATH /* This code only used for debugging */ - - -/* Overhead of profiling counter in cycles. Automatically adjusted to - * your machine at run time - counter initialization should give very - * consistent results. - */ -long counter_overhead = 0; - -/* This is the value of the environment variable MESA_PROFILE, and is - * used to determine if we should benchmark the functions as well as - * verify their correctness. - */ -char *mesa_profile = NULL; - - -static int m_general[16] = { - VAR, VAR, VAR, VAR, - VAR, VAR, VAR, VAR, - VAR, VAR, VAR, VAR, - VAR, VAR, VAR, VAR -}; -static int m_identity[16] = { - ONE, NIL, NIL, NIL, - NIL, ONE, NIL, NIL, - NIL, NIL, ONE, NIL, - NIL, NIL, NIL, ONE -}; -static int m_2d[16] = { - VAR, VAR, NIL, VAR, - VAR, VAR, NIL, VAR, - NIL, NIL, ONE, NIL, - NIL, NIL, NIL, ONE -}; -static int m_2d_no_rot[16] = { - VAR, NIL, NIL, VAR, - NIL, VAR, NIL, VAR, - NIL, NIL, ONE, NIL, - NIL, NIL, NIL, ONE -}; -static int m_3d[16] = { - VAR, VAR, VAR, VAR, - VAR, VAR, VAR, VAR, - VAR, VAR, VAR, VAR, - NIL, NIL, NIL, ONE -}; -static int m_3d_no_rot[16] = { - VAR, NIL, NIL, VAR, - NIL, VAR, NIL, VAR, - NIL, NIL, VAR, VAR, - NIL, NIL, NIL, ONE -}; -static int m_perspective[16] = { - VAR, NIL, VAR, NIL, - NIL, VAR, VAR, NIL, - NIL, NIL, VAR, VAR, - NIL, NIL, NEG, NIL -}; -static int *templates[7] = { - m_general, - m_identity, - m_3d_no_rot, - m_perspective, - m_2d, - m_2d_no_rot, - m_3d -}; -static enum GLmatrixtype mtypes[7] = { - MATRIX_GENERAL, - MATRIX_IDENTITY, - MATRIX_3D_NO_ROT, - MATRIX_PERSPECTIVE, - MATRIX_2D, - MATRIX_2D_NO_ROT, - MATRIX_3D -}; -static char *mstrings[7] = { - "MATRIX_GENERAL", - "MATRIX_IDENTITY", - "MATRIX_3D_NO_ROT", - "MATRIX_PERSPECTIVE", - "MATRIX_2D", - "MATRIX_2D_NO_ROT", - "MATRIX_3D" -}; - - -/* ============================================================= - * Reference transformations - */ - -static void ref_transform( GLvector4f *dst, - const GLmatrix *mat, - const GLvector4f *src ) -{ - GLuint i; - GLfloat *s = (GLfloat *)src->start; - GLfloat (*d)[4] = (GLfloat (*)[4])dst->start; - const GLfloat *m = mat->m; - - for ( i = 0 ; i < src->count ; i++ ) { - TRANSFORM_POINT( d[i], m, s ); - s = (GLfloat *)((char *)s + src->stride); - } -} - - -/* ============================================================= - * Vertex transformation tests - */ - -static void init_matrix( GLfloat *m ) -{ - m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; - m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; - m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; - m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; -} - -ALIGN16(static GLfloat, s[TEST_COUNT][4]); -ALIGN16(static GLfloat, d[TEST_COUNT][4]); -ALIGN16(static GLfloat, r[TEST_COUNT][4]); - -static int test_transform_function( transform_func func, int psize, - int mtype, unsigned long *cycles ) -{ - GLvector4f source[1], dest[1], ref[1]; - GLmatrix mat[1]; - GLfloat *m; - int i, j; -#ifdef RUN_DEBUG_BENCHMARK - int cycle_i; /* the counter for the benchmarks we run */ -#endif - - (void) cycles; - - if ( psize > 4 ) { - _mesa_problem( NULL, "test_transform_function called with psize > 4\n" ); - return 0; - } - - mat->m = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 ); - mat->type = mtypes[mtype]; - - m = mat->m; - ASSERT( ((long)m & 15) == 0 ); - - init_matrix( m ); - - for ( i = 0 ; i < 4 ; i++ ) { - for ( j = 0 ; j < 4 ; j++ ) { - switch ( templates[mtype][i * 4 + j] ) { - case NIL: - m[j * 4 + i] = 0.0; - break; - case ONE: - m[j * 4 + i] = 1.0; - break; - case NEG: - m[j * 4 + i] = -1.0; - break; - case VAR: - break; - default: - ASSERT(0); - return 0; - } - } - } - - for ( i = 0 ; i < TEST_COUNT ; i++) { - ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 ); - ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 ); - for ( j = 0 ; j < psize ; j++ ) - s[i][j] = rnd(); - } - - source->data = (GLfloat(*)[4])s; - source->start = (GLfloat *)s; - source->count = TEST_COUNT; - source->stride = sizeof(s[0]); - source->size = 4; - source->flags = 0; - - dest->data = (GLfloat(*)[4])d; - dest->start = (GLfloat *)d; - dest->count = TEST_COUNT; - dest->stride = sizeof(float[4]); - dest->size = 0; - dest->flags = 0; - - ref->data = (GLfloat(*)[4])r; - ref->start = (GLfloat *)r; - ref->count = TEST_COUNT; - ref->stride = sizeof(float[4]); - ref->size = 0; - ref->flags = 0; - - ref_transform( ref, mat, source ); - - if ( mesa_profile ) { - BEGIN_RACE( *cycles ); - func( dest, mat->m, source ); - END_RACE( *cycles ); - } - else { - func( dest, mat->m, source ); - } - - for ( i = 0 ; i < TEST_COUNT ; i++ ) { - for ( j = 0 ; j < 4 ; j++ ) { - if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { - printf("-----------------------------\n" ); - printf("(i = %i, j = %i)\n", i, j ); - printf("%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][0], r[i][0], r[i][0]-d[i][0], - MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); - printf("%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][1], r[i][1], r[i][1]-d[i][1], - MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); - printf("%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][2], r[i][2], r[i][2]-d[i][2], - MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); - printf("%f \t %f \t [diff = %e - %i bit missed]\n", - d[i][3], r[i][3], r[i][3]-d[i][3], - MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); - return 0; - } - } - } - - _mesa_align_free( mat->m ); - return 1; -} - -void _math_test_all_transform_functions( char *description ) -{ - int psize, mtype; - unsigned long benchmark_tab[4][7]; - static int first_time = 1; - - if ( first_time ) { - first_time = 0; - mesa_profile = _mesa_getenv( "MESA_PROFILE" ); - } - -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - if ( !counter_overhead ) { - INIT_COUNTER(); - printf("counter overhead: %lu cycles\n\n", counter_overhead ); - } - printf("transform results after hooking in %s functions:\n", description ); - } -#endif - -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) { - printf("\n" ); - for ( psize = 1 ; psize <= 4 ; psize++ ) { - printf(" p%d\t", psize ); - } - printf("\n--------------------------------------------------------\n" ); - } -#endif - - for ( mtype = 0 ; mtype < 7 ; mtype++ ) { - for ( psize = 1 ; psize <= 4 ; psize++ ) { - transform_func func = _mesa_transform_tab[psize][mtypes[mtype]]; - unsigned long *cycles = &(benchmark_tab[psize-1][mtype]); - - if ( test_transform_function( func, psize, mtype, cycles ) == 0 ) { - char buf[100]; - sprintf(buf, "_mesa_transform_tab[0][%d][%s] failed test (%s)", - psize, mstrings[mtype], description ); - _mesa_problem( NULL, "%s", buf ); - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) - printf(" %li\t", benchmark_tab[psize-1][mtype] ); -#endif - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) - printf(" | [%s]\n", mstrings[mtype] ); -#endif - } -#ifdef RUN_DEBUG_BENCHMARK - if ( mesa_profile ) - printf( "\n" ); -#endif -} - - -#endif /* DEBUG_MATH */ diff --git a/src/mesa/math/m_dotprod_tmp.h b/src/mesa/math/m_dotprod_tmp.h deleted file mode 100644 index 03e65af..0000000 --- a/src/mesa/math/m_dotprod_tmp.h +++ /dev/null @@ -1,102 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -/* Note - respects the stride of the output vector. - */ -static void TAG(dotprod_vec2)( GLfloat *out, - GLuint outstride, - const GLvector4f *coord_vec, - const GLfloat plane[4] ) -{ - GLuint stride = coord_vec->stride; - GLfloat *coord = coord_vec->start; - GLuint count = coord_vec->count; - - GLuint i; - - const GLfloat plane0 = plane[0], plane1 = plane[1], plane3 = plane[3]; - - for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { - *out = (coord[0] * plane0 + - coord[1] * plane1 + - plane3); - } -} - -static void TAG(dotprod_vec3)( GLfloat *out, - GLuint outstride, - const GLvector4f *coord_vec, - const GLfloat plane[4] ) -{ - GLuint stride = coord_vec->stride; - GLfloat *coord = coord_vec->start; - GLuint count = coord_vec->count; - - GLuint i; - - const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; - const GLfloat plane3 = plane[3]; - - for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { - *out = (coord[0] * plane0 + - coord[1] * plane1 + - coord[2] * plane2 + - plane3); - } -} - -static void TAG(dotprod_vec4)( GLfloat *out, - GLuint outstride, - const GLvector4f *coord_vec, - const GLfloat plane[4] ) -{ - GLuint stride = coord_vec->stride; - GLfloat *coord = coord_vec->start; - GLuint count = coord_vec->count; - GLuint i; - - const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; - const GLfloat plane3 = plane[3]; - - for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(out,outstride)) { - *out = (coord[0] * plane0 + - coord[1] * plane1 + - coord[2] * plane2 + - coord[3] * plane3); - } -} - - -static void TAG(init_dotprod)( void ) -{ - _mesa_dotprod_tab[2] = TAG(dotprod_vec2); - _mesa_dotprod_tab[3] = TAG(dotprod_vec3); - _mesa_dotprod_tab[4] = TAG(dotprod_vec4); -} diff --git a/src/mesa/math/m_eval.c b/src/mesa/math/m_eval.c deleted file mode 100644 index d324673..0000000 --- a/src/mesa/math/m_eval.c +++ /dev/null @@ -1,461 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/* - * eval.c was written by - * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and - * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de). - * - * My original implementation of evaluators was simplistic and didn't - * compute surface normal vectors properly. Bernd and Volker applied - * used more sophisticated methods to get better results. - * - * Thanks guys! - */ - - -#include "main/glheader.h" -#include "main/config.h" -#include "m_eval.h" - -static GLfloat inv_tab[MAX_EVAL_ORDER]; - - - -/* - * Horner scheme for Bezier curves - * - * Bezier curves can be computed via a Horner scheme. - * Horner is numerically less stable than the de Casteljau - * algorithm, but it is faster. For curves of degree n - * the complexity of Horner is O(n) and de Casteljau is O(n^2). - * Since stability is not important for displaying curve - * points I decided to use the Horner scheme. - * - * A cubic Bezier curve with control points b0, b1, b2, b3 can be - * written as - * - * (([3] [3] ) [3] ) [3] - * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3 - * - * [n] - * where s=1-t and the binomial coefficients [i]. These can - * be computed iteratively using the identity: - * - * [n] [n ] [n] - * [i] = (n-i+1)/i * [i-1] and [0] = 1 - */ - - -void -_math_horner_bezier_curve(const GLfloat * cp, GLfloat * out, GLfloat t, - GLuint dim, GLuint order) -{ - GLfloat s, powert, bincoeff; - GLuint i, k; - - if (order >= 2) { - bincoeff = (GLfloat) (order - 1); - s = 1.0F - t; - - for (k = 0; k < dim; k++) - out[k] = s * cp[k] + bincoeff * t * cp[dim + k]; - - for (i = 2, cp += 2 * dim, powert = t * t; i < order; - i++, powert *= t, cp += dim) { - bincoeff *= (GLfloat) (order - i); - bincoeff *= inv_tab[i]; - - for (k = 0; k < dim; k++) - out[k] = s * out[k] + bincoeff * powert * cp[k]; - } - } - else { /* order=1 -> constant curve */ - - for (k = 0; k < dim; k++) - out[k] = cp[k]; - } -} - -/* - * Tensor product Bezier surfaces - * - * Again the Horner scheme is used to compute a point on a - * TP Bezier surface. First a control polygon for a curve - * on the surface in one parameter direction is computed, - * then the point on the curve for the other parameter - * direction is evaluated. - * - * To store the curve control polygon additional storage - * for max(uorder,vorder) points is needed in the - * control net cn. - */ - -void -_math_horner_bezier_surf(GLfloat * cn, GLfloat * out, GLfloat u, GLfloat v, - GLuint dim, GLuint uorder, GLuint vorder) -{ - GLfloat *cp = cn + uorder * vorder * dim; - GLuint i, uinc = vorder * dim; - - if (vorder > uorder) { - if (uorder >= 2) { - GLfloat s, poweru, bincoeff; - GLuint j, k; - - /* Compute the control polygon for the surface-curve in u-direction */ - for (j = 0; j < vorder; j++) { - GLfloat *ucp = &cn[j * dim]; - - /* Each control point is the point for parameter u on a */ - /* curve defined by the control polygons in u-direction */ - bincoeff = (GLfloat) (uorder - 1); - s = 1.0F - u; - - for (k = 0; k < dim; k++) - cp[j * dim + k] = s * ucp[k] + bincoeff * u * ucp[uinc + k]; - - for (i = 2, ucp += 2 * uinc, poweru = u * u; i < uorder; - i++, poweru *= u, ucp += uinc) { - bincoeff *= (GLfloat) (uorder - i); - bincoeff *= inv_tab[i]; - - for (k = 0; k < dim; k++) - cp[j * dim + k] = - s * cp[j * dim + k] + bincoeff * poweru * ucp[k]; - } - } - - /* Evaluate curve point in v */ - _math_horner_bezier_curve(cp, out, v, dim, vorder); - } - else /* uorder=1 -> cn defines a curve in v */ - _math_horner_bezier_curve(cn, out, v, dim, vorder); - } - else { /* vorder <= uorder */ - - if (vorder > 1) { - GLuint i; - - /* Compute the control polygon for the surface-curve in u-direction */ - for (i = 0; i < uorder; i++, cn += uinc) { - /* For constant i all cn[i][j] (j=0..vorder) are located */ - /* on consecutive memory locations, so we can use */ - /* horner_bezier_curve to compute the control points */ - - _math_horner_bezier_curve(cn, &cp[i * dim], v, dim, vorder); - } - - /* Evaluate curve point in u */ - _math_horner_bezier_curve(cp, out, u, dim, uorder); - } - else /* vorder=1 -> cn defines a curve in u */ - _math_horner_bezier_curve(cn, out, u, dim, uorder); - } -} - -/* - * The direct de Casteljau algorithm is used when a point on the - * surface and the tangent directions spanning the tangent plane - * should be computed (this is needed to compute normals to the - * surface). In this case the de Casteljau algorithm approach is - * nicer because a point and the partial derivatives can be computed - * at the same time. To get the correct tangent length du and dv - * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. - * Since only the directions are needed, this scaling step is omitted. - * - * De Casteljau needs additional storage for uorder*vorder - * values in the control net cn. - */ - -void -_math_de_casteljau_surf(GLfloat * cn, GLfloat * out, GLfloat * du, - GLfloat * dv, GLfloat u, GLfloat v, GLuint dim, - GLuint uorder, GLuint vorder) -{ - GLfloat *dcn = cn + uorder * vorder * dim; - GLfloat us = 1.0F - u, vs = 1.0F - v; - GLuint h, i, j, k; - GLuint minorder = uorder < vorder ? uorder : vorder; - GLuint uinc = vorder * dim; - GLuint dcuinc = vorder; - - /* Each component is evaluated separately to save buffer space */ - /* This does not drasticaly decrease the performance of the */ - /* algorithm. If additional storage for (uorder-1)*(vorder-1) */ - /* points would be available, the components could be accessed */ - /* in the innermost loop which could lead to less cache misses. */ - -#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)] -#define DCN(I, J) dcn[(I)*dcuinc+(J)] - if (minorder < 3) { - if (uorder == vorder) { - for (k = 0; k < dim; k++) { - /* Derivative direction in u */ - du[k] = vs * (CN(1, 0, k) - CN(0, 0, k)) + - v * (CN(1, 1, k) - CN(0, 1, k)); - - /* Derivative direction in v */ - dv[k] = us * (CN(0, 1, k) - CN(0, 0, k)) + - u * (CN(1, 1, k) - CN(1, 0, k)); - - /* bilinear de Casteljau step */ - out[k] = us * (vs * CN(0, 0, k) + v * CN(0, 1, k)) + - u * (vs * CN(1, 0, k) + v * CN(1, 1, k)); - } - } - else if (minorder == uorder) { - for (k = 0; k < dim; k++) { - /* bilinear de Casteljau step */ - DCN(1, 0) = CN(1, 0, k) - CN(0, 0, k); - DCN(0, 0) = us * CN(0, 0, k) + u * CN(1, 0, k); - - for (j = 0; j < vorder - 1; j++) { - /* for the derivative in u */ - DCN(1, j + 1) = CN(1, j + 1, k) - CN(0, j + 1, k); - DCN(1, j) = vs * DCN(1, j) + v * DCN(1, j + 1); - - /* for the `point' */ - DCN(0, j + 1) = us * CN(0, j + 1, k) + u * CN(1, j + 1, k); - DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); - } - - /* remaining linear de Casteljau steps until the second last step */ - for (h = minorder; h < vorder - 1; h++) - for (j = 0; j < vorder - h; j++) { - /* for the derivative in u */ - DCN(1, j) = vs * DCN(1, j) + v * DCN(1, j + 1); - - /* for the `point' */ - DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); - } - - /* derivative direction in v */ - dv[k] = DCN(0, 1) - DCN(0, 0); - - /* derivative direction in u */ - du[k] = vs * DCN(1, 0) + v * DCN(1, 1); - - /* last linear de Casteljau step */ - out[k] = vs * DCN(0, 0) + v * DCN(0, 1); - } - } - else { /* minorder == vorder */ - - for (k = 0; k < dim; k++) { - /* bilinear de Casteljau step */ - DCN(0, 1) = CN(0, 1, k) - CN(0, 0, k); - DCN(0, 0) = vs * CN(0, 0, k) + v * CN(0, 1, k); - for (i = 0; i < uorder - 1; i++) { - /* for the derivative in v */ - DCN(i + 1, 1) = CN(i + 1, 1, k) - CN(i + 1, 0, k); - DCN(i, 1) = us * DCN(i, 1) + u * DCN(i + 1, 1); - - /* for the `point' */ - DCN(i + 1, 0) = vs * CN(i + 1, 0, k) + v * CN(i + 1, 1, k); - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - } - - /* remaining linear de Casteljau steps until the second last step */ - for (h = minorder; h < uorder - 1; h++) - for (i = 0; i < uorder - h; i++) { - /* for the derivative in v */ - DCN(i, 1) = us * DCN(i, 1) + u * DCN(i + 1, 1); - - /* for the `point' */ - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - } - - /* derivative direction in u */ - du[k] = DCN(1, 0) - DCN(0, 0); - - /* derivative direction in v */ - dv[k] = us * DCN(0, 1) + u * DCN(1, 1); - - /* last linear de Casteljau step */ - out[k] = us * DCN(0, 0) + u * DCN(1, 0); - } - } - } - else if (uorder == vorder) { - for (k = 0; k < dim; k++) { - /* first bilinear de Casteljau step */ - for (i = 0; i < uorder - 1; i++) { - DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k); - for (j = 0; j < vorder - 1; j++) { - DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k); - DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); - } - } - - /* remaining bilinear de Casteljau steps until the second last step */ - for (h = 2; h < minorder - 1; h++) - for (i = 0; i < uorder - h; i++) { - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - for (j = 0; j < vorder - h; j++) { - DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1); - DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); - } - } - - /* derivative direction in u */ - du[k] = vs * (DCN(1, 0) - DCN(0, 0)) + v * (DCN(1, 1) - DCN(0, 1)); - - /* derivative direction in v */ - dv[k] = us * (DCN(0, 1) - DCN(0, 0)) + u * (DCN(1, 1) - DCN(1, 0)); - - /* last bilinear de Casteljau step */ - out[k] = us * (vs * DCN(0, 0) + v * DCN(0, 1)) + - u * (vs * DCN(1, 0) + v * DCN(1, 1)); - } - } - else if (minorder == uorder) { - for (k = 0; k < dim; k++) { - /* first bilinear de Casteljau step */ - for (i = 0; i < uorder - 1; i++) { - DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k); - for (j = 0; j < vorder - 1; j++) { - DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k); - DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); - } - } - - /* remaining bilinear de Casteljau steps until the second last step */ - for (h = 2; h < minorder - 1; h++) - for (i = 0; i < uorder - h; i++) { - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - for (j = 0; j < vorder - h; j++) { - DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1); - DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); - } - } - - /* last bilinear de Casteljau step */ - DCN(2, 0) = DCN(1, 0) - DCN(0, 0); - DCN(0, 0) = us * DCN(0, 0) + u * DCN(1, 0); - for (j = 0; j < vorder - 1; j++) { - /* for the derivative in u */ - DCN(2, j + 1) = DCN(1, j + 1) - DCN(0, j + 1); - DCN(2, j) = vs * DCN(2, j) + v * DCN(2, j + 1); - - /* for the `point' */ - DCN(0, j + 1) = us * DCN(0, j + 1) + u * DCN(1, j + 1); - DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); - } - - /* remaining linear de Casteljau steps until the second last step */ - for (h = minorder; h < vorder - 1; h++) - for (j = 0; j < vorder - h; j++) { - /* for the derivative in u */ - DCN(2, j) = vs * DCN(2, j) + v * DCN(2, j + 1); - - /* for the `point' */ - DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); - } - - /* derivative direction in v */ - dv[k] = DCN(0, 1) - DCN(0, 0); - - /* derivative direction in u */ - du[k] = vs * DCN(2, 0) + v * DCN(2, 1); - - /* last linear de Casteljau step */ - out[k] = vs * DCN(0, 0) + v * DCN(0, 1); - } - } - else { /* minorder == vorder */ - - for (k = 0; k < dim; k++) { - /* first bilinear de Casteljau step */ - for (i = 0; i < uorder - 1; i++) { - DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k); - for (j = 0; j < vorder - 1; j++) { - DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k); - DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); - } - } - - /* remaining bilinear de Casteljau steps until the second last step */ - for (h = 2; h < minorder - 1; h++) - for (i = 0; i < uorder - h; i++) { - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - for (j = 0; j < vorder - h; j++) { - DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1); - DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); - } - } - - /* last bilinear de Casteljau step */ - DCN(0, 2) = DCN(0, 1) - DCN(0, 0); - DCN(0, 0) = vs * DCN(0, 0) + v * DCN(0, 1); - for (i = 0; i < uorder - 1; i++) { - /* for the derivative in v */ - DCN(i + 1, 2) = DCN(i + 1, 1) - DCN(i + 1, 0); - DCN(i, 2) = us * DCN(i, 2) + u * DCN(i + 1, 2); - - /* for the `point' */ - DCN(i + 1, 0) = vs * DCN(i + 1, 0) + v * DCN(i + 1, 1); - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - } - - /* remaining linear de Casteljau steps until the second last step */ - for (h = minorder; h < uorder - 1; h++) - for (i = 0; i < uorder - h; i++) { - /* for the derivative in v */ - DCN(i, 2) = us * DCN(i, 2) + u * DCN(i + 1, 2); - - /* for the `point' */ - DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); - } - - /* derivative direction in u */ - du[k] = DCN(1, 0) - DCN(0, 0); - - /* derivative direction in v */ - dv[k] = us * DCN(0, 2) + u * DCN(1, 2); - - /* last linear de Casteljau step */ - out[k] = us * DCN(0, 0) + u * DCN(1, 0); - } - } -#undef DCN -#undef CN -} - - -/* - * Do one-time initialization for evaluators. - */ -void -_math_init_eval(void) -{ - GLuint i; - - /* KW: precompute 1/x for useful x. - */ - for (i = 1; i < MAX_EVAL_ORDER; i++) - inv_tab[i] = 1.0F / i; -} diff --git a/src/mesa/math/m_eval.h b/src/mesa/math/m_eval.h deleted file mode 100644 index d73ecaa..0000000 --- a/src/mesa/math/m_eval.h +++ /dev/null @@ -1,103 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _M_EVAL_H -#define _M_EVAL_H - -#include "main/glheader.h" - -void _math_init_eval( void ); - - -/* - * Horner scheme for Bezier curves - * - * Bezier curves can be computed via a Horner scheme. - * Horner is numerically less stable than the de Casteljau - * algorithm, but it is faster. For curves of degree n - * the complexity of Horner is O(n) and de Casteljau is O(n^2). - * Since stability is not important for displaying curve - * points I decided to use the Horner scheme. - * - * A cubic Bezier curve with control points b0, b1, b2, b3 can be - * written as - * - * (([3] [3] ) [3] ) [3] - * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3 - * - * [n] - * where s=1-t and the binomial coefficients [i]. These can - * be computed iteratively using the identity: - * - * [n] [n ] [n] - * [i] = (n-i+1)/i * [i-1] and [0] = 1 - */ - - -void -_math_horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t, - GLuint dim, GLuint order); - - -/* - * Tensor product Bezier surfaces - * - * Again the Horner scheme is used to compute a point on a - * TP Bezier surface. First a control polygon for a curve - * on the surface in one parameter direction is computed, - * then the point on the curve for the other parameter - * direction is evaluated. - * - * To store the curve control polygon additional storage - * for max(uorder,vorder) points is needed in the - * control net cn. - */ - -void -_math_horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v, - GLuint dim, GLuint uorder, GLuint vorder); - - -/* - * The direct de Casteljau algorithm is used when a point on the - * surface and the tangent directions spanning the tangent plane - * should be computed (this is needed to compute normals to the - * surface). In this case the de Casteljau algorithm approach is - * nicer because a point and the partial derivatives can be computed - * at the same time. To get the correct tangent length du and dv - * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. - * Since only the directions are needed, this scaling step is omitted. - * - * De Casteljau needs additional storage for uorder*vorder - * values in the control net cn. - */ - -void -_math_de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv, - GLfloat u, GLfloat v, GLuint dim, - GLuint uorder, GLuint vorder); - - -#endif diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c deleted file mode 100644 index 02aedba..0000000 --- a/src/mesa/math/m_matrix.c +++ /dev/null @@ -1,1641 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file m_matrix.c - * Matrix operations. - * - * \note - * -# 4x4 transformation matrices are stored in memory in column major order. - * -# Points/vertices are to be thought of as column vectors. - * -# Transformation of a point p by a matrix M is: p' = M * p - */ - - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/macros.h" - -#include "m_matrix.h" - - -/** - * \defgroup MatFlags MAT_FLAG_XXX-flags - * - * Bitmasks to indicate different kinds of 4x4 matrices in GLmatrix::flags - * It would be nice to make all these flags private to m_matrix.c - */ -/*@{*/ -#define MAT_FLAG_IDENTITY 0 /**< is an identity matrix flag. - * (Not actually used - the identity - * matrix is identified by the absense - * of all other flags.) - */ -#define MAT_FLAG_GENERAL 0x1 /**< is a general matrix flag */ -#define MAT_FLAG_ROTATION 0x2 /**< is a rotation matrix flag */ -#define MAT_FLAG_TRANSLATION 0x4 /**< is a translation matrix flag */ -#define MAT_FLAG_UNIFORM_SCALE 0x8 /**< is an uniform scaling matrix flag */ -#define MAT_FLAG_GENERAL_SCALE 0x10 /**< is a general scaling matrix flag */ -#define MAT_FLAG_GENERAL_3D 0x20 /**< general 3D matrix flag */ -#define MAT_FLAG_PERSPECTIVE 0x40 /**< is a perspective proj matrix flag */ -#define MAT_FLAG_SINGULAR 0x80 /**< is a singular matrix flag */ -#define MAT_DIRTY_TYPE 0x100 /**< matrix type is dirty */ -#define MAT_DIRTY_FLAGS 0x200 /**< matrix flags are dirty */ -#define MAT_DIRTY_INVERSE 0x400 /**< matrix inverse is dirty */ - -/** angle preserving matrix flags mask */ -#define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION | \ - MAT_FLAG_UNIFORM_SCALE) - -/** geometry related matrix flags mask */ -#define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \ - MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION | \ - MAT_FLAG_UNIFORM_SCALE | \ - MAT_FLAG_GENERAL_SCALE | \ - MAT_FLAG_GENERAL_3D | \ - MAT_FLAG_PERSPECTIVE | \ - MAT_FLAG_SINGULAR) - -/** length preserving matrix flags mask */ -#define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION) - - -/** 3D (non-perspective) matrix flags mask */ -#define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION | \ - MAT_FLAG_UNIFORM_SCALE | \ - MAT_FLAG_GENERAL_SCALE | \ - MAT_FLAG_GENERAL_3D) - -/** dirty matrix flags mask */ -#define MAT_DIRTY (MAT_DIRTY_TYPE | \ - MAT_DIRTY_FLAGS | \ - MAT_DIRTY_INVERSE) - -/*@}*/ - - -/** - * Test geometry related matrix flags. - * - * \param mat a pointer to a GLmatrix structure. - * \param a flags mask. - * - * \returns non-zero if all geometry related matrix flags are contained within - * the mask, or zero otherwise. - */ -#define TEST_MAT_FLAGS(mat, a) \ - ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0) - - - -/** - * Names of the corresponding GLmatrixtype values. - */ -static const char *types[] = { - "MATRIX_GENERAL", - "MATRIX_IDENTITY", - "MATRIX_3D_NO_ROT", - "MATRIX_PERSPECTIVE", - "MATRIX_2D", - "MATRIX_2D_NO_ROT", - "MATRIX_3D" -}; - - -/** - * Identity matrix. - */ -static GLfloat Identity[16] = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 -}; - - - -/**********************************************************************/ -/** \name Matrix multiplication */ -/*@{*/ - -#define A(row,col) a[(col<<2)+row] -#define B(row,col) b[(col<<2)+row] -#define P(row,col) product[(col<<2)+row] - -/** - * Perform a full 4x4 matrix multiplication. - * - * \param a matrix. - * \param b matrix. - * \param product will receive the product of \p a and \p b. - * - * \warning Is assumed that \p product != \p b. \p product == \p a is allowed. - * - * \note KW: 4*16 = 64 multiplications - * - * \author This \c matmul was contributed by Thomas Malik - */ -static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b ) -{ - GLint i; - for (i = 0; i < 4; i++) { - const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); - P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); - P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); - P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); - P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); - } -} - -/** - * Multiply two matrices known to occupy only the top three rows, such - * as typical model matrices, and orthogonal matrices. - * - * \param a matrix. - * \param b matrix. - * \param product will receive the product of \p a and \p b. - */ -static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b ) -{ - GLint i; - for (i = 0; i < 3; i++) { - const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); - P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0); - P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1); - P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2); - P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3; - } - P(3,0) = 0; - P(3,1) = 0; - P(3,2) = 0; - P(3,3) = 1; -} - -#undef A -#undef B -#undef P - -/** - * Multiply a matrix by an array of floats with known properties. - * - * \param mat pointer to a GLmatrix structure containing the left multiplication - * matrix, and that will receive the product result. - * \param m right multiplication matrix array. - * \param flags flags of the matrix \p m. - * - * Joins both flags and marks the type and inverse as dirty. Calls matmul34() - * if both matrices are 3D, or matmul4() otherwise. - */ -static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags ) -{ - mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); - - if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) - matmul34( mat->m, mat->m, m ); - else - matmul4( mat->m, mat->m, m ); -} - -/** - * Matrix multiplication. - * - * \param dest destination matrix. - * \param a left matrix. - * \param b right matrix. - * - * Joins both flags and marks the type and inverse as dirty. Calls matmul34() - * if both matrices are 3D, or matmul4() otherwise. - */ -void -_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ) -{ - dest->flags = (a->flags | - b->flags | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE); - - if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D)) - matmul34( dest->m, a->m, b->m ); - else - matmul4( dest->m, a->m, b->m ); -} - -/** - * Matrix multiplication. - * - * \param dest left and destination matrix. - * \param m right matrix array. - * - * Marks the matrix flags with general flag, and type and inverse dirty flags. - * Calls matmul4() for the multiplication. - */ -void -_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m ) -{ - dest->flags |= (MAT_FLAG_GENERAL | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE | - MAT_DIRTY_FLAGS); - - matmul4( dest->m, dest->m, m ); -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Matrix output */ -/*@{*/ - -/** - * Print a matrix array. - * - * \param m matrix array. - * - * Called by _math_matrix_print() to print a matrix or its inverse. - */ -static void print_matrix_floats( const GLfloat m[16] ) -{ - int i; - for (i=0;i<4;i++) { - _mesa_debug(NULL,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] ); - } -} - -/** - * Dumps the contents of a GLmatrix structure. - * - * \param m pointer to the GLmatrix structure. - */ -void -_math_matrix_print( const GLmatrix *m ) -{ - _mesa_debug(NULL, "Matrix type: %s, flags: %x\n", types[m->type], m->flags); - print_matrix_floats(m->m); - _mesa_debug(NULL, "Inverse: \n"); - if (m->inv) { - GLfloat prod[16]; - print_matrix_floats(m->inv); - matmul4(prod, m->m, m->inv); - _mesa_debug(NULL, "Mat * Inverse:\n"); - print_matrix_floats(prod); - } - else { - _mesa_debug(NULL, " - not available\n"); - } -} - -/*@}*/ - - -/** - * References an element of 4x4 matrix. - * - * \param m matrix array. - * \param c column of the desired element. - * \param r row of the desired element. - * - * \return value of the desired element. - * - * Calculate the linear storage index of the element and references it. - */ -#define MAT(m,r,c) (m)[(c)*4+(r)] - - -/**********************************************************************/ -/** \name Matrix inversion */ -/*@{*/ - -/** - * Swaps the values of two floating pointer variables. - * - * Used by invert_matrix_general() to swap the row pointers. - */ -#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; } - -/** - * Compute inverse of 4x4 transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). - * - * \author - * Code contributed by Jacques Leroy jle@star.be - * - * Calculates the inverse matrix by performing the gaussian matrix reduction - * with partial pivoting followed by back/substitution with the loops manually - * unrolled. - */ -static GLboolean invert_matrix_general( GLmatrix *mat ) -{ - const GLfloat *m = mat->m; - GLfloat *out = mat->inv; - GLfloat wtmp[4][8]; - GLfloat m0, m1, m2, m3, s; - GLfloat *r0, *r1, *r2, *r3; - - r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; - - r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), - r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), - r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, - - r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), - r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), - r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, - - r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), - r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), - r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, - - r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), - r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), - r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; - - /* choose pivot - or die */ - if (FABSF(r3[0])>FABSF(r2[0])) SWAP_ROWS(r3, r2); - if (FABSF(r2[0])>FABSF(r1[0])) SWAP_ROWS(r2, r1); - if (FABSF(r1[0])>FABSF(r0[0])) SWAP_ROWS(r1, r0); - if (0.0 == r0[0]) return GL_FALSE; - - /* eliminate first variable */ - m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; - s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; - s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; - s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; - s = r0[4]; - if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r0[5]; - if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r0[6]; - if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r0[7]; - if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (FABSF(r3[1])>FABSF(r2[1])) SWAP_ROWS(r3, r2); - if (FABSF(r2[1])>FABSF(r1[1])) SWAP_ROWS(r2, r1); - if (0.0 == r1[1]) return GL_FALSE; - - /* eliminate second variable */ - m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; - r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; - r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; - s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (FABSF(r3[2])>FABSF(r2[2])) SWAP_ROWS(r3, r2); - if (0.0 == r2[2]) return GL_FALSE; - - /* eliminate third variable */ - m3 = r3[2]/r2[2]; - r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], - r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], - r3[7] -= m3 * r2[7]; - - /* last check */ - if (0.0 == r3[3]) return GL_FALSE; - - s = 1.0F/r3[3]; /* now back substitute row 3 */ - r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; - - m2 = r2[3]; /* now back substitute row 2 */ - s = 1.0F/r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), - r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, - r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, - r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; - - m1 = r1[2]; /* now back substitute row 1 */ - s = 1.0F/r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), - r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, - r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; - - m0 = r0[1]; /* now back substitute row 0 */ - s = 1.0F/r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), - r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); - - MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], - MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], - MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], - MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], - MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], - MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], - MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], - MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; - - return GL_TRUE; -} -#undef SWAP_ROWS - -/** - * Compute inverse of a general 3d transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). - * - * \author Adapted from graphics gems II. - * - * Calculates the inverse of the upper left by first calculating its - * determinant and multiplying it to the symmetric adjust matrix of each - * element. Finally deals with the translation part by transforming the - * original translation vector using by the calculated submatrix inverse. - */ -static GLboolean invert_matrix_3d_general( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - GLfloat pos, neg, t; - GLfloat det; - - /* Calculate the determinant of upper left 3x3 submatrix and - * determine if the matrix is singular. - */ - pos = neg = 0.0; - t = MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2); - if (t >= 0.0) pos += t; else neg += t; - - t = MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2); - if (t >= 0.0) pos += t; else neg += t; - - t = MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2); - if (t >= 0.0) pos += t; else neg += t; - - det = pos + neg; - - if (det*det < 1e-25) - return GL_FALSE; - - det = 1.0F / det; - MAT(out,0,0) = ( (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det); - MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det); - MAT(out,0,2) = ( (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det); - MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det); - MAT(out,1,1) = ( (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det); - MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det); - MAT(out,2,0) = ( (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det); - MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det); - MAT(out,2,2) = ( (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det); - - /* Do the translation part */ - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + - MAT(in,1,3) * MAT(out,0,1) + - MAT(in,2,3) * MAT(out,0,2) ); - MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + - MAT(in,1,3) * MAT(out,1,1) + - MAT(in,2,3) * MAT(out,1,2) ); - MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + - MAT(in,1,3) * MAT(out,2,1) + - MAT(in,2,3) * MAT(out,2,2) ); - - return GL_TRUE; -} - -/** - * Compute inverse of a 3d transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). - * - * If the matrix is not an angle preserving matrix then calls - * invert_matrix_3d_general for the actual calculation. Otherwise calculates - * the inverse matrix analyzing and inverting each of the scaling, rotation and - * translation parts. - */ -static GLboolean invert_matrix_3d( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) { - return invert_matrix_3d_general( mat ); - } - - if (mat->flags & MAT_FLAG_UNIFORM_SCALE) { - GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) + - MAT(in,0,1) * MAT(in,0,1) + - MAT(in,0,2) * MAT(in,0,2)); - - if (scale == 0.0) - return GL_FALSE; - - scale = 1.0F / scale; - - /* Transpose and scale the 3 by 3 upper-left submatrix. */ - MAT(out,0,0) = scale * MAT(in,0,0); - MAT(out,1,0) = scale * MAT(in,0,1); - MAT(out,2,0) = scale * MAT(in,0,2); - MAT(out,0,1) = scale * MAT(in,1,0); - MAT(out,1,1) = scale * MAT(in,1,1); - MAT(out,2,1) = scale * MAT(in,1,2); - MAT(out,0,2) = scale * MAT(in,2,0); - MAT(out,1,2) = scale * MAT(in,2,1); - MAT(out,2,2) = scale * MAT(in,2,2); - } - else if (mat->flags & MAT_FLAG_ROTATION) { - /* Transpose the 3 by 3 upper-left submatrix. */ - MAT(out,0,0) = MAT(in,0,0); - MAT(out,1,0) = MAT(in,0,1); - MAT(out,2,0) = MAT(in,0,2); - MAT(out,0,1) = MAT(in,1,0); - MAT(out,1,1) = MAT(in,1,1); - MAT(out,2,1) = MAT(in,1,2); - MAT(out,0,2) = MAT(in,2,0); - MAT(out,1,2) = MAT(in,2,1); - MAT(out,2,2) = MAT(in,2,2); - } - else { - /* pure translation */ - memcpy( out, Identity, sizeof(Identity) ); - MAT(out,0,3) = - MAT(in,0,3); - MAT(out,1,3) = - MAT(in,1,3); - MAT(out,2,3) = - MAT(in,2,3); - return GL_TRUE; - } - - if (mat->flags & MAT_FLAG_TRANSLATION) { - /* Do the translation part */ - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + - MAT(in,1,3) * MAT(out,0,1) + - MAT(in,2,3) * MAT(out,0,2) ); - MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + - MAT(in,1,3) * MAT(out,1,1) + - MAT(in,2,3) * MAT(out,1,2) ); - MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + - MAT(in,1,3) * MAT(out,2,1) + - MAT(in,2,3) * MAT(out,2,2) ); - } - else { - MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0; - } - - return GL_TRUE; -} - -/** - * Compute inverse of an identity transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return always GL_TRUE. - * - * Simply copies Identity into GLmatrix::inv. - */ -static GLboolean invert_matrix_identity( GLmatrix *mat ) -{ - memcpy( mat->inv, Identity, sizeof(Identity) ); - return GL_TRUE; -} - -/** - * Compute inverse of a no-rotation 3d transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). - * - * Calculates the - */ -static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 ) - return GL_FALSE; - - memcpy( out, Identity, 16 * sizeof(GLfloat) ); - MAT(out,0,0) = 1.0F / MAT(in,0,0); - MAT(out,1,1) = 1.0F / MAT(in,1,1); - MAT(out,2,2) = 1.0F / MAT(in,2,2); - - if (mat->flags & MAT_FLAG_TRANSLATION) { - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); - MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); - MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2)); - } - - return GL_TRUE; -} - -/** - * Compute inverse of a no-rotation 2d transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). - * - * Calculates the inverse matrix by applying the inverse scaling and - * translation to the identity matrix. - */ -static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0) - return GL_FALSE; - - memcpy( out, Identity, 16 * sizeof(GLfloat) ); - MAT(out,0,0) = 1.0F / MAT(in,0,0); - MAT(out,1,1) = 1.0F / MAT(in,1,1); - - if (mat->flags & MAT_FLAG_TRANSLATION) { - MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); - MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); - } - - return GL_TRUE; -} - -#if 0 -/* broken */ -static GLboolean invert_matrix_perspective( GLmatrix *mat ) -{ - const GLfloat *in = mat->m; - GLfloat *out = mat->inv; - - if (MAT(in,2,3) == 0) - return GL_FALSE; - - memcpy( out, Identity, 16 * sizeof(GLfloat) ); - - MAT(out,0,0) = 1.0F / MAT(in,0,0); - MAT(out,1,1) = 1.0F / MAT(in,1,1); - - MAT(out,0,3) = MAT(in,0,2); - MAT(out,1,3) = MAT(in,1,2); - - MAT(out,2,2) = 0; - MAT(out,2,3) = -1; - - MAT(out,3,2) = 1.0F / MAT(in,2,3); - MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2); - - return GL_TRUE; -} -#endif - -/** - * Matrix inversion function pointer type. - */ -typedef GLboolean (*inv_mat_func)( GLmatrix *mat ); - -/** - * Table of the matrix inversion functions according to the matrix type. - */ -static inv_mat_func inv_mat_tab[7] = { - invert_matrix_general, - invert_matrix_identity, - invert_matrix_3d_no_rot, -#if 0 - /* Don't use this function for now - it fails when the projection matrix - * is premultiplied by a translation (ala Chromium's tilesort SPU). - */ - invert_matrix_perspective, -#else - invert_matrix_general, -#endif - invert_matrix_3d, /* lazy! */ - invert_matrix_2d_no_rot, - invert_matrix_3d -}; - -/** - * Compute inverse of a transformation matrix. - * - * \param mat pointer to a GLmatrix structure. The matrix inverse will be - * stored in the GLmatrix::inv attribute. - * - * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). - * - * Calls the matrix inversion function in inv_mat_tab corresponding to the - * given matrix type. In case of failure, updates the MAT_FLAG_SINGULAR flag, - * and copies the identity matrix into GLmatrix::inv. - */ -static GLboolean matrix_invert( GLmatrix *mat ) -{ - if (inv_mat_tab[mat->type](mat)) { - mat->flags &= ~MAT_FLAG_SINGULAR; - return GL_TRUE; - } else { - mat->flags |= MAT_FLAG_SINGULAR; - memcpy( mat->inv, Identity, sizeof(Identity) ); - return GL_FALSE; - } -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Matrix generation */ -/*@{*/ - -/** - * Generate a 4x4 transformation matrix from glRotate parameters, and - * post-multiply the input matrix by it. - * - * \author - * This function was contributed by Erich Boleyn (erich@uruk.org). - * Optimizations contributed by Rudolf Opalla (rudi@khm.de). - */ -void -_math_matrix_rotate( GLmatrix *mat, - GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) -{ - GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c; - GLfloat m[16]; - GLboolean optimized; - - s = (GLfloat) sin( angle * DEG2RAD ); - c = (GLfloat) cos( angle * DEG2RAD ); - - memcpy(m, Identity, sizeof(GLfloat)*16); - optimized = GL_FALSE; - -#define M(row,col) m[col*4+row] - - if (x == 0.0F) { - if (y == 0.0F) { - if (z != 0.0F) { - optimized = GL_TRUE; - /* rotate only around z-axis */ - M(0,0) = c; - M(1,1) = c; - if (z < 0.0F) { - M(0,1) = s; - M(1,0) = -s; - } - else { - M(0,1) = -s; - M(1,0) = s; - } - } - } - else if (z == 0.0F) { - optimized = GL_TRUE; - /* rotate only around y-axis */ - M(0,0) = c; - M(2,2) = c; - if (y < 0.0F) { - M(0,2) = -s; - M(2,0) = s; - } - else { - M(0,2) = s; - M(2,0) = -s; - } - } - } - else if (y == 0.0F) { - if (z == 0.0F) { - optimized = GL_TRUE; - /* rotate only around x-axis */ - M(1,1) = c; - M(2,2) = c; - if (x < 0.0F) { - M(1,2) = s; - M(2,1) = -s; - } - else { - M(1,2) = -s; - M(2,1) = s; - } - } - } - - if (!optimized) { - const GLfloat mag = SQRTF(x * x + y * y + z * z); - - if (mag <= 1.0e-4) { - /* no rotation, leave mat as-is */ - return; - } - - x /= mag; - y /= mag; - z /= mag; - - - /* - * Arbitrary axis rotation matrix. - * - * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied - * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation - * (which is about the X-axis), and the two composite transforms - * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary - * from the arbitrary axis to the X-axis then back. They are - * all elementary rotations. - * - * Rz' is a rotation about the Z-axis, to bring the axis vector - * into the x-z plane. Then Ry' is applied, rotating about the - * Y-axis to bring the axis vector parallel with the X-axis. The - * rotation about the X-axis is then performed. Ry and Rz are - * simply the respective inverse transforms to bring the arbitrary - * axis back to its original orientation. The first transforms - * Rz' and Ry' are considered inverses, since the data from the - * arbitrary axis gives you info on how to get to it, not how - * to get away from it, and an inverse must be applied. - * - * The basic calculation used is to recognize that the arbitrary - * axis vector (x, y, z), since it is of unit length, actually - * represents the sines and cosines of the angles to rotate the - * X-axis to the same orientation, with theta being the angle about - * Z and phi the angle about Y (in the order described above) - * as follows: - * - * cos ( theta ) = x / sqrt ( 1 - z^2 ) - * sin ( theta ) = y / sqrt ( 1 - z^2 ) - * - * cos ( phi ) = sqrt ( 1 - z^2 ) - * sin ( phi ) = z - * - * Note that cos ( phi ) can further be inserted to the above - * formulas: - * - * cos ( theta ) = x / cos ( phi ) - * sin ( theta ) = y / sin ( phi ) - * - * ...etc. Because of those relations and the standard trigonometric - * relations, it is pssible to reduce the transforms down to what - * is used below. It may be that any primary axis chosen will give the - * same results (modulo a sign convention) using thie method. - * - * Particularly nice is to notice that all divisions that might - * have caused trouble when parallel to certain planes or - * axis go away with care paid to reducing the expressions. - * After checking, it does perform correctly under all cases, since - * in all the cases of division where the denominator would have - * been zero, the numerator would have been zero as well, giving - * the expected result. - */ - - xx = x * x; - yy = y * y; - zz = z * z; - xy = x * y; - yz = y * z; - zx = z * x; - xs = x * s; - ys = y * s; - zs = z * s; - one_c = 1.0F - c; - - /* We already hold the identity-matrix so we can skip some statements */ - M(0,0) = (one_c * xx) + c; - M(0,1) = (one_c * xy) - zs; - M(0,2) = (one_c * zx) + ys; -/* M(0,3) = 0.0F; */ - - M(1,0) = (one_c * xy) + zs; - M(1,1) = (one_c * yy) + c; - M(1,2) = (one_c * yz) - xs; -/* M(1,3) = 0.0F; */ - - M(2,0) = (one_c * zx) - ys; - M(2,1) = (one_c * yz) + xs; - M(2,2) = (one_c * zz) + c; -/* M(2,3) = 0.0F; */ - -/* - M(3,0) = 0.0F; - M(3,1) = 0.0F; - M(3,2) = 0.0F; - M(3,3) = 1.0F; -*/ - } -#undef M - - matrix_multf( mat, m, MAT_FLAG_ROTATION ); -} - -/** - * Apply a perspective projection matrix. - * - * \param mat matrix to apply the projection. - * \param left left clipping plane coordinate. - * \param right right clipping plane coordinate. - * \param bottom bottom clipping plane coordinate. - * \param top top clipping plane coordinate. - * \param nearval distance to the near clipping plane. - * \param farval distance to the far clipping plane. - * - * Creates the projection matrix and multiplies it with \p mat, marking the - * MAT_FLAG_PERSPECTIVE flag. - */ -void -_math_matrix_frustum( GLmatrix *mat, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat nearval, GLfloat farval ) -{ - GLfloat x, y, a, b, c, d; - GLfloat m[16]; - - x = (2.0F*nearval) / (right-left); - y = (2.0F*nearval) / (top-bottom); - a = (right+left) / (right-left); - b = (top+bottom) / (top-bottom); - c = -(farval+nearval) / ( farval-nearval); - d = -(2.0F*farval*nearval) / (farval-nearval); /* error? */ - -#define M(row,col) m[col*4+row] - M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; - M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; - M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; - M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; -#undef M - - matrix_multf( mat, m, MAT_FLAG_PERSPECTIVE ); -} - -/** - * Apply an orthographic projection matrix. - * - * \param mat matrix to apply the projection. - * \param left left clipping plane coordinate. - * \param right right clipping plane coordinate. - * \param bottom bottom clipping plane coordinate. - * \param top top clipping plane coordinate. - * \param nearval distance to the near clipping plane. - * \param farval distance to the far clipping plane. - * - * Creates the projection matrix and multiplies it with \p mat, marking the - * MAT_FLAG_GENERAL_SCALE and MAT_FLAG_TRANSLATION flags. - */ -void -_math_matrix_ortho( GLmatrix *mat, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat nearval, GLfloat farval ) -{ - GLfloat m[16]; - -#define M(row,col) m[col*4+row] - M(0,0) = 2.0F / (right-left); - M(0,1) = 0.0F; - M(0,2) = 0.0F; - M(0,3) = -(right+left) / (right-left); - - M(1,0) = 0.0F; - M(1,1) = 2.0F / (top-bottom); - M(1,2) = 0.0F; - M(1,3) = -(top+bottom) / (top-bottom); - - M(2,0) = 0.0F; - M(2,1) = 0.0F; - M(2,2) = -2.0F / (farval-nearval); - M(2,3) = -(farval+nearval) / (farval-nearval); - - M(3,0) = 0.0F; - M(3,1) = 0.0F; - M(3,2) = 0.0F; - M(3,3) = 1.0F; -#undef M - - matrix_multf( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION)); -} - -/** - * Multiply a matrix with a general scaling matrix. - * - * \param mat matrix. - * \param x x axis scale factor. - * \param y y axis scale factor. - * \param z z axis scale factor. - * - * Multiplies in-place the elements of \p mat by the scale factors. Checks if - * the scales factors are roughly the same, marking the MAT_FLAG_UNIFORM_SCALE - * flag, or MAT_FLAG_GENERAL_SCALE. Marks the MAT_DIRTY_TYPE and - * MAT_DIRTY_INVERSE dirty flags. - */ -void -_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) -{ - GLfloat *m = mat->m; - m[0] *= x; m[4] *= y; m[8] *= z; - m[1] *= x; m[5] *= y; m[9] *= z; - m[2] *= x; m[6] *= y; m[10] *= z; - m[3] *= x; m[7] *= y; m[11] *= z; - - if (FABSF(x - y) < 1e-8 && FABSF(x - z) < 1e-8) - mat->flags |= MAT_FLAG_UNIFORM_SCALE; - else - mat->flags |= MAT_FLAG_GENERAL_SCALE; - - mat->flags |= (MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE); -} - -/** - * Multiply a matrix with a translation matrix. - * - * \param mat matrix. - * \param x translation vector x coordinate. - * \param y translation vector y coordinate. - * \param z translation vector z coordinate. - * - * Adds the translation coordinates to the elements of \p mat in-place. Marks - * the MAT_FLAG_TRANSLATION flag, and the MAT_DIRTY_TYPE and MAT_DIRTY_INVERSE - * dirty flags. - */ -void -_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) -{ - GLfloat *m = mat->m; - m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; - m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; - m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; - m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; - - mat->flags |= (MAT_FLAG_TRANSLATION | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE); -} - - -/** - * Set matrix to do viewport and depthrange mapping. - * Transforms Normalized Device Coords to window/Z values. - */ -void -_math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height, - GLfloat zNear, GLfloat zFar, GLfloat depthMax) -{ - m->m[MAT_SX] = (GLfloat) width / 2.0F; - m->m[MAT_TX] = m->m[MAT_SX] + x; - m->m[MAT_SY] = (GLfloat) height / 2.0F; - m->m[MAT_TY] = m->m[MAT_SY] + y; - m->m[MAT_SZ] = depthMax * ((zFar - zNear) / 2.0F); - m->m[MAT_TZ] = depthMax * ((zFar - zNear) / 2.0F + zNear); - m->flags = MAT_FLAG_GENERAL_SCALE | MAT_FLAG_TRANSLATION; - m->type = MATRIX_3D_NO_ROT; -} - - -/** - * Set a matrix to the identity matrix. - * - * \param mat matrix. - * - * Copies ::Identity into \p GLmatrix::m, and into GLmatrix::inv if not NULL. - * Sets the matrix type to identity, and clear the dirty flags. - */ -void -_math_matrix_set_identity( GLmatrix *mat ) -{ - memcpy( mat->m, Identity, 16*sizeof(GLfloat) ); - - if (mat->inv) - memcpy( mat->inv, Identity, 16*sizeof(GLfloat) ); - - mat->type = MATRIX_IDENTITY; - mat->flags &= ~(MAT_DIRTY_FLAGS| - MAT_DIRTY_TYPE| - MAT_DIRTY_INVERSE); -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Matrix analysis */ -/*@{*/ - -#define ZERO(x) (1<<x) -#define ONE(x) (1<<(x+16)) - -#define MASK_NO_TRX (ZERO(12) | ZERO(13) | ZERO(14)) -#define MASK_NO_2D_SCALE ( ONE(0) | ONE(5)) - -#define MASK_IDENTITY ( ONE(0) | ZERO(4) | ZERO(8) | ZERO(12) |\ - ZERO(1) | ONE(5) | ZERO(9) | ZERO(13) |\ - ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - -#define MASK_2D_NO_ROT ( ZERO(4) | ZERO(8) | \ - ZERO(1) | ZERO(9) | \ - ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - -#define MASK_2D ( ZERO(8) | \ - ZERO(9) | \ - ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - - -#define MASK_3D_NO_ROT ( ZERO(4) | ZERO(8) | \ - ZERO(1) | ZERO(9) | \ - ZERO(2) | ZERO(6) | \ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - -#define MASK_3D ( \ - \ - \ - ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) - - -#define MASK_PERSPECTIVE ( ZERO(4) | ZERO(12) |\ - ZERO(1) | ZERO(13) |\ - ZERO(2) | ZERO(6) | \ - ZERO(3) | ZERO(7) | ZERO(15) ) - -#define SQ(x) ((x)*(x)) - -/** - * Determine type and flags from scratch. - * - * \param mat matrix. - * - * This is expensive enough to only want to do it once. - */ -static void analyse_from_scratch( GLmatrix *mat ) -{ - const GLfloat *m = mat->m; - GLuint mask = 0; - GLuint i; - - for (i = 0 ; i < 16 ; i++) { - if (m[i] == 0.0) mask |= (1<<i); - } - - if (m[0] == 1.0F) mask |= (1<<16); - if (m[5] == 1.0F) mask |= (1<<21); - if (m[10] == 1.0F) mask |= (1<<26); - if (m[15] == 1.0F) mask |= (1<<31); - - mat->flags &= ~MAT_FLAGS_GEOMETRY; - - /* Check for translation - no-one really cares - */ - if ((mask & MASK_NO_TRX) != MASK_NO_TRX) - mat->flags |= MAT_FLAG_TRANSLATION; - - /* Do the real work - */ - if (mask == (GLuint) MASK_IDENTITY) { - mat->type = MATRIX_IDENTITY; - } - else if ((mask & MASK_2D_NO_ROT) == (GLuint) MASK_2D_NO_ROT) { - mat->type = MATRIX_2D_NO_ROT; - - if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE) - mat->flags |= MAT_FLAG_GENERAL_SCALE; - } - else if ((mask & MASK_2D) == (GLuint) MASK_2D) { - GLfloat mm = DOT2(m, m); - GLfloat m4m4 = DOT2(m+4,m+4); - GLfloat mm4 = DOT2(m,m+4); - - mat->type = MATRIX_2D; - - /* Check for scale */ - if (SQ(mm-1) > SQ(1e-6) || - SQ(m4m4-1) > SQ(1e-6)) - mat->flags |= MAT_FLAG_GENERAL_SCALE; - - /* Check for rotation */ - if (SQ(mm4) > SQ(1e-6)) - mat->flags |= MAT_FLAG_GENERAL_3D; - else - mat->flags |= MAT_FLAG_ROTATION; - - } - else if ((mask & MASK_3D_NO_ROT) == (GLuint) MASK_3D_NO_ROT) { - mat->type = MATRIX_3D_NO_ROT; - - /* Check for scale */ - if (SQ(m[0]-m[5]) < SQ(1e-6) && - SQ(m[0]-m[10]) < SQ(1e-6)) { - if (SQ(m[0]-1.0) > SQ(1e-6)) { - mat->flags |= MAT_FLAG_UNIFORM_SCALE; - } - } - else { - mat->flags |= MAT_FLAG_GENERAL_SCALE; - } - } - else if ((mask & MASK_3D) == (GLuint) MASK_3D) { - GLfloat c1 = DOT3(m,m); - GLfloat c2 = DOT3(m+4,m+4); - GLfloat c3 = DOT3(m+8,m+8); - GLfloat d1 = DOT3(m, m+4); - GLfloat cp[3]; - - mat->type = MATRIX_3D; - - /* Check for scale */ - if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) { - if (SQ(c1-1.0) > SQ(1e-6)) - mat->flags |= MAT_FLAG_UNIFORM_SCALE; - /* else no scale at all */ - } - else { - mat->flags |= MAT_FLAG_GENERAL_SCALE; - } - - /* Check for rotation */ - if (SQ(d1) < SQ(1e-6)) { - CROSS3( cp, m, m+4 ); - SUB_3V( cp, cp, (m+8) ); - if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) - mat->flags |= MAT_FLAG_ROTATION; - else - mat->flags |= MAT_FLAG_GENERAL_3D; - } - else { - mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */ - } - } - else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) { - mat->type = MATRIX_PERSPECTIVE; - mat->flags |= MAT_FLAG_GENERAL; - } - else { - mat->type = MATRIX_GENERAL; - mat->flags |= MAT_FLAG_GENERAL; - } -} - -/** - * Analyze a matrix given that its flags are accurate. - * - * This is the more common operation, hopefully. - */ -static void analyse_from_flags( GLmatrix *mat ) -{ - const GLfloat *m = mat->m; - - if (TEST_MAT_FLAGS(mat, 0)) { - mat->type = MATRIX_IDENTITY; - } - else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION | - MAT_FLAG_UNIFORM_SCALE | - MAT_FLAG_GENERAL_SCALE))) { - if ( m[10]==1.0F && m[14]==0.0F ) { - mat->type = MATRIX_2D_NO_ROT; - } - else { - mat->type = MATRIX_3D_NO_ROT; - } - } - else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) { - if ( m[ 8]==0.0F - && m[ 9]==0.0F - && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) { - mat->type = MATRIX_2D; - } - else { - mat->type = MATRIX_3D; - } - } - else if ( m[4]==0.0F && m[12]==0.0F - && m[1]==0.0F && m[13]==0.0F - && m[2]==0.0F && m[6]==0.0F - && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) { - mat->type = MATRIX_PERSPECTIVE; - } - else { - mat->type = MATRIX_GENERAL; - } -} - -/** - * Analyze and update a matrix. - * - * \param mat matrix. - * - * If the matrix type is dirty then calls either analyse_from_scratch() or - * analyse_from_flags() to determine its type, according to whether the flags - * are dirty or not, respectively. If the matrix has an inverse and it's dirty - * then calls matrix_invert(). Finally clears the dirty flags. - */ -void -_math_matrix_analyse( GLmatrix *mat ) -{ - if (mat->flags & MAT_DIRTY_TYPE) { - if (mat->flags & MAT_DIRTY_FLAGS) - analyse_from_scratch( mat ); - else - analyse_from_flags( mat ); - } - - if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) { - matrix_invert( mat ); - mat->flags &= ~MAT_DIRTY_INVERSE; - } - - mat->flags &= ~(MAT_DIRTY_FLAGS | MAT_DIRTY_TYPE); -} - -/*@}*/ - - -/** - * Test if the given matrix preserves vector lengths. - */ -GLboolean -_math_matrix_is_length_preserving( const GLmatrix *m ) -{ - return TEST_MAT_FLAGS( m, MAT_FLAGS_LENGTH_PRESERVING); -} - - -/** - * Test if the given matrix does any rotation. - * (or perhaps if the upper-left 3x3 is non-identity) - */ -GLboolean -_math_matrix_has_rotation( const GLmatrix *m ) -{ - if (m->flags & (MAT_FLAG_GENERAL | - MAT_FLAG_ROTATION | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_PERSPECTIVE)) - return GL_TRUE; - else - return GL_FALSE; -} - - -GLboolean -_math_matrix_is_general_scale( const GLmatrix *m ) -{ - return (m->flags & MAT_FLAG_GENERAL_SCALE) ? GL_TRUE : GL_FALSE; -} - - -GLboolean -_math_matrix_is_dirty( const GLmatrix *m ) -{ - return (m->flags & MAT_DIRTY) ? GL_TRUE : GL_FALSE; -} - - -/**********************************************************************/ -/** \name Matrix setup */ -/*@{*/ - -/** - * Copy a matrix. - * - * \param to destination matrix. - * \param from source matrix. - * - * Copies all fields in GLmatrix, creating an inverse array if necessary. - */ -void -_math_matrix_copy( GLmatrix *to, const GLmatrix *from ) -{ - memcpy( to->m, from->m, sizeof(Identity) ); - to->flags = from->flags; - to->type = from->type; - - if (to->inv != 0) { - if (from->inv == 0) { - matrix_invert( to ); - } - else { - memcpy(to->inv, from->inv, sizeof(GLfloat)*16); - } - } -} - -/** - * Loads a matrix array into GLmatrix. - * - * \param m matrix array. - * \param mat matrix. - * - * Copies \p m into GLmatrix::m and marks the MAT_FLAG_GENERAL and MAT_DIRTY - * flags. - */ -void -_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ) -{ - memcpy( mat->m, m, 16*sizeof(GLfloat) ); - mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY); -} - -/** - * Matrix constructor. - * - * \param m matrix. - * - * Initialize the GLmatrix fields. - */ -void -_math_matrix_ctr( GLmatrix *m ) -{ - m->m = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 ); - if (m->m) - memcpy( m->m, Identity, sizeof(Identity) ); - m->inv = NULL; - m->type = MATRIX_IDENTITY; - m->flags = 0; -} - -/** - * Matrix destructor. - * - * \param m matrix. - * - * Frees the data in a GLmatrix. - */ -void -_math_matrix_dtr( GLmatrix *m ) -{ - if (m->m) { - _mesa_align_free( m->m ); - m->m = NULL; - } - if (m->inv) { - _mesa_align_free( m->inv ); - m->inv = NULL; - } -} - -/** - * Allocate a matrix inverse. - * - * \param m matrix. - * - * Allocates the matrix inverse, GLmatrix::inv, and sets it to Identity. - */ -void -_math_matrix_alloc_inv( GLmatrix *m ) -{ - if (!m->inv) { - m->inv = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 ); - if (m->inv) - memcpy( m->inv, Identity, 16 * sizeof(GLfloat) ); - } -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Matrix transpose */ -/*@{*/ - -/** - * Transpose a GLfloat matrix. - * - * \param to destination array. - * \param from source array. - */ -void -_math_transposef( GLfloat to[16], const GLfloat from[16] ) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - -/** - * Transpose a GLdouble matrix. - * - * \param to destination array. - * \param from source array. - */ -void -_math_transposed( GLdouble to[16], const GLdouble from[16] ) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - -/** - * Transpose a GLdouble matrix and convert to GLfloat. - * - * \param to destination array. - * \param from source array. - */ -void -_math_transposefd( GLfloat to[16], const GLdouble from[16] ) -{ - to[0] = (GLfloat) from[0]; - to[1] = (GLfloat) from[4]; - to[2] = (GLfloat) from[8]; - to[3] = (GLfloat) from[12]; - to[4] = (GLfloat) from[1]; - to[5] = (GLfloat) from[5]; - to[6] = (GLfloat) from[9]; - to[7] = (GLfloat) from[13]; - to[8] = (GLfloat) from[2]; - to[9] = (GLfloat) from[6]; - to[10] = (GLfloat) from[10]; - to[11] = (GLfloat) from[14]; - to[12] = (GLfloat) from[3]; - to[13] = (GLfloat) from[7]; - to[14] = (GLfloat) from[11]; - to[15] = (GLfloat) from[15]; -} - -/*@}*/ - - -/** - * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This - * function is used for transforming clipping plane equations and spotlight - * directions. - * Mathematically, u = v * m. - * Input: v - input vector - * m - transformation matrix - * Output: u - transformed vector - */ -void -_mesa_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] ) -{ - const GLfloat v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; -#define M(row,col) m[row + col*4] - u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0); - u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1); - u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2); - u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3); -#undef M -} diff --git a/src/mesa/math/m_matrix.h b/src/mesa/math/m_matrix.h deleted file mode 100644 index a69afb8..0000000 --- a/src/mesa/math/m_matrix.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file math/m_matrix.h - * Defines basic structures for matrix-handling. - */ - -#ifndef _M_MATRIX_H -#define _M_MATRIX_H - - -#include "main/glheader.h" - - -/** - * \name Symbolic names to some of the entries in the matrix - * - * These are handy for the viewport mapping, which is expressed as a matrix. - */ -/*@{*/ -#define MAT_SX 0 -#define MAT_SY 5 -#define MAT_SZ 10 -#define MAT_TX 12 -#define MAT_TY 13 -#define MAT_TZ 14 -/*@}*/ - - -/** - * Different kinds of 4x4 transformation matrices. - * We use these to select specific optimized vertex transformation routines. - */ -enum GLmatrixtype { - MATRIX_GENERAL, /**< general 4x4 matrix */ - MATRIX_IDENTITY, /**< identity matrix */ - MATRIX_3D_NO_ROT, /**< orthogonal projection and others... */ - MATRIX_PERSPECTIVE, /**< perspective projection matrix */ - MATRIX_2D, /**< 2-D transformation */ - MATRIX_2D_NO_ROT, /**< 2-D scale & translate only */ - MATRIX_3D /**< 3-D transformation */ -} ; - -/** - * Matrix type to represent 4x4 transformation matrices. - */ -typedef struct { - GLfloat *m; /**< 16 matrix elements (16-byte aligned) */ - GLfloat *inv; /**< optional 16-element inverse (16-byte aligned) */ - GLuint flags; /**< possible values determined by (of \link - * MatFlags MAT_FLAG_* flags\endlink) - */ - enum GLmatrixtype type; -} GLmatrix; - - - - -extern void -_math_matrix_ctr( GLmatrix *m ); - -extern void -_math_matrix_dtr( GLmatrix *m ); - -extern void -_math_matrix_alloc_inv( GLmatrix *m ); - -extern void -_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ); - -extern void -_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *b ); - -extern void -_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ); - -extern void -_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); - -extern void -_math_matrix_rotate( GLmatrix *m, GLfloat angle, - GLfloat x, GLfloat y, GLfloat z ); - -extern void -_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); - -extern void -_math_matrix_ortho( GLmatrix *mat, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat nearval, GLfloat farval ); - -extern void -_math_matrix_frustum( GLmatrix *mat, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat nearval, GLfloat farval ); - -extern void -_math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height, - GLfloat zNear, GLfloat zFar, GLfloat depthMax); - -extern void -_math_matrix_set_identity( GLmatrix *dest ); - -extern void -_math_matrix_copy( GLmatrix *to, const GLmatrix *from ); - -extern void -_math_matrix_analyse( GLmatrix *mat ); - -extern void -_math_matrix_print( const GLmatrix *m ); - -extern GLboolean -_math_matrix_is_length_preserving( const GLmatrix *m ); - -extern GLboolean -_math_matrix_has_rotation( const GLmatrix *m ); - -extern GLboolean -_math_matrix_is_general_scale( const GLmatrix *m ); - -extern GLboolean -_math_matrix_is_dirty( const GLmatrix *m ); - - -/** - * \name Related functions that don't actually operate on GLmatrix structs - */ -/*@{*/ - -extern void -_math_transposef( GLfloat to[16], const GLfloat from[16] ); - -extern void -_math_transposed( GLdouble to[16], const GLdouble from[16] ); - -extern void -_math_transposefd( GLfloat to[16], const GLdouble from[16] ); - - -/* - * Transform a point (column vector) by a matrix: Q = M * P - */ -#define TRANSFORM_POINT( Q, M, P ) \ - Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; \ - Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; \ - Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; \ - Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; - - -#define TRANSFORM_POINT3( Q, M, P ) \ - Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; \ - Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; \ - Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; \ - Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; - - -/* - * Transform a normal (row vector) by a matrix: [NX NY NZ] = N * MAT - */ -#define TRANSFORM_NORMAL( TO, N, MAT ) \ -do { \ - TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2]; \ - TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6]; \ - TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10]; \ -} while (0) - - -/** - * Transform a direction by a matrix. - */ -#define TRANSFORM_DIRECTION( TO, DIR, MAT ) \ -do { \ - TO[0] = DIR[0] * MAT[0] + DIR[1] * MAT[4] + DIR[2] * MAT[8]; \ - TO[1] = DIR[0] * MAT[1] + DIR[1] * MAT[5] + DIR[2] * MAT[9]; \ - TO[2] = DIR[0] * MAT[2] + DIR[1] * MAT[6] + DIR[2] * MAT[10];\ -} while (0) - - -extern void -_mesa_transform_vector(GLfloat u[4], const GLfloat v[4], const GLfloat m[16]); - - -/*@}*/ - - -#endif diff --git a/src/mesa/math/m_norm_tmp.h b/src/mesa/math/m_norm_tmp.h deleted file mode 100644 index a20cb05..0000000 --- a/src/mesa/math/m_norm_tmp.h +++ /dev/null @@ -1,390 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - -/* Functions to tranform a vector of normals. This includes applying - * the transformation matrix, rescaling and normalization. - */ - -/* - * mat - the 4x4 transformation matrix - * scale - uniform scale factor of the transformation matrix (not always used) - * in - the source vector of normals - * lengths - length of each incoming normal (may be NULL) (a display list - * optimization) - * dest - the destination vector of normals - */ -static void _XFORMAPI -TAG(transform_normalize_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; - GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; - GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; - GLuint i; - - if (!lengths) { - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 + uy * m1 + uz * m2; - ty = ux * m4 + uy * m5 + uz * m6; - tz = ux * m8 + uy * m9 + uz * m10; - } - { - GLdouble len = tx*tx + ty*ty + tz*tz; - if (len > 1e-20) { - GLfloat scale = INV_SQRTF(len); - out[i][0] = tx * scale; - out[i][1] = ty * scale; - out[i][2] = tz * scale; - } - else { - out[i][0] = out[i][1] = out[i][2] = 0; - } - } - } - } - else { - if (scale != 1.0) { - m0 *= scale, m4 *= scale, m8 *= scale; - m1 *= scale, m5 *= scale, m9 *= scale; - m2 *= scale, m6 *= scale, m10 *= scale; - } - - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 + uy * m1 + uz * m2; - ty = ux * m4 + uy * m5 + uz * m6; - tz = ux * m8 + uy * m9 + uz * m10; - } - { - GLfloat len = lengths[i]; - out[i][0] = tx * len; - out[i][1] = ty * len; - out[i][2] = tz * len; - } - } - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - GLfloat m0 = m[0]; - GLfloat m5 = m[5]; - GLfloat m10 = m[10]; - GLuint i; - - if (!lengths) { - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 ; - ty = uy * m5 ; - tz = uz * m10; - } - { - GLdouble len = tx*tx + ty*ty + tz*tz; - if (len > 1e-20) { - GLfloat scale = INV_SQRTF(len); - out[i][0] = tx * scale; - out[i][1] = ty * scale; - out[i][2] = tz * scale; - } - else { - out[i][0] = out[i][1] = out[i][2] = 0; - } - } - } - } - else { - m0 *= scale; - m5 *= scale; - m10 *= scale; - - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 ; - ty = uy * m5 ; - tz = uz * m10; - } - { - GLfloat len = lengths[i]; - out[i][0] = tx * len; - out[i][1] = ty * len; - out[i][2] = tz * len; - } - } - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - const GLfloat m0 = scale*m[0]; - const GLfloat m5 = scale*m[5]; - const GLfloat m10 = scale*m[10]; - GLuint i; - - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0; - out[i][1] = uy * m5; - out[i][2] = uz * m10; - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(transform_rescale_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - /* Since we are unlikely to have < 3 vertices in the buffer, - * it makes sense to pre-multiply by scale. - */ - const GLfloat *m = mat->inv; - const GLfloat m0 = scale*m[0], m4 = scale*m[4], m8 = scale*m[8]; - const GLfloat m1 = scale*m[1], m5 = scale*m[5], m9 = scale*m[9]; - const GLfloat m2 = scale*m[2], m6 = scale*m[6], m10 = scale*m[10]; - GLuint i; - - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0 + uy * m1 + uz * m2; - out[i][1] = ux * m4 + uy * m5 + uz * m6; - out[i][2] = ux * m8 + uy * m9 + uz * m10; - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(transform_normals_no_rot)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - const GLfloat m0 = m[0]; - const GLfloat m5 = m[5]; - const GLfloat m10 = m[10]; - GLuint i; - - (void) scale; - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0; - out[i][1] = uy * m5; - out[i][2] = uz * m10; - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(transform_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - const GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; - const GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; - const GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; - GLuint i; - - (void) scale; - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0 + uy * m1 + uz * m2; - out[i][1] = ux * m4 + uy * m5 + uz * m6; - out[i][2] = ux * m8 + uy * m9 + uz * m10; - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(normalize_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - GLuint i; - - (void) mat; - (void) scale; - - if (lengths) { - STRIDE_LOOP { - const GLfloat x = from[0], y = from[1], z = from[2]; - GLfloat invlen = lengths[i]; - out[i][0] = x * invlen; - out[i][1] = y * invlen; - out[i][2] = z * invlen; - } - } - else { - STRIDE_LOOP { - const GLfloat x = from[0], y = from[1], z = from[2]; - GLdouble len = x * x + y * y + z * z; - if (len > 1e-50) { - len = INV_SQRTF(len); - out[i][0] = (GLfloat)(x * len); - out[i][1] = (GLfloat)(y * len); - out[i][2] = (GLfloat)(z * len); - } - else { - out[i][0] = x; - out[i][1] = y; - out[i][2] = z; - } - } - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(rescale_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - GLuint i; - - (void) mat; - (void) lengths; - - STRIDE_LOOP { - SCALE_SCALAR_3V( out[i], scale, from ); - } - dest->count = in->count; -} - - -static void _XFORMAPI -TAG(init_c_norm_transform)( void ) -{ - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = - TAG(transform_normals_no_rot); - - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = - TAG(transform_rescale_normals_no_rot); - - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = - TAG(transform_normalize_normals_no_rot); - - _mesa_normal_tab[NORM_TRANSFORM] = - TAG(transform_normals); - - _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = - TAG(transform_rescale_normals); - - _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = - TAG(transform_normalize_normals); - - _mesa_normal_tab[NORM_RESCALE] = - TAG(rescale_normals); - - _mesa_normal_tab[NORM_NORMALIZE] = - TAG(normalize_normals); -} diff --git a/src/mesa/math/m_trans_tmp.h b/src/mesa/math/m_trans_tmp.h deleted file mode 100644 index 08fb4d1..0000000 --- a/src/mesa/math/m_trans_tmp.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \brief Templates for vector conversions. - * \author Keith Whitwell. - */ - -#ifdef DEST_4F -static void DEST_4F( GLfloat (*t)[4], - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - - (void) first; - (void) start; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - if (SZ >= 1) t[i][0] = TRX_4F(f, 0); - if (SZ >= 2) t[i][1] = TRX_4F(f, 1); - if (SZ >= 3) t[i][2] = TRX_4F(f, 2); - if (SZ == 4) t[i][3] = TRX_4F(f, 3); else t[i][3] = 1.0; - } - } -} -#endif - - - -#ifdef DEST_4FN -static void DEST_4FN( GLfloat (*t)[4], - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - - (void) first; - (void) start; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - if (SZ >= 1) t[i][0] = TRX_4FN(f, 0); - if (SZ >= 2) t[i][1] = TRX_4FN(f, 1); - if (SZ >= 3) t[i][2] = TRX_4FN(f, 2); - if (SZ == 4) t[i][3] = TRX_4FN(f, 3); else t[i][3] = 1.0; - } - } -} -#endif - - -#ifdef DEST_3FN -static void DEST_3FN( GLfloat (*t)[3], - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - (void) first; - (void) start; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - t[i][0] = TRX_3FN(f, 0); - t[i][1] = TRX_3FN(f, 1); - t[i][2] = TRX_3FN(f, 2); - } - } -} -#endif - -#ifdef DEST_1F -static void DEST_1F( GLfloat *t, - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - (void) first; - (void) start; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - t[i] = TRX_1F(f, 0); - } - } -} -#endif - -#ifdef DEST_4UB -static void DEST_4UB( GLubyte (*t)[4], - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - (void) start; - (void) first; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - if (SZ >= 1) TRX_UB(t[i][0], f, 0); - if (SZ >= 2) TRX_UB(t[i][1], f, 1); - if (SZ >= 3) TRX_UB(t[i][2], f, 2); - if (SZ == 4) TRX_UB(t[i][3], f, 3); else t[i][3] = 255; - } - } -} -#endif - - -#ifdef DEST_4US -static void DEST_4US( GLushort (*t)[4], - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ((GLubyte *) ptr + SRC_START * stride); - const GLubyte *first = f; - GLuint i; - (void) start; - (void) first; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - if (SZ >= 1) TRX_US(t[i][0], f, 0); - if (SZ >= 2) TRX_US(t[i][1], f, 1); - if (SZ >= 3) TRX_US(t[i][2], f, 2); - if (SZ == 4) TRX_US(t[i][3], f, 3); else t[i][3] = 65535; - } - } -} -#endif - - -#ifdef DEST_1UB -static void DEST_1UB( GLubyte *t, - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - (void) start; - (void) first; - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - TRX_UB(t[i], f, 0); - } - } -} -#endif - - -#ifdef DEST_1UI -static void DEST_1UI( GLuint *t, - CONST void *ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; - const GLubyte *first = f; - GLuint i; - (void) start; - (void) first; - - for (i = DST_START ; i < n ; i++, NEXT_F) { - CHECK { - NEXT_F2; - t[i] = TRX_UI(f, 0); - } - } -} -#endif - - -static void INIT(void) -{ -#ifdef DEST_1UI - ASSERT(SZ == 1); - TAB(_1ui)[SRC_IDX] = DEST_1UI; -#endif -#ifdef DEST_1UB - ASSERT(SZ == 1); - TAB(_1ub)[SRC_IDX] = DEST_1UB; -#endif -#ifdef DEST_1F - ASSERT(SZ == 1); - TAB(_1f)[SRC_IDX] = DEST_1F; -#endif -#ifdef DEST_3FN - ASSERT(SZ == 3); - TAB(_3fn)[SRC_IDX] = DEST_3FN; -#endif -#ifdef DEST_4UB - TAB(_4ub)[SZ][SRC_IDX] = DEST_4UB; -#endif -#ifdef DEST_4US - TAB(_4us)[SZ][SRC_IDX] = DEST_4US; -#endif -#ifdef DEST_4F - TAB(_4f)[SZ][SRC_IDX] = DEST_4F; -#endif -#ifdef DEST_4FN - TAB(_4fn)[SZ][SRC_IDX] = DEST_4FN; -#endif - -} - - -#ifdef INIT -#undef INIT -#endif -#ifdef DEST_1UI -#undef DEST_1UI -#endif -#ifdef DEST_1UB -#undef DEST_1UB -#endif -#ifdef DEST_4UB -#undef DEST_4UB -#endif -#ifdef DEST_4US -#undef DEST_4US -#endif -#ifdef DEST_3FN -#undef DEST_3FN -#endif -#ifdef DEST_4F -#undef DEST_4F -#endif -#ifdef DEST_4FN -#undef DEST_4FN -#endif -#ifdef DEST_1F -#undef DEST_1F -#endif -#ifdef SZ -#undef SZ -#endif -#ifdef TAG -#undef TAG -#endif - diff --git a/src/mesa/math/m_translate.c b/src/mesa/math/m_translate.c deleted file mode 100644 index 51daf7b..0000000 --- a/src/mesa/math/m_translate.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \brief Translate vectors of numbers between various types. - * \author Keith Whitwell. - */ - - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/mtypes.h" /* GLchan hack */ - -#include "m_translate.h" - - - -typedef void (*trans_1f_func)(GLfloat *to, - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - -typedef void (*trans_1ui_func)(GLuint *to, - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - -typedef void (*trans_1ub_func)(GLubyte *to, - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - -typedef void (*trans_4ub_func)(GLubyte (*to)[4], - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - -typedef void (*trans_4us_func)(GLushort (*to)[4], - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - -typedef void (*trans_4f_func)(GLfloat (*to)[4], - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - -typedef void (*trans_3fn_func)(GLfloat (*to)[3], - CONST void *ptr, - GLuint stride, - GLuint start, - GLuint n ); - - - - -#define TYPE_IDX(t) ((t) & 0xf) -#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */ - - -/* This macro is used on other systems, so undefine it for this module */ - -#undef CHECK - -static trans_1f_func _math_trans_1f_tab[MAX_TYPES]; -static trans_1ui_func _math_trans_1ui_tab[MAX_TYPES]; -static trans_1ub_func _math_trans_1ub_tab[MAX_TYPES]; -static trans_3fn_func _math_trans_3fn_tab[MAX_TYPES]; -static trans_4ub_func _math_trans_4ub_tab[5][MAX_TYPES]; -static trans_4us_func _math_trans_4us_tab[5][MAX_TYPES]; -static trans_4f_func _math_trans_4f_tab[5][MAX_TYPES]; -static trans_4f_func _math_trans_4fn_tab[5][MAX_TYPES]; - - -#define PTR_ELT(ptr, elt) (((SRC *)ptr)[elt]) - - -#define TAB(x) _math_trans##x##_tab -#define ARGS GLuint start, GLuint n -#define SRC_START start -#define DST_START 0 -#define STRIDE stride -#define NEXT_F f += stride -#define NEXT_F2 -#define CHECK - - - - -/** - * Translate from GL_BYTE. - */ -#define SRC GLbyte -#define SRC_IDX TYPE_IDX(GL_BYTE) -#define TRX_3FN(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) -#if 1 -#define TRX_4F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) -#else -#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) -#endif -#define TRX_4FN(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_UB(ub, f,n) ub = BYTE_TO_UBYTE( PTR_ELT(f,n) ) -#define TRX_US(ch, f,n) ch = BYTE_TO_USHORT( PTR_ELT(f,n) ) -#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) - - -#define SZ 4 -#define INIT init_trans_4_GLbyte_raw -#define DEST_4F trans_4_GLbyte_4f_raw -#define DEST_4FN trans_4_GLbyte_4fn_raw -#define DEST_4UB trans_4_GLbyte_4ub_raw -#define DEST_4US trans_4_GLbyte_4us_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLbyte_raw -#define DEST_4F trans_3_GLbyte_4f_raw -#define DEST_4FN trans_3_GLbyte_4fn_raw -#define DEST_4UB trans_3_GLbyte_4ub_raw -#define DEST_4US trans_3_GLbyte_4us_raw -#define DEST_3FN trans_3_GLbyte_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLbyte_raw -#define DEST_4F trans_2_GLbyte_4f_raw -#define DEST_4FN trans_2_GLbyte_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLbyte_raw -#define DEST_4F trans_1_GLbyte_4f_raw -#define DEST_4FN trans_1_GLbyte_4fn_raw -#define DEST_1UB trans_1_GLbyte_1ub_raw -#define DEST_1UI trans_1_GLbyte_1ui_raw -#include "m_trans_tmp.h" - -#undef SRC -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI -#undef SRC_IDX - - -/** - * Translate from GL_UNSIGNED_BYTE. - */ -#define SRC GLubyte -#define SRC_IDX TYPE_IDX(GL_UNSIGNED_BYTE) -#define TRX_3FN(f,n) UBYTE_TO_FLOAT(PTR_ELT(f,n)) -#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) -#define TRX_4FN(f,n) UBYTE_TO_FLOAT(PTR_ELT(f,n)) -#define TRX_UB(ub, f,n) ub = PTR_ELT(f,n) -#define TRX_US(us, f,n) us = UBYTE_TO_USHORT(PTR_ELT(f,n)) -#define TRX_UI(f,n) (GLuint)PTR_ELT(f,n) - -/* 4ub->4ub handled in special case below. - */ -#define SZ 4 -#define INIT init_trans_4_GLubyte_raw -#define DEST_4F trans_4_GLubyte_4f_raw -#define DEST_4FN trans_4_GLubyte_4fn_raw -#define DEST_4US trans_4_GLubyte_4us_raw -#include "m_trans_tmp.h" - - -#define SZ 3 -#define INIT init_trans_3_GLubyte_raw -#define DEST_4UB trans_3_GLubyte_4ub_raw -#define DEST_4US trans_3_GLubyte_4us_raw -#define DEST_3FN trans_3_GLubyte_3fn_raw -#define DEST_4F trans_3_GLubyte_4f_raw -#define DEST_4FN trans_3_GLubyte_4fn_raw -#include "m_trans_tmp.h" - - -#define SZ 1 -#define INIT init_trans_1_GLubyte_raw -#define DEST_1UI trans_1_GLubyte_1ui_raw -#define DEST_1UB trans_1_GLubyte_1ub_raw -#include "m_trans_tmp.h" - -#undef SRC -#undef SRC_IDX -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI - - -/* GL_SHORT - */ -#define SRC GLshort -#define SRC_IDX TYPE_IDX(GL_SHORT) -#define TRX_3FN(f,n) SHORT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) -#define TRX_4FN(f,n) SHORT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_UB(ub, f,n) ub = SHORT_TO_UBYTE(PTR_ELT(f,n)) -#define TRX_US(us, f,n) us = SHORT_TO_USHORT(PTR_ELT(f,n)) -#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) - - -#define SZ 4 -#define INIT init_trans_4_GLshort_raw -#define DEST_4F trans_4_GLshort_4f_raw -#define DEST_4FN trans_4_GLshort_4fn_raw -#define DEST_4UB trans_4_GLshort_4ub_raw -#define DEST_4US trans_4_GLshort_4us_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLshort_raw -#define DEST_4F trans_3_GLshort_4f_raw -#define DEST_4FN trans_3_GLshort_4fn_raw -#define DEST_4UB trans_3_GLshort_4ub_raw -#define DEST_4US trans_3_GLshort_4us_raw -#define DEST_3FN trans_3_GLshort_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLshort_raw -#define DEST_4F trans_2_GLshort_4f_raw -#define DEST_4FN trans_2_GLshort_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLshort_raw -#define DEST_4F trans_1_GLshort_4f_raw -#define DEST_4FN trans_1_GLshort_4fn_raw -#define DEST_1UB trans_1_GLshort_1ub_raw -#define DEST_1UI trans_1_GLshort_1ui_raw -#include "m_trans_tmp.h" - - -#undef SRC -#undef SRC_IDX -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI - - -/* GL_UNSIGNED_SHORT - */ -#define SRC GLushort -#define SRC_IDX TYPE_IDX(GL_UNSIGNED_SHORT) -#define TRX_3FN(f,n) USHORT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) -#define TRX_4FN(f,n) USHORT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_UB(ub,f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 8) -#define TRX_US(us,f,n) us = PTR_ELT(f,n) -#define TRX_UI(f,n) (GLuint) PTR_ELT(f,n) - - -#define SZ 4 -#define INIT init_trans_4_GLushort_raw -#define DEST_4F trans_4_GLushort_4f_raw -#define DEST_4FN trans_4_GLushort_4fn_raw -#define DEST_4UB trans_4_GLushort_4ub_raw -#define DEST_4US trans_4_GLushort_4us_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLushort_raw -#define DEST_4F trans_3_GLushort_4f_raw -#define DEST_4FN trans_3_GLushort_4fn_raw -#define DEST_4UB trans_3_GLushort_4ub_raw -#define DEST_4US trans_3_GLushort_4us_raw -#define DEST_3FN trans_3_GLushort_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLushort_raw -#define DEST_4F trans_2_GLushort_4f_raw -#define DEST_4FN trans_2_GLushort_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLushort_raw -#define DEST_4F trans_1_GLushort_4f_raw -#define DEST_4FN trans_1_GLushort_4fn_raw -#define DEST_1UB trans_1_GLushort_1ub_raw -#define DEST_1UI trans_1_GLushort_1ui_raw -#include "m_trans_tmp.h" - -#undef SRC -#undef SRC_IDX -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI - - -/* GL_INT - */ -#define SRC GLint -#define SRC_IDX TYPE_IDX(GL_INT) -#define TRX_3FN(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) -#define TRX_4FN(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_UB(ub, f,n) ub = INT_TO_UBYTE(PTR_ELT(f,n)) -#define TRX_US(us, f,n) us = INT_TO_USHORT(PTR_ELT(f,n)) -#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) - - -#define SZ 4 -#define INIT init_trans_4_GLint_raw -#define DEST_4F trans_4_GLint_4f_raw -#define DEST_4FN trans_4_GLint_4fn_raw -#define DEST_4UB trans_4_GLint_4ub_raw -#define DEST_4US trans_4_GLint_4us_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLint_raw -#define DEST_4F trans_3_GLint_4f_raw -#define DEST_4FN trans_3_GLint_4fn_raw -#define DEST_4UB trans_3_GLint_4ub_raw -#define DEST_4US trans_3_GLint_4us_raw -#define DEST_3FN trans_3_GLint_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLint_raw -#define DEST_4F trans_2_GLint_4f_raw -#define DEST_4FN trans_2_GLint_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLint_raw -#define DEST_4F trans_1_GLint_4f_raw -#define DEST_4FN trans_1_GLint_4fn_raw -#define DEST_1UB trans_1_GLint_1ub_raw -#define DEST_1UI trans_1_GLint_1ui_raw -#include "m_trans_tmp.h" - - -#undef SRC -#undef SRC_IDX -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI - - -/* GL_UNSIGNED_INT - */ -#define SRC GLuint -#define SRC_IDX TYPE_IDX(GL_UNSIGNED_INT) -#define TRX_3FN(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) -#define TRX_4FN(f,n) UINT_TO_FLOAT( PTR_ELT(f,n) ) -#define TRX_UB(ub, f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 24) -#define TRX_US(us, f,n) us = (GLshort) (PTR_ELT(f,n) >> 16) -#define TRX_UI(f,n) PTR_ELT(f,n) - - -#define SZ 4 -#define INIT init_trans_4_GLuint_raw -#define DEST_4F trans_4_GLuint_4f_raw -#define DEST_4FN trans_4_GLuint_4fn_raw -#define DEST_4UB trans_4_GLuint_4ub_raw -#define DEST_4US trans_4_GLuint_4us_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLuint_raw -#define DEST_4F trans_3_GLuint_4f_raw -#define DEST_4FN trans_3_GLuint_4fn_raw -#define DEST_4UB trans_3_GLuint_4ub_raw -#define DEST_4US trans_3_GLuint_4us_raw -#define DEST_3FN trans_3_GLuint_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLuint_raw -#define DEST_4F trans_2_GLuint_4f_raw -#define DEST_4FN trans_2_GLuint_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLuint_raw -#define DEST_4F trans_1_GLuint_4f_raw -#define DEST_4FN trans_1_GLuint_4fn_raw -#define DEST_1UB trans_1_GLuint_1ub_raw -#define DEST_1UI trans_1_GLuint_1ui_raw -#include "m_trans_tmp.h" - -#undef SRC -#undef SRC_IDX -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI - - -/* GL_DOUBLE - */ -#define SRC GLdouble -#define SRC_IDX TYPE_IDX(GL_DOUBLE) -#define TRX_3FN(f,n) (GLfloat) PTR_ELT(f,n) -#define TRX_4F(f,n) (GLfloat) PTR_ELT(f,n) -#define TRX_4FN(f,n) (GLfloat) PTR_ELT(f,n) -#define TRX_UB(ub,f,n) UNCLAMPED_FLOAT_TO_UBYTE(ub, PTR_ELT(f,n)) -#define TRX_US(us,f,n) UNCLAMPED_FLOAT_TO_USHORT(us, PTR_ELT(f,n)) -#define TRX_UI(f,n) (GLuint) (GLint) PTR_ELT(f,n) -#define TRX_1F(f,n) (GLfloat) PTR_ELT(f,n) - - -#define SZ 4 -#define INIT init_trans_4_GLdouble_raw -#define DEST_4F trans_4_GLdouble_4f_raw -#define DEST_4FN trans_4_GLdouble_4fn_raw -#define DEST_4UB trans_4_GLdouble_4ub_raw -#define DEST_4US trans_4_GLdouble_4us_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLdouble_raw -#define DEST_4F trans_3_GLdouble_4f_raw -#define DEST_4FN trans_3_GLdouble_4fn_raw -#define DEST_4UB trans_3_GLdouble_4ub_raw -#define DEST_4US trans_3_GLdouble_4us_raw -#define DEST_3FN trans_3_GLdouble_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLdouble_raw -#define DEST_4F trans_2_GLdouble_4f_raw -#define DEST_4FN trans_2_GLdouble_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLdouble_raw -#define DEST_4F trans_1_GLdouble_4f_raw -#define DEST_4FN trans_1_GLdouble_4fn_raw -#define DEST_1UB trans_1_GLdouble_1ub_raw -#define DEST_1UI trans_1_GLdouble_1ui_raw -#define DEST_1F trans_1_GLdouble_1f_raw -#include "m_trans_tmp.h" - -#undef SRC -#undef SRC_IDX - -/* GL_FLOAT - */ -#define SRC GLfloat -#define SRC_IDX TYPE_IDX(GL_FLOAT) -#define SZ 4 -#define INIT init_trans_4_GLfloat_raw -#define DEST_4UB trans_4_GLfloat_4ub_raw -#define DEST_4US trans_4_GLfloat_4us_raw -#define DEST_4F trans_4_GLfloat_4f_raw -#define DEST_4FN trans_4_GLfloat_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 3 -#define INIT init_trans_3_GLfloat_raw -#define DEST_4F trans_3_GLfloat_4f_raw -#define DEST_4FN trans_3_GLfloat_4fn_raw -#define DEST_4UB trans_3_GLfloat_4ub_raw -#define DEST_4US trans_3_GLfloat_4us_raw -#define DEST_3FN trans_3_GLfloat_3fn_raw -#include "m_trans_tmp.h" - -#define SZ 2 -#define INIT init_trans_2_GLfloat_raw -#define DEST_4F trans_2_GLfloat_4f_raw -#define DEST_4FN trans_2_GLfloat_4fn_raw -#include "m_trans_tmp.h" - -#define SZ 1 -#define INIT init_trans_1_GLfloat_raw -#define DEST_4F trans_1_GLfloat_4f_raw -#define DEST_4FN trans_1_GLfloat_4fn_raw -#define DEST_1UB trans_1_GLfloat_1ub_raw -#define DEST_1UI trans_1_GLfloat_1ui_raw -#define DEST_1F trans_1_GLfloat_1f_raw - -#include "m_trans_tmp.h" - -#undef SRC -#undef SRC_IDX -#undef TRX_3FN -#undef TRX_4F -#undef TRX_4FN -#undef TRX_UB -#undef TRX_US -#undef TRX_UI - - -static void trans_4_GLubyte_4ub_raw(GLubyte (*t)[4], - CONST void *Ptr, - GLuint stride, - ARGS ) -{ - const GLubyte *f = (GLubyte *) Ptr + SRC_START * stride; - GLuint i; - - if (((((uintptr_t) f | (uintptr_t) stride)) & 3L) == 0L) { - /* Aligned. - */ - for (i = DST_START ; i < n ; i++, f += stride) { - COPY_4UBV( t[i], f ); - } - } else { - for (i = DST_START ; i < n ; i++, f += stride) { - t[i][0] = f[0]; - t[i][1] = f[1]; - t[i][2] = f[2]; - t[i][3] = f[3]; - } - } -} - - -static void init_translate_raw(void) -{ - memset( TAB(_1ui), 0, sizeof(TAB(_1ui)) ); - memset( TAB(_1ub), 0, sizeof(TAB(_1ub)) ); - memset( TAB(_3fn), 0, sizeof(TAB(_3fn)) ); - memset( TAB(_4ub), 0, sizeof(TAB(_4ub)) ); - memset( TAB(_4us), 0, sizeof(TAB(_4us)) ); - memset( TAB(_4f), 0, sizeof(TAB(_4f)) ); - memset( TAB(_4fn), 0, sizeof(TAB(_4fn)) ); - - init_trans_4_GLbyte_raw(); - init_trans_3_GLbyte_raw(); - init_trans_2_GLbyte_raw(); - init_trans_1_GLbyte_raw(); - init_trans_1_GLubyte_raw(); - init_trans_3_GLubyte_raw(); - init_trans_4_GLubyte_raw(); - init_trans_4_GLshort_raw(); - init_trans_3_GLshort_raw(); - init_trans_2_GLshort_raw(); - init_trans_1_GLshort_raw(); - init_trans_4_GLushort_raw(); - init_trans_3_GLushort_raw(); - init_trans_2_GLushort_raw(); - init_trans_1_GLushort_raw(); - init_trans_4_GLint_raw(); - init_trans_3_GLint_raw(); - init_trans_2_GLint_raw(); - init_trans_1_GLint_raw(); - init_trans_4_GLuint_raw(); - init_trans_3_GLuint_raw(); - init_trans_2_GLuint_raw(); - init_trans_1_GLuint_raw(); - init_trans_4_GLdouble_raw(); - init_trans_3_GLdouble_raw(); - init_trans_2_GLdouble_raw(); - init_trans_1_GLdouble_raw(); - init_trans_4_GLfloat_raw(); - init_trans_3_GLfloat_raw(); - init_trans_2_GLfloat_raw(); - init_trans_1_GLfloat_raw(); - - TAB(_4ub)[4][TYPE_IDX(GL_UNSIGNED_BYTE)] = trans_4_GLubyte_4ub_raw; -} - - -#undef TAB -#ifdef CLASS -#undef CLASS -#endif -#undef ARGS -#undef CHECK -#undef SRC_START -#undef DST_START -#undef NEXT_F -#undef NEXT_F2 - - - - - -void _math_init_translate( void ) -{ - init_translate_raw(); -} - - -/** - * Translate vector of values to GLfloat [1]. - */ -void _math_trans_1f(GLfloat *to, - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ) -{ - _math_trans_1f_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - -/** - * Translate vector of values to GLuint [1]. - */ -void _math_trans_1ui(GLuint *to, - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ) -{ - _math_trans_1ui_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - -/** - * Translate vector of values to GLubyte [1]. - */ -void _math_trans_1ub(GLubyte *to, - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ) -{ - _math_trans_1ub_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - - -/** - * Translate vector of values to GLubyte [4]. - */ -void _math_trans_4ub(GLubyte (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ) -{ - _math_trans_4ub_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - -/** - * Translate vector of values to GLchan [4]. - */ -void _math_trans_4chan( GLchan (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ) -{ -#if CHAN_TYPE == GL_UNSIGNED_BYTE - _math_trans_4ub( to, ptr, stride, type, size, start, n ); -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - _math_trans_4us( to, ptr, stride, type, size, start, n ); -#elif CHAN_TYPE == GL_FLOAT - _math_trans_4fn( to, ptr, stride, type, size, start, n ); -#endif -} - -/** - * Translate vector of values to GLushort [4]. - */ -void _math_trans_4us(GLushort (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ) -{ - _math_trans_4us_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - -/** - * Translate vector of values to GLfloat [4]. - */ -void _math_trans_4f(GLfloat (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ) -{ - _math_trans_4f_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - -/** - * Translate vector of values to GLfloat[4], normalized to [-1, 1]. - */ -void _math_trans_4fn(GLfloat (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ) -{ - _math_trans_4fn_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); -} - -/** - * Translate vector of values to GLfloat[3], normalized to [-1, 1]. - */ -void _math_trans_3fn(GLfloat (*to)[3], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ) -{ - _math_trans_3fn_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); -} diff --git a/src/mesa/math/m_translate.h b/src/mesa/math/m_translate.h deleted file mode 100644 index 5804103..0000000 --- a/src/mesa/math/m_translate.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef _M_TRANSLATE_H_ -#define _M_TRANSLATE_H_ - -#include "main/compiler.h" -#include "main/glheader.h" -#include "main/mtypes.h" /* hack for GLchan */ - - -/** - * Array translation. - * For example, convert array of GLushort[3] to GLfloat[4]. - * The function name specifies the destination format/size. - * \param to the destination address - * \param ptr the source address - * \param stride the source stride (in bytes) between elements - * \param type the source datatype (GL_SHORT, GL_UNSIGNED_INT, etc) - * \param size number of values per element in source array (1,2,3 or 4) - * \param start first element in source array to convert - * \param n number of elements to convert - * - * Note: "element" means a tuple like GLfloat[3] or GLubyte[4]. - */ - - -extern void _math_trans_1f(GLfloat *to, - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ); - -extern void _math_trans_1ui(GLuint *to, - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ); - -extern void _math_trans_1ub(GLubyte *to, - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ); - -extern void _math_trans_4ub(GLubyte (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ); - -extern void _math_trans_4chan( GLchan (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ); - -extern void _math_trans_4us(GLushort (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ); - -/** Convert to floats w/out normalization (i.e. just cast) */ -extern void _math_trans_4f(GLfloat (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ); - -/** Convert to normalized floats in [0,1] or [-1, 1] */ -extern void _math_trans_4fn(GLfloat (*to)[4], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ); - -extern void _math_trans_3fn(GLfloat (*to)[3], - CONST void *ptr, - GLuint stride, - GLenum type, - GLuint start, - GLuint n ); - -extern void _math_init_translate( void ); - - -#endif diff --git a/src/mesa/math/m_vector.c b/src/mesa/math/m_vector.c deleted file mode 100644 index 4bded31..0000000 --- a/src/mesa/math/m_vector.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/macros.h" - -#include "m_vector.h" - - - -/** - * Given a vector [count][4] of floats, set all the [][elt] values - * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). - */ -void -_mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) -{ - static const GLubyte elem_bits[4] = { - VEC_DIRTY_0, - VEC_DIRTY_1, - VEC_DIRTY_2, - VEC_DIRTY_3 - }; - static const GLfloat clean[4] = { 0, 0, 0, 1 }; - const GLfloat v = clean[elt]; - GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; - GLuint i; - - for (i = 0; i < count; i++) - data[i][elt] = v; - - vec->flags &= ~elem_bits[elt]; -} - - -static const GLubyte size_bits[5] = { - 0, - VEC_SIZE_1, - VEC_SIZE_2, - VEC_SIZE_3, - VEC_SIZE_4, -}; - - -/** - * Initialize GLvector objects. - * \param v the vector object to initialize. - * \param flags bitwise-OR of VEC_* flags - * \param storage pointer to storage for the vector's data - */ -void -_mesa_vector4f_init( GLvector4f *v, GLbitfield flags, GLfloat (*storage)[4] ) -{ - v->stride = 4 * sizeof(GLfloat); - v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ - v->data = storage; - v->start = (GLfloat *) storage; - v->count = 0; - v->flags = size_bits[4] | flags; -} - - -/** - * Initialize GLvector objects and allocate storage. - * \param v the vector object - * \param flags bitwise-OR of VEC_* flags - * \param count number of elements to allocate in vector - * \param alignment desired memory alignment for the data (in bytes) - */ -void -_mesa_vector4f_alloc( GLvector4f *v, GLbitfield flags, GLuint count, - GLuint alignment ) -{ - v->stride = 4 * sizeof(GLfloat); - v->size = 2; - v->storage = _mesa_align_malloc( count * 4 * sizeof(GLfloat), alignment ); - v->storage_count = count; - v->start = (GLfloat *) v->storage; - v->data = (GLfloat (*)[4]) v->storage; - v->count = 0; - v->flags = size_bits[4] | flags | VEC_MALLOC; -} - - -/** - * Vector deallocation. Free whatever memory is pointed to by the - * vector's storage field if the VEC_MALLOC flag is set. - * DO NOT free the GLvector object itself, though. - */ -void -_mesa_vector4f_free( GLvector4f *v ) -{ - if (v->flags & VEC_MALLOC) { - _mesa_align_free( v->storage ); - v->data = NULL; - v->start = NULL; - v->storage = NULL; - v->flags &= ~VEC_MALLOC; - } -} - - -/** - * For debugging - */ -void -_mesa_vector4f_print( const GLvector4f *v, const GLubyte *cullmask, - GLboolean culling ) -{ - static const GLfloat c[4] = { 0, 0, 0, 1 }; - static const char *templates[5] = { - "%d:\t0, 0, 0, 1\n", - "%d:\t%f, 0, 0, 1\n", - "%d:\t%f, %f, 0, 1\n", - "%d:\t%f, %f, %f, 1\n", - "%d:\t%f, %f, %f, %f\n" - }; - - const char *t = templates[v->size]; - GLfloat *d = (GLfloat *)v->data; - GLuint j, i = 0, count; - - printf("data-start\n"); - for (; d != v->start; STRIDE_F(d, v->stride), i++) - printf(t, i, d[0], d[1], d[2], d[3]); - - printf("start-count(%u)\n", v->count); - count = i + v->count; - - if (culling) { - for (; i < count; STRIDE_F(d, v->stride), i++) - if (cullmask[i]) - printf(t, i, d[0], d[1], d[2], d[3]); - } - else { - for (; i < count; STRIDE_F(d, v->stride), i++) - printf(t, i, d[0], d[1], d[2], d[3]); - } - - for (j = v->size; j < 4; j++) { - if ((v->flags & (1<<j)) == 0) { - - printf("checking col %u is clean as advertised ", j); - - for (i = 0, d = (GLfloat *) v->data; - i < count && d[j] == c[j]; - i++, STRIDE_F(d, v->stride)) { - /* no-op */ - } - - if (i == count) - printf(" --> ok\n"); - else - printf(" --> Failed at %u ******\n", i); - } - } -} diff --git a/src/mesa/math/m_vector.h b/src/mesa/math/m_vector.h deleted file mode 100644 index 71281d5..0000000 --- a/src/mesa/math/m_vector.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -#ifndef _M_VECTOR_H_ -#define _M_VECTOR_H_ - -#include "main/glheader.h" - - -#define VEC_DIRTY_0 0x1 -#define VEC_DIRTY_1 0x2 -#define VEC_DIRTY_2 0x4 -#define VEC_DIRTY_3 0x8 -#define VEC_MALLOC 0x10 /* storage field points to self-allocated mem*/ -#define VEC_NOT_WRITEABLE 0x40 /* writable elements to hold clipped data */ -#define VEC_BAD_STRIDE 0x100 /* matches tnl's prefered stride */ - - -#define VEC_SIZE_1 VEC_DIRTY_0 -#define VEC_SIZE_2 (VEC_DIRTY_0|VEC_DIRTY_1) -#define VEC_SIZE_3 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2) -#define VEC_SIZE_4 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2|VEC_DIRTY_3) - - - -/** - * Wrap all the information about vectors up in a struct. Has - * additional fields compared to the other vectors to help us track of - * different vertex sizes, and whether we need to clean columns out - * because they contain non-(0,0,0,1) values. - * - * The start field is used to reserve data for copied vertices at the - * end of _mesa_transform_vb, and avoids the need for a multiplication in - * the transformation routines. - */ -typedef struct { - GLfloat (*data)[4]; /**< may be malloc'd or point to client data */ - GLfloat *start; /**< points somewhere inside of <data> */ - GLuint count; /**< size of the vector (in elements) */ - GLuint stride; /**< stride from one element to the next (in bytes) */ - GLuint size; /**< 2-4 for vertices and 1-4 for texcoords */ - GLbitfield flags; /**< bitmask of VEC_x flags */ - void *storage; /**< self-allocated storage */ - GLuint storage_count; /**< storage size in elements */ -} GLvector4f; - - -extern void _mesa_vector4f_init( GLvector4f *v, GLbitfield flags, - GLfloat (*storage)[4] ); -extern void _mesa_vector4f_alloc( GLvector4f *v, GLbitfield flags, - GLuint count, GLuint alignment ); -extern void _mesa_vector4f_free( GLvector4f *v ); -extern void _mesa_vector4f_print( const GLvector4f *v, const GLubyte *, GLboolean ); -extern void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt ); - - -/** - * Given vector <v>, return a pointer (cast to <type *> to the <i>-th element. - * - * End up doing a lot of slow imuls if not careful. - */ -#define VEC_ELT( v, type, i ) \ - ( (type *) ( ((GLbyte *) ((v)->data)) + (i) * (v)->stride) ) - - -#endif diff --git a/src/mesa/math/m_xform.c b/src/mesa/math/m_xform.c deleted file mode 100644 index 369f2c6..0000000 --- a/src/mesa/math/m_xform.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/* - * Matrix/vertex/vector transformation stuff - * - * - * NOTES: - * 1. 4x4 transformation matrices are stored in memory in column major order. - * 2. Points/vertices are to be thought of as column vectors. - * 3. Transformation of a point p by a matrix M is: p' = M * p - */ - -#include "main/glheader.h" -#include "main/macros.h" - -#include "m_eval.h" -#include "m_matrix.h" -#include "m_translate.h" -#include "m_xform.h" - - -#ifdef DEBUG_MATH -#include "m_debug.h" -#endif - -#ifdef USE_X86_ASM -#include "x86/common_x86_asm.h" -#endif - -#ifdef USE_X86_64_ASM -#include "x86-64/x86-64.h" -#endif - -#ifdef USE_SPARC_ASM -#include "sparc/sparc.h" -#endif - -#ifdef USE_PPC_ASM -#include "ppc/common_ppc_features.h" -#endif - -clip_func _mesa_clip_tab[5]; -clip_func _mesa_clip_np_tab[5]; -dotprod_func _mesa_dotprod_tab[5]; -vec_copy_func _mesa_copy_tab[0x10]; -normal_func _mesa_normal_tab[0xf]; -transform_func *_mesa_transform_tab[5]; - - -/* Raw data format used for: - * - Object-to-eye transform prior to culling, although this too - * could be culled under some circumstances. - * - Eye-to-clip transform (via the function above). - * - Cliptesting - * - And everything else too, if culling happens to be disabled. - * - * GH: It's used for everything now, as clipping/culling is done - * elsewhere (most often by the driver itself). - */ -#define TAG(x) x -#define TAG2(x,y) x##y -#define STRIDE_LOOP for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) -#define LOOP for ( i = 0 ; i < n ; i++ ) -#define ARGS -#include "m_xform_tmp.h" -#include "m_clip_tmp.h" -#include "m_norm_tmp.h" -#include "m_dotprod_tmp.h" -#include "m_copy_tmp.h" -#undef TAG -#undef TAG2 -#undef LOOP -#undef ARGS - - -/* - * This is called only once. It initializes several tables with pointers - * to optimized transformation functions. This is where we can test for - * AMD 3Dnow! capability, Intel SSE, etc. and hook in the right code. - */ -void -_math_init_transformation( void ) -{ - init_c_transformations(); - init_c_norm_transform(); - init_c_cliptest(); - init_copy0(); - init_dotprod(); - -#ifdef DEBUG_MATH - _math_test_all_transform_functions( "default" ); - _math_test_all_normal_transform_functions( "default" ); - _math_test_all_cliptest_functions( "default" ); -#endif - -#ifdef USE_X86_ASM - _mesa_init_all_x86_transform_asm(); -#elif defined( USE_SPARC_ASM ) - _mesa_init_all_sparc_transform_asm(); -#elif defined( USE_PPC_ASM ) - _mesa_init_all_ppc_transform_asm(); -#elif defined( USE_X86_64_ASM ) - _mesa_init_all_x86_64_transform_asm(); -#endif -} diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h deleted file mode 100644 index 14ac956..0000000 --- a/src/mesa/math/m_xform.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef _M_XFORM_H -#define _M_XFORM_H - - -#include "main/compiler.h" -#include "main/glheader.h" -#include "math/m_matrix.h" -#include "math/m_vector.h" - -#ifdef USE_X86_ASM -#define _XFORMAPI _ASMAPI -#define _XFORMAPIP _ASMAPIP -#else -#define _XFORMAPI -#define _XFORMAPIP * -#endif - - -extern void -_math_init_transformation(void); -extern void -init_c_cliptest(void); - -/* KW: Clip functions now do projective divide as well. The projected - * coordinates are very useful to us because they let us cull - * backfaces and eliminate vertices from lighting, fogging, etc - * calculations. Despite the fact that this divide could be done one - * day in hardware, we would still have a reason to want to do it here - * as long as those other calculations remain in software. - * - * Clipping is a convenient place to do the divide on x86 as it should be - * possible to overlap with integer outcode calculations. - * - * There are two cases where we wouldn't want to do the divide in cliptest: - * - When we aren't clipping. We still might want to cull backfaces - * so the divide should be done elsewhere. This currently never - * happens. - * - * - When culling isn't likely to help us, such as when the GL culling - * is disabled and we not lighting or are only lighting - * one-sided. In this situation, backface determination provides - * us with no useful information. A tricky case to detect is when - * all input data is already culled, although hopefully the - * application wouldn't turn on culling in such cases. - * - * We supply a buffer to hold the [x/w,y/w,z/w,1/w] values which - * are the result of the projection. This is only used in the - * 4-vector case - in other cases, we just use the clip coordinates - * as the projected coordinates - they are identical. - * - * This is doubly convenient because it means the Win[] array is now - * of the same stride as all the others, so I can now turn map_vertices - * into a straight-forward matrix transformation, with asm acceleration - * automatically available. - */ - -/* Vertex buffer clipping flags - */ -#define CLIP_RIGHT_SHIFT 0 -#define CLIP_LEFT_SHIFT 1 -#define CLIP_TOP_SHIFT 2 -#define CLIP_BOTTOM_SHIFT 3 -#define CLIP_NEAR_SHIFT 4 -#define CLIP_FAR_SHIFT 5 - -#define CLIP_RIGHT_BIT 0x01 -#define CLIP_LEFT_BIT 0x02 -#define CLIP_TOP_BIT 0x04 -#define CLIP_BOTTOM_BIT 0x08 -#define CLIP_NEAR_BIT 0x10 -#define CLIP_FAR_BIT 0x20 -#define CLIP_USER_BIT 0x40 -#define CLIP_CULL_BIT 0x80 -#define CLIP_FRUSTUM_BITS 0x3f - - -typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip, - GLvector4f *vProj, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ); - -typedef void (*dotprod_func)( GLfloat *out, - GLuint out_stride, - CONST GLvector4f *coord_vec, - CONST GLfloat plane[4] ); - -typedef void (*vec_copy_func)( GLvector4f *to, - CONST GLvector4f *from ); - - - -/* - * Functions for transformation of normals in the VB. - */ -typedef void (_NORMAPIP normal_func)( CONST GLmatrix *mat, - GLfloat scale, - CONST GLvector4f *in, - CONST GLfloat lengths[], - GLvector4f *dest ); - - -/* Flags for selecting a normal transformation function. - */ -#define NORM_RESCALE 0x1 /* apply the scale factor */ -#define NORM_NORMALIZE 0x2 /* normalize */ -#define NORM_TRANSFORM 0x4 /* apply the transformation matrix */ -#define NORM_TRANSFORM_NO_ROT 0x8 /* apply the transformation matrix */ - - - - -/* KW: New versions of the transform function allow a mask array - * specifying that individual vector transform should be skipped - * when the mask byte is zero. This is always present as a - * parameter, to allow a unified interface. - */ -typedef void (_XFORMAPIP transform_func)( GLvector4f *to_vec, - CONST GLfloat m[16], - CONST GLvector4f *from_vec ); - - -extern dotprod_func _mesa_dotprod_tab[5]; -extern vec_copy_func _mesa_copy_tab[0x10]; -extern vec_copy_func _mesa_copy_clean_tab[5]; -extern clip_func _mesa_clip_tab[5]; -extern clip_func _mesa_clip_np_tab[5]; -extern normal_func _mesa_normal_tab[0xf]; - -/* Use of 2 layers of linked 1-dimensional arrays to reduce - * cost of lookup. - */ -extern transform_func *_mesa_transform_tab[5]; - - - -#define TransformRaw( to, mat, from ) \ - ( _mesa_transform_tab[(from)->size][(mat)->type]( to, (mat)->m, from ), \ - (to) ) - - -#endif diff --git a/src/mesa/math/m_xform_tmp.h b/src/mesa/math/m_xform_tmp.h deleted file mode 100644 index e938377..0000000 --- a/src/mesa/math/m_xform_tmp.h +++ /dev/null @@ -1,810 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -/*---------------------------------------------------------------------- - * Begin Keith's new code - * - *---------------------------------------------------------------------- - */ - -/* KW: Fixed stride, now measured in bytes as is the OpenGL array stride. - */ - -/* KW: These are now parameterized to produce two versions, one - * which transforms all incoming points, and a second which - * takes notice of a cullmask array, and only transforms - * unculled vertices. - */ - -/* KW: 1-vectors can sneak into the texture pipeline via the array - * interface. These functions are here because I want consistant - * treatment of the vertex sizes and a lazy strategy for - * cleaning unused parts of the vector, and so as not to exclude - * them from the vertex array interface. - * - * Under our current analysis of matrices, there is no way that - * the product of a matrix and a 1-vector can remain a 1-vector, - * with the exception of the identity transform. - */ - -/* KW: No longer zero-pad outgoing vectors. Now that external - * vectors can get into the pipeline we cannot ever assume - * that there is more to a vector than indicated by its - * size. - */ - -/* KW: Now uses clipmask and a flag to allow us to skip both/either - * cliped and/or culled vertices. - */ - -/* GH: Not any more -- it's easier (and faster) to just process the - * entire vector. Clipping and culling are handled further down - * the pipe, most often during or after the conversion to some - * driver-specific vertex format. - */ - -static void _XFORMAPI -TAG(transform_points1_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m12 = m[12]; - const GLfloat m1 = m[1], m13 = m[13]; - const GLfloat m2 = m[2], m14 = m[14]; - const GLfloat m3 = m[3], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m1 * ox + m13; - to[i][2] = m2 * ox + m14; - to[i][3] = m3 * ox + m15; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points1_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLuint count = from_vec->count; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - } - to_vec->size = 1; - to_vec->flags |= VEC_SIZE_1; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points1_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m1 * ox + m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points1_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m1 * ox + m13; - to[i][2] = m2 * ox + m14; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - - -static void _XFORMAPI -TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m13; - to[i][2] = m14; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points1_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox ; - to[i][1] = 0 ; - to[i][2] = m14; - to[i][3] = 0; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - - - - -/* 2-vectors, which are a lot more relevant than 1-vectors, are - * present early in the geometry pipeline and throughout the - * texture pipeline. - */ -static void _XFORMAPI -TAG(transform_points2_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m4 = m[4], m12 = m[12]; - const GLfloat m1 = m[1], m5 = m[5], m13 = m[13]; - const GLfloat m2 = m[2], m6 = m[6], m14 = m[14]; - const GLfloat m3 = m[3], m7 = m[7], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m4 * oy + m12; - to[i][1] = m1 * ox + m5 * oy + m13; - to[i][2] = m2 * ox + m6 * oy + m14; - to[i][3] = m3 * ox + m7 * oy + m15; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points2_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - to[i][1] = from[1]; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points2_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m4 * oy + m12; - to[i][1] = m1 * ox + m5 * oy + m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m12; - to[i][1] = m5 * oy + m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points2_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; - const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m4 * oy + m12; - to[i][1] = m1 * ox + m5 * oy + m13; - to[i][2] = m2 * ox + m6 * oy + m14; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - - -/* I would actually say this was a fairly important function, from - * a texture transformation point of view. - */ -static void _XFORMAPI -TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m12; - to[i][1] = m5 * oy + m13; - to[i][2] = m14; - } - if (m14 == 0) { - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - } else { - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - } - to_vec->count = from_vec->count; -} - - -static void _XFORMAPI -TAG(transform_points2_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox ; - to[i][1] = m5 * oy ; - to[i][2] = m14; - to[i][3] = 0; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - - - -static void _XFORMAPI -TAG(transform_points3_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14; - to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points3_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - to[i][1] = from[1]; - to[i][2] = from[2]; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points3_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m4 * oy + m12 ; - to[i][1] = m1 * ox + m5 * oy + m13 ; - to[i][2] = + oz ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m12 ; - to[i][1] = m5 * oy + m13 ; - to[i][2] = + oz ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points3_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; - const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 ; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 ; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -/* previously known as ortho... - */ -static void _XFORMAPI -TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5]; - const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m12 ; - to[i][1] = m5 * oy + m13 ; - to[i][2] = m10 * oz + m14 ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points3_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; - const GLfloat m10 = m[10], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m8 * oz ; - to[i][1] = m5 * oy + m9 * oz ; - to[i][2] = m10 * oz + m14 ; - to[i][3] = -oz ; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - - - -static void _XFORMAPI -TAG(transform_points4_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; - to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points4_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - to[i][1] = from[1]; - to[i][2] = from[2]; - to[i][3] = from[3]; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points4_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m4 * oy + m12 * ow; - to[i][1] = m1 * ox + m5 * oy + m13 * ow; - to[i][2] = + oz ; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m12 * ow; - to[i][1] = m5 * oy + m13 * ow; - to[i][2] = + oz ; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points4_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; - const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5]; - const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m12 * ow; - to[i][1] = m5 * oy + m13 * ow; - to[i][2] = m10 * oz + m14 * ow; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void _XFORMAPI -TAG(transform_points4_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; - const GLfloat m10 = m[10], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m8 * oz ; - to[i][1] = m5 * oy + m9 * oz ; - to[i][2] = m10 * oz + m14 * ow ; - to[i][3] = -oz ; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static transform_func TAG(transform_tab_1)[7]; -static transform_func TAG(transform_tab_2)[7]; -static transform_func TAG(transform_tab_3)[7]; -static transform_func TAG(transform_tab_4)[7]; - -/* Similar functions could be called several times, with more highly - * optimized routines overwriting the arrays. This only occurs during - * startup. - */ -static void _XFORMAPI TAG(init_c_transformations)( void ) -{ -#define TAG_TAB _mesa_transform_tab -#define TAG_TAB_1 TAG(transform_tab_1) -#define TAG_TAB_2 TAG(transform_tab_2) -#define TAG_TAB_3 TAG(transform_tab_3) -#define TAG_TAB_4 TAG(transform_tab_4) - - TAG_TAB[1] = TAG_TAB_1; - TAG_TAB[2] = TAG_TAB_2; - TAG_TAB[3] = TAG_TAB_3; - TAG_TAB[4] = TAG_TAB_4; - - /* 1-D points (ie texcoords) */ - TAG_TAB_1[MATRIX_GENERAL] = TAG(transform_points1_general); - TAG_TAB_1[MATRIX_IDENTITY] = TAG(transform_points1_identity); - TAG_TAB_1[MATRIX_3D_NO_ROT] = TAG(transform_points1_3d_no_rot); - TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective); - TAG_TAB_1[MATRIX_2D] = TAG(transform_points1_2d); - TAG_TAB_1[MATRIX_2D_NO_ROT] = TAG(transform_points1_2d_no_rot); - TAG_TAB_1[MATRIX_3D] = TAG(transform_points1_3d); - - /* 2-D points */ - TAG_TAB_2[MATRIX_GENERAL] = TAG(transform_points2_general); - TAG_TAB_2[MATRIX_IDENTITY] = TAG(transform_points2_identity); - TAG_TAB_2[MATRIX_3D_NO_ROT] = TAG(transform_points2_3d_no_rot); - TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective); - TAG_TAB_2[MATRIX_2D] = TAG(transform_points2_2d); - TAG_TAB_2[MATRIX_2D_NO_ROT] = TAG(transform_points2_2d_no_rot); - TAG_TAB_2[MATRIX_3D] = TAG(transform_points2_3d); - - /* 3-D points */ - TAG_TAB_3[MATRIX_GENERAL] = TAG(transform_points3_general); - TAG_TAB_3[MATRIX_IDENTITY] = TAG(transform_points3_identity); - TAG_TAB_3[MATRIX_3D_NO_ROT] = TAG(transform_points3_3d_no_rot); - TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective); - TAG_TAB_3[MATRIX_2D] = TAG(transform_points3_2d); - TAG_TAB_3[MATRIX_2D_NO_ROT] = TAG(transform_points3_2d_no_rot); - TAG_TAB_3[MATRIX_3D] = TAG(transform_points3_3d); - - /* 4-D points */ - TAG_TAB_4[MATRIX_GENERAL] = TAG(transform_points4_general); - TAG_TAB_4[MATRIX_IDENTITY] = TAG(transform_points4_identity); - TAG_TAB_4[MATRIX_3D_NO_ROT] = TAG(transform_points4_3d_no_rot); - TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective); - TAG_TAB_4[MATRIX_2D] = TAG(transform_points4_2d); - TAG_TAB_4[MATRIX_2D_NO_ROT] = TAG(transform_points4_2d_no_rot); - TAG_TAB_4[MATRIX_3D] = TAG(transform_points4_3d); - -#undef TAG_TAB -#undef TAG_TAB_1 -#undef TAG_TAB_2 -#undef TAG_TAB_3 -#undef TAG_TAB_4 -} diff --git a/src/pixelflinger2/pixelflinger2.cpp b/src/pixelflinger2/pixelflinger2.cpp index bc4b827..0845d23 100644 --- a/src/pixelflinger2/pixelflinger2.cpp +++ b/src/pixelflinger2/pixelflinger2.cpp @@ -17,14 +17,12 @@ #include "pixelflinger2.h" -//#include "src/pixelflinger2/texture.h" - -//#include "src/mesa/main/context.h" - #include <stdlib.h> #include <stdio.h> #include <assert.h> +#include "src/talloc/hieralloc.h" + void gglError(unsigned error) { assert(0); @@ -245,4 +243,5 @@ void DestroyGGLInterface(GGLInterface * iface) #if USE_LLVM_EXECUTIONENGINE puts("USE_LLVM_EXECUTIONENGINE"); #endif + hieralloc_report_brief(NULL, stdout); }
\ No newline at end of file diff --git a/src/pixelflinger2/raster.cpp b/src/pixelflinger2/raster.cpp index 19212d7..3f05c9f 100644 --- a/src/pixelflinger2/raster.cpp +++ b/src/pixelflinger2/raster.cpp @@ -188,7 +188,7 @@ static void RasterTriangle(const GGLInterface * iface, const VertexOutput * v1, const VertexOutput * v2, const VertexOutput * v3) { GGL_GET_CONST_CONTEXT(ctx, iface); - const unsigned varyingCount = 0;//ctx->glCtx->Shader.CurrentProgram->Varying->NumParameters; + const unsigned varyingCount = ctx->glCtx->CurrentProgram->VaryingSlots; const unsigned height = ctx->frameSurface.height; const VertexOutput * a = v1, * b = v2, * d = v3; //abc is a triangle, bcd is another triangle, they share bc as horizontal edge diff --git a/src/pixelflinger2/scanline.cpp b/src/pixelflinger2/scanline.cpp index 106582a..bcb8853 100644 --- a/src/pixelflinger2/scanline.cpp +++ b/src/pixelflinger2/scanline.cpp @@ -240,10 +240,10 @@ void ScanLine(const GGLInterface * iface, const VertexOutput * v1, const VertexO unsigned * frame, int * depth, unsigned char * stencil, GGLContext::ActiveStencilState *, unsigned count); - ScanLineFunction_t scanLineFunction = (ScanLineFunction_t) - ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->function; + ScanLineFunction_t scanLineFunction = (ScanLineFunction_t) + ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->function; if (endX >= startX) { - scanLineFunction(&vertex, &vertexDx, frame, depth, stencil, &ctx->activeStencil, endX - startX + 1); + scanLineFunction(&vertex, &vertexDx, frame, depth, stencil, &ctx->activeStencil, endX - startX + 1); } #else @@ -302,8 +302,7 @@ void ScanLine(const GGLInterface * iface, const VertexOutput * v1, const VertexO if (z & 0x80000000) // negative float has leading 1 z ^= 0x7fffffff; // bigger negative is smaller bool zCmp = true; - if (DepthTest) - { + if (DepthTest) { switch (0x200 | ctx->bufferState.depthFunc) { case GL_NEVER: zCmp = false; @@ -336,7 +335,7 @@ void ScanLine(const GGLInterface * iface, const VertexOutput * v1, const VertexO } if (!DepthTest || zCmp) { float * varying = (float *)ctx->glCtx->CurrentProgram->ValuesVertexOutput; - + assert((void *)&(vertex.varyings[0]) == &(varying[2 * 4])); ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->function(); if (BlendEnable) { @@ -481,15 +480,14 @@ void ScanLine(const GGLInterface * iface, const VertexOutput * v1, const VertexO vertex.frontFacingPointCoord.i[3] = vertexDx.frontFacingPointCoord.i[3]; } #else - if (ctx->glCtx->CurrentProgram->UsesFragCoord) - vertex.position += vertexDx.position; - else if (ctx->bufferState.depthTest) - vertex.position.z += vertexDx.position.z; + if (ctx->glCtx->CurrentProgram->UsesFragCoord) + vertex.position += vertexDx.position; + else if (ctx->bufferState.depthTest) + vertex.position.z += vertexDx.position.z; for (unsigned i = 0; i < varyingCount; i++) vertex.varyings[i] += vertexDx.varyings[i]; - if (ctx->glCtx->CurrentProgram->UsesPointCoord) - { + if (ctx->glCtx->CurrentProgram->UsesPointCoord) { vertex.frontFacingPointCoord.z += vertexDx.frontFacingPointCoord.z; vertex.frontFacingPointCoord.w += vertexDx.frontFacingPointCoord.w; } diff --git a/src/pixelflinger2/shader.cpp b/src/pixelflinger2/shader.cpp index fc75a1c..1e92f9e 100644 --- a/src/pixelflinger2/shader.cpp +++ b/src/pixelflinger2/shader.cpp @@ -569,9 +569,18 @@ static void ShaderUniformMatrix(const GGLInterface * iface, gl_shader_program * GLboolean transpose, const GLfloat *values) { GGL_GET_CONST_CONTEXT(ctx, iface); -// if (!program) -// return gglError(GL_INVALID_OPERATION); -// _mesa_uniform_matrix(ctx->glCtx, program, cols, rows, location, count, transpose, values); + if (location == -1) + return; + assert(cols == rows); + int start = location, slots = cols * count; + if (start < 0 || start + slots > ctx->glCtx->CurrentProgram->Uniforms->Slots) + return gglError(GL_INVALID_OPERATION); + for (unsigned i = 0; i < slots; i++) + { + float * column = ctx->glCtx->CurrentProgram->ValuesUniform[start + i]; + for (unsigned j = 0; j < rows; j++) + column[j] = *(values++); + } } static void ShaderVerifyProcessVertex(const GGLInterface * iface, const VertexInput * input, diff --git a/test/Android.mk b/test/Android.mk index f5f62f2..593d163 100644 --- a/test/Android.mk +++ b/test/Android.mk @@ -7,6 +7,7 @@ LOCAL_PATH := $(call my-dir) mesa_SRC_FILES := \ egl.cpp \ cmain.c \ + m_matrix.c \ main.cpp # Executable for host diff --git a/test/Debug/cg.tga b/test/Debug/cg.tga Binary files differnew file mode 100644 index 0000000..32942ab --- /dev/null +++ b/test/Debug/cg.tga diff --git a/test/Debug/fs.frag b/test/Debug/fs.frag index ba9719f..f2fdda0 100644 --- a/test/Debug/fs.frag +++ b/test/Debug/fs.frag @@ -16,7 +16,7 @@ void main(void) //gl_FragColor += vec4(0,0,0,0); //gl_FragColor = vTexCoord.xyzw; //gl_FragColor = texture2D(samp2DArray[int(vTexCoord.z)], vTexCoord.xy); - gl_FragColor = texture2D(samp2D, vTexCoord.xy) * vTexCoord; + gl_FragColor = texture2D(samp2D, vTexCoord.xy); //gl_FragColor = textureCube(sampCube, vTexCoord.xyz); //gl_FragColor *= vNormal; //gl_FragColor = textureCube(samplercube, vNormal.xyz); @@ -24,24 +24,23 @@ void main(void) //gl_FragColor.a = 1; //gl_FragColor *= (vTexCoord.wwww - vTexCoord * vTexCoord); - - //gl_FragColor = gl_FragColor * gl_FragColor * gl_FragColor; - - - //gl_FragColor = gl_FragColor * gl_FragColor; - //gl_FragColor -= vec4(0.5); - //gl_FragColor.a = 0; - //gl_FragColor = uRotM * gl_FragColor; - //gl_FragColor += vec4(0.5); - - //float dot = dot(vNormal.xyz, vec3(-1.414213562373095, 0, -1.414213562373095)); - //float dot = dot(vNormal.xyz, vNormal.xyz); - //gl_FragColor.rgb *= vec3(dot); + //* + gl_FragColor -= vec4(0.5); + gl_FragColor.a = 0.0; + gl_FragColor = uRotM * gl_FragColor; + gl_FragColor += vec4(0.5); + //*/ + + //* + float dot = dot(vNormal.xyz, vec3(-1.414213562373095, 0, -1.414213562373095)); + gl_FragColor.rgb *= vec3(dot); + //*/ + //gl_FragColor.rgb += vNormal.xyz; //gl_FragColor = (gl_FragCoord / vec4(480, 800, 1, 1)); //gl_FragColor.r = gl_FrontFacing == true ? 1.0 : 0.0; //gl_FragColor.gb = gl_PointCoord; //gl_FragColor = vTexCoord; - //gl_FragColor.a = 1; + gl_FragColor.a = 1.0; } diff --git a/test/Debug/vs.vert b/test/Debug/vs.vert index 39cc6ea..73bcc74 100644 --- a/test/Debug/vs.vert +++ b/test/Debug/vs.vert @@ -13,9 +13,9 @@ varying vec4 vNormal; void main() { vTexCoord = aTexCoord;// + texture2D(sampler2d, aTexCoord.xy); - //gl_Position = uMatrix * aPosition;// * vec4(0.5,0.5,0.5,1); - gl_Position = aPosition; - gl_Position = aTransM * gl_Position; + gl_Position = uMatrix * aPosition;// * vec4(0.5,0.5,0.5,1); + //gl_Position = aPosition; + //gl_Position = aTransM * gl_Position; //gl_Position = aPosition * vec4(0.2, 0.2, 0.2, 1); vNormal = aPosition / vec4(vec3(1.732050807568877),1); gl_PointSize = aTexCoord.z; diff --git a/test/egl.cpp b/test/egl.cpp index cfdf74e..5b55400 100644 --- a/test/egl.cpp +++ b/test/egl.cpp @@ -1924,11 +1924,23 @@ static struct S sp<SurfaceComposerClient> client; sp<SurfaceControl> surfaceControl; sp<Surface> surface; + ~S() + { + //surface->dispose(); + surface.~sp(); + puts("surface.~sp()"); + //surfaceControl->dispose(); + surfaceControl.~sp(); + puts("surfaceControl.~sp()"); + client->dispose(); + client.~sp(); + puts("client.~sp()"); + } } * s = NULL; -ANativeWindow * window; -EGLDisplay display; -EGLContext eglCtx; -EGLSurface drawSurface; +static ANativeWindow * window; +static EGLDisplay display; +static EGLContext eglCtx; +static EGLSurface drawSurface; extern "C" int SetupDrawingSurface(unsigned * width, unsigned * height, unsigned * bpp) { @@ -1936,16 +1948,17 @@ extern "C" int SetupDrawingSurface(unsigned * width, unsigned * height, unsigned // create a client to surfaceflinger s->client = new SurfaceComposerClient(); - s->surfaceControl = s->client->createSurface(getpid(), 0, 1280, 800, PIXEL_FORMAT_RGBA_8888); + s->surfaceControl = s->client->createSurface(getpid(), 0, 640, 400, PIXEL_FORMAT_RGBA_8888); s->client->openTransaction(); s->surfaceControl->setLayer(25000); + s->surfaceControl->show(); s->client->closeTransaction(); s->surface = s->surfaceControl->getSurface(); window = s->surface.get(); printf("window=%p\n", window); - + assert(window); display = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint attrib_list[] = { @@ -2003,9 +2016,11 @@ extern "C" void DisposeDrawingSurface() { puts("DisposeDrawingSurface"); eglDestroySurface(display, drawSurface); + puts("eglDestroySurface"); eglDestroyContext(display, eglCtx); - + puts("eglDestroyContext"); delete s; + puts("delete s"); s = NULL; puts("DisposeDrawingSurface"); diff --git a/test/m_matrix.c b/test/m_matrix.c new file mode 100644 index 0000000..3b56948 --- /dev/null +++ b/test/m_matrix.c @@ -0,0 +1,1701 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \file m_matrix.c + * Matrix operations. + * + * \note + * -# 4x4 transformation matrices are stored in memory in column major order. + * -# Points/vertices are to be thought of as column vectors. + * -# Transformation of a point p by a matrix M is: p' = M * p + */ + +#include <GLES2/gl2.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include <string.h> + +#include "../src/mesa/main/macros.h" + +#include "m_matrix.h" + +#define _mesa_debug(...) +/** + * \defgroup MatFlags MAT_FLAG_XXX-flags + * + * Bitmasks to indicate different kinds of 4x4 matrices in GLmatrix::flags + * It would be nice to make all these flags private to m_matrix.c + */ +/*@{*/ +#define MAT_FLAG_IDENTITY 0 /**< is an identity matrix flag. +* (Not actually used - the identity +* matrix is identified by the absense +* of all other flags.) +*/ +#define MAT_FLAG_GENERAL 0x1 /**< is a general matrix flag */ +#define MAT_FLAG_ROTATION 0x2 /**< is a rotation matrix flag */ +#define MAT_FLAG_TRANSLATION 0x4 /**< is a translation matrix flag */ +#define MAT_FLAG_UNIFORM_SCALE 0x8 /**< is an uniform scaling matrix flag */ +#define MAT_FLAG_GENERAL_SCALE 0x10 /**< is a general scaling matrix flag */ +#define MAT_FLAG_GENERAL_3D 0x20 /**< general 3D matrix flag */ +#define MAT_FLAG_PERSPECTIVE 0x40 /**< is a perspective proj matrix flag */ +#define MAT_FLAG_SINGULAR 0x80 /**< is a singular matrix flag */ +#define MAT_DIRTY_TYPE 0x100 /**< matrix type is dirty */ +#define MAT_DIRTY_FLAGS 0x200 /**< matrix flags are dirty */ +#define MAT_DIRTY_INVERSE 0x400 /**< matrix inverse is dirty */ + +/** angle preserving matrix flags mask */ +#define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \ +MAT_FLAG_TRANSLATION | \ +MAT_FLAG_UNIFORM_SCALE) + +/** geometry related matrix flags mask */ +#define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \ +MAT_FLAG_ROTATION | \ +MAT_FLAG_TRANSLATION | \ +MAT_FLAG_UNIFORM_SCALE | \ +MAT_FLAG_GENERAL_SCALE | \ +MAT_FLAG_GENERAL_3D | \ +MAT_FLAG_PERSPECTIVE | \ +MAT_FLAG_SINGULAR) + +/** length preserving matrix flags mask */ +#define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \ +MAT_FLAG_TRANSLATION) + + +/** 3D (non-perspective) matrix flags mask */ +#define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \ +MAT_FLAG_TRANSLATION | \ +MAT_FLAG_UNIFORM_SCALE | \ +MAT_FLAG_GENERAL_SCALE | \ +MAT_FLAG_GENERAL_3D) + +/** dirty matrix flags mask */ +#define MAT_DIRTY (MAT_DIRTY_TYPE | \ +MAT_DIRTY_FLAGS | \ +MAT_DIRTY_INVERSE) + +/*@}*/ + + +/** + * Test geometry related matrix flags. + * + * \param mat a pointer to a GLmatrix structure. + * \param a flags mask. + * + * \returns non-zero if all geometry related matrix flags are contained within + * the mask, or zero otherwise. + */ +#define TEST_MAT_FLAGS(mat, a) \ +((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0) + + + +/** + * Names of the corresponding GLmatrixtype values. + */ +static const char *types[] = { +"MATRIX_GENERAL", +"MATRIX_IDENTITY", +"MATRIX_3D_NO_ROT", +"MATRIX_PERSPECTIVE", +"MATRIX_2D", +"MATRIX_2D_NO_ROT", +"MATRIX_3D" +}; + + +/** + * Identity matrix. + */ +static GLfloat Identity[16] = { +1.0, 0.0, 0.0, 0.0, +0.0, 1.0, 0.0, 0.0, +0.0, 0.0, 1.0, 0.0, +0.0, 0.0, 0.0, 1.0 +}; + + + +/**********************************************************************/ +/** \name Matrix multiplication */ +/*@{*/ + +#define A(row,col) a[(col<<2)+row] +#define B(row,col) b[(col<<2)+row] +#define P(row,col) product[(col<<2)+row] + +/** + * Perform a full 4x4 matrix multiplication. + * + * \param a matrix. + * \param b matrix. + * \param product will receive the product of \p a and \p b. + * + * \warning Is assumed that \p product != \p b. \p product == \p a is allowed. + * + * \note KW: 4*16 = 64 multiplications + * + * \author This \c matmul was contributed by Thomas Malik + */ +static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b ) +{ + assert(product != b); + GLint i; + for (i = 0; i < 4; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); + } +} + +/** + * Multiply two matrices known to occupy only the top three rows, such + * as typical model matrices, and orthogonal matrices. + * + * \param a matrix. + * \param b matrix. + * \param product will receive the product of \p a and \p b. + */ +static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b ) +{ + GLint i; + for (i = 0; i < 3; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3; + } + P(3,0) = 0; + P(3,1) = 0; + P(3,2) = 0; + P(3,3) = 1; +} + +#undef A +#undef B +#undef P + +/** + * Multiply a matrix by an array of floats with known properties. + * + * \param mat pointer to a GLmatrix structure containing the left multiplication + * matrix, and that will receive the product result. + * \param m right multiplication matrix array. + * \param flags flags of the matrix \p m. + * + * Joins both flags and marks the type and inverse as dirty. Calls matmul34() + * if both matrices are 3D, or matmul4() otherwise. + */ +static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags ) +{ + mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); + + if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) + matmul34( mat->m, mat->m, m ); + else + matmul4( mat->m, mat->m, m ); +} + +/** + * Matrix multiplication. + * + * \param dest destination matrix. + * \param a left matrix. + * \param b right matrix. + * + * Joins both flags and marks the type and inverse as dirty. Calls matmul34() + * if both matrices are 3D, or matmul4() otherwise. + */ +void +_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ) +{ + dest->flags = (a->flags | + b->flags | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); + + if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D)) + matmul34( dest->m, a->m, b->m ); + else + matmul4( dest->m, a->m, b->m ); +} + +/** + * Matrix multiplication. + * + * \param dest left and destination matrix. + * \param m right matrix array. + * + * Marks the matrix flags with general flag, and type and inverse dirty flags. + * Calls matmul4() for the multiplication. + */ +void +_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m ) +{ + dest->flags |= (MAT_FLAG_GENERAL | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE | + MAT_DIRTY_FLAGS); + + matmul4( dest->m, dest->m, m ); +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Matrix output */ +/*@{*/ + +/** + * Print a matrix array. + * + * \param m matrix array. + * + * Called by _math_matrix_print() to print a matrix or its inverse. + */ +static void print_matrix_floats( const GLfloat m[16] ) +{ + int i; + for (i=0;i<4;i++) { + _mesa_debug(NULL,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] ); + } +} + +/** + * Dumps the contents of a GLmatrix structure. + * + * \param m pointer to the GLmatrix structure. + */ +void +_math_matrix_print( const GLmatrix *m ) +{ + _mesa_debug(NULL, "Matrix type: %s, flags: %x\n", types[m->type], m->flags); + print_matrix_floats(m->m); + _mesa_debug(NULL, "Inverse: \n"); + if (m->inv) { + GLfloat prod[16]; + print_matrix_floats(m->inv); + matmul4(prod, m->m, m->inv); + _mesa_debug(NULL, "Mat * Inverse:\n"); + print_matrix_floats(prod); + } + else { + _mesa_debug(NULL, " - not available\n"); + } +} + +/*@}*/ + + +/** + * References an element of 4x4 matrix. + * + * \param m matrix array. + * \param c column of the desired element. + * \param r row of the desired element. + * + * \return value of the desired element. + * + * Calculate the linear storage index of the element and references it. + */ +#define MAT(m,r,c) (m)[(c)*4+(r)] + + +/**********************************************************************/ +/** \name Matrix inversion */ +/*@{*/ + +/** + * Swaps the values of two floating pointer variables. + * + * Used by invert_matrix_general() to swap the row pointers. + */ +#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; } + +/** + * Compute inverse of 4x4 transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). + * + * \author + * Code contributed by Jacques Leroy jle@star.be + * + * Calculates the inverse matrix by performing the gaussian matrix reduction + * with partial pivoting followed by back/substitution with the loops manually + * unrolled. + */ +static GLboolean invert_matrix_general( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + GLfloat *out = mat->inv; + GLfloat wtmp[4][8]; + GLfloat m0, m1, m2, m3, s; + GLfloat *r0, *r1, *r2, *r3; + + r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; + + r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), + r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), + r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, + + r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), + r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), + r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, + + r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), + r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), + r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, + + r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), + r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), + r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; + + /* choose pivot - or die */ + if (FABSF(r3[0])>FABSF(r2[0])) SWAP_ROWS(r3, r2); + if (FABSF(r2[0])>FABSF(r1[0])) SWAP_ROWS(r2, r1); + if (FABSF(r1[0])>FABSF(r0[0])) SWAP_ROWS(r1, r0); + if (0.0 == r0[0]) return GL_FALSE; + + /* eliminate first variable */ + m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; + s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; + s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; + s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r0[5]; + if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r0[6]; + if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r0[7]; + if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (FABSF(r3[1])>FABSF(r2[1])) SWAP_ROWS(r3, r2); + if (FABSF(r2[1])>FABSF(r1[1])) SWAP_ROWS(r2, r1); + if (0.0 == r1[1]) return GL_FALSE; + + /* eliminate second variable */ + m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; + r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; + s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (FABSF(r3[2])>FABSF(r2[2])) SWAP_ROWS(r3, r2); + if (0.0 == r2[2]) return GL_FALSE; + + /* eliminate third variable */ + m3 = r3[2]/r2[2]; + r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], + r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], + r3[7] -= m3 * r2[7]; + + /* last check */ + if (0.0 == r3[3]) return GL_FALSE; + + s = 1.0F/r3[3]; /* now back substitute row 3 */ + r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; + + m2 = r2[3]; /* now back substitute row 2 */ + s = 1.0F/r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), + r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, + r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, + r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; + + m1 = r1[2]; /* now back substitute row 1 */ + s = 1.0F/r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), + r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, + r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; + + m0 = r0[1]; /* now back substitute row 0 */ + s = 1.0F/r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), + r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); + + MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], + MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], + MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], + MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], + MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], + MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], + MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], + MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; + + return GL_TRUE; +} +#undef SWAP_ROWS + +/** + * Compute inverse of a general 3d transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). + * + * \author Adapted from graphics gems II. + * + * Calculates the inverse of the upper left by first calculating its + * determinant and multiplying it to the symmetric adjust matrix of each + * element. Finally deals with the translation part by transforming the + * original translation vector using by the calculated submatrix inverse. + */ +static GLboolean invert_matrix_3d_general( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + GLfloat pos, neg, t; + GLfloat det; + + /* Calculate the determinant of upper left 3x3 submatrix and + * determine if the matrix is singular. + */ + pos = neg = 0.0; + t = MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2); + if (t >= 0.0) pos += t; else neg += t; + + t = MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2); + if (t >= 0.0) pos += t; else neg += t; + + t = MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2); + if (t >= 0.0) pos += t; else neg += t; + + det = pos + neg; + + if (det*det < 1e-25) + return GL_FALSE; + + det = 1.0F / det; + MAT(out,0,0) = ( (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det); + MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det); + MAT(out,0,2) = ( (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det); + MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det); + MAT(out,1,1) = ( (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det); + MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det); + MAT(out,2,0) = ( (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det); + MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det); + MAT(out,2,2) = ( (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det); + + /* Do the translation part */ + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + + MAT(in,1,3) * MAT(out,0,1) + + MAT(in,2,3) * MAT(out,0,2) ); + MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + + MAT(in,1,3) * MAT(out,1,1) + + MAT(in,2,3) * MAT(out,1,2) ); + MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + + MAT(in,1,3) * MAT(out,2,1) + + MAT(in,2,3) * MAT(out,2,2) ); + + return GL_TRUE; +} + +/** + * Compute inverse of a 3d transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). + * + * If the matrix is not an angle preserving matrix then calls + * invert_matrix_3d_general for the actual calculation. Otherwise calculates + * the inverse matrix analyzing and inverting each of the scaling, rotation and + * translation parts. + */ +static GLboolean invert_matrix_3d( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) { + return invert_matrix_3d_general( mat ); + } + + if (mat->flags & MAT_FLAG_UNIFORM_SCALE) { + GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) + + MAT(in,0,1) * MAT(in,0,1) + + MAT(in,0,2) * MAT(in,0,2)); + + if (scale == 0.0) + return GL_FALSE; + + scale = 1.0F / scale; + + /* Transpose and scale the 3 by 3 upper-left submatrix. */ + MAT(out,0,0) = scale * MAT(in,0,0); + MAT(out,1,0) = scale * MAT(in,0,1); + MAT(out,2,0) = scale * MAT(in,0,2); + MAT(out,0,1) = scale * MAT(in,1,0); + MAT(out,1,1) = scale * MAT(in,1,1); + MAT(out,2,1) = scale * MAT(in,1,2); + MAT(out,0,2) = scale * MAT(in,2,0); + MAT(out,1,2) = scale * MAT(in,2,1); + MAT(out,2,2) = scale * MAT(in,2,2); + } + else if (mat->flags & MAT_FLAG_ROTATION) { + /* Transpose the 3 by 3 upper-left submatrix. */ + MAT(out,0,0) = MAT(in,0,0); + MAT(out,1,0) = MAT(in,0,1); + MAT(out,2,0) = MAT(in,0,2); + MAT(out,0,1) = MAT(in,1,0); + MAT(out,1,1) = MAT(in,1,1); + MAT(out,2,1) = MAT(in,1,2); + MAT(out,0,2) = MAT(in,2,0); + MAT(out,1,2) = MAT(in,2,1); + MAT(out,2,2) = MAT(in,2,2); + } + else { + /* pure translation */ + memcpy( out, Identity, sizeof(Identity) ); + MAT(out,0,3) = - MAT(in,0,3); + MAT(out,1,3) = - MAT(in,1,3); + MAT(out,2,3) = - MAT(in,2,3); + return GL_TRUE; + } + + if (mat->flags & MAT_FLAG_TRANSLATION) { + /* Do the translation part */ + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + + MAT(in,1,3) * MAT(out,0,1) + + MAT(in,2,3) * MAT(out,0,2) ); + MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + + MAT(in,1,3) * MAT(out,1,1) + + MAT(in,2,3) * MAT(out,1,2) ); + MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + + MAT(in,1,3) * MAT(out,2,1) + + MAT(in,2,3) * MAT(out,2,2) ); + } + else { + MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0; + } + + return GL_TRUE; +} + +/** + * Compute inverse of an identity transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return always GL_TRUE. + * + * Simply copies Identity into GLmatrix::inv. + */ +static GLboolean invert_matrix_identity( GLmatrix *mat ) +{ + memcpy( mat->inv, Identity, sizeof(Identity) ); + return GL_TRUE; +} + +/** + * Compute inverse of a no-rotation 3d transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). + * + * Calculates the + */ +static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 ) + return GL_FALSE; + + memcpy( out, Identity, 16 * sizeof(GLfloat) ); + MAT(out,0,0) = 1.0F / MAT(in,0,0); + MAT(out,1,1) = 1.0F / MAT(in,1,1); + MAT(out,2,2) = 1.0F / MAT(in,2,2); + + if (mat->flags & MAT_FLAG_TRANSLATION) { + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); + MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); + MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2)); + } + + return GL_TRUE; +} + +/** + * Compute inverse of a no-rotation 2d transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). + * + * Calculates the inverse matrix by applying the inverse scaling and + * translation to the identity matrix. + */ +static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0) + return GL_FALSE; + + memcpy( out, Identity, 16 * sizeof(GLfloat) ); + MAT(out,0,0) = 1.0F / MAT(in,0,0); + MAT(out,1,1) = 1.0F / MAT(in,1,1); + + if (mat->flags & MAT_FLAG_TRANSLATION) { + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); + MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); + } + + return GL_TRUE; +} + +#if 0 +/* broken */ +static GLboolean invert_matrix_perspective( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,2,3) == 0) + return GL_FALSE; + + memcpy( out, Identity, 16 * sizeof(GLfloat) ); + + MAT(out,0,0) = 1.0F / MAT(in,0,0); + MAT(out,1,1) = 1.0F / MAT(in,1,1); + + MAT(out,0,3) = MAT(in,0,2); + MAT(out,1,3) = MAT(in,1,2); + + MAT(out,2,2) = 0; + MAT(out,2,3) = -1; + + MAT(out,3,2) = 1.0F / MAT(in,2,3); + MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2); + + return GL_TRUE; +} +#endif + +/** + * Matrix inversion function pointer type. + */ +typedef GLboolean (*inv_mat_func)( GLmatrix *mat ); + +/** + * Table of the matrix inversion functions according to the matrix type. + */ +static inv_mat_func inv_mat_tab[7] = { +invert_matrix_general, +invert_matrix_identity, +invert_matrix_3d_no_rot, +#if 0 +/* Don't use this function for now - it fails when the projection matrix + * is premultiplied by a translation (ala Chromium's tilesort SPU). + */ +invert_matrix_perspective, +#else +invert_matrix_general, +#endif +invert_matrix_3d, /* lazy! */ +invert_matrix_2d_no_rot, +invert_matrix_3d +}; + +/** + * Compute inverse of a transformation matrix. + * + * \param mat pointer to a GLmatrix structure. The matrix inverse will be + * stored in the GLmatrix::inv attribute. + * + * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix). + * + * Calls the matrix inversion function in inv_mat_tab corresponding to the + * given matrix type. In case of failure, updates the MAT_FLAG_SINGULAR flag, + * and copies the identity matrix into GLmatrix::inv. + */ +static GLboolean matrix_invert( GLmatrix *mat ) +{ + if (inv_mat_tab[mat->type](mat)) { + mat->flags &= ~MAT_FLAG_SINGULAR; + return GL_TRUE; + } else { + mat->flags |= MAT_FLAG_SINGULAR; + memcpy( mat->inv, Identity, sizeof(Identity) ); + return GL_FALSE; + } +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Matrix generation */ +/*@{*/ + +/** + * Generate a 4x4 transformation matrix from glRotate parameters, and + * post-multiply the input matrix by it. + * + * \author + * This function was contributed by Erich Boleyn (erich@uruk.org). + * Optimizations contributed by Rudolf Opalla (rudi@khm.de). + */ +void +_math_matrix_rotate( GLmatrix *mat, + GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c; + GLfloat m[16]; + GLboolean optimized; + + s = (GLfloat) sinf( angle * (M_PI / 180.0f) ); + c = (GLfloat) cosf( angle * (M_PI / 180.0f) ); + + memcpy(m, Identity, sizeof(GLfloat)*16); + optimized = GL_FALSE; + +#define M(row,col) m[col*4+row] + + if (x == 0.0F) { + if (y == 0.0F) { + if (z != 0.0F) { + optimized = GL_TRUE; + /* rotate only around z-axis */ + M(0,0) = c; + M(1,1) = c; + if (z < 0.0F) { + M(0,1) = s; + M(1,0) = -s; + } + else { + M(0,1) = -s; + M(1,0) = s; + } + } + } + else if (z == 0.0F) { + optimized = GL_TRUE; + /* rotate only around y-axis */ + M(0,0) = c; + M(2,2) = c; + if (y < 0.0F) { + M(0,2) = -s; + M(2,0) = s; + } + else { + M(0,2) = s; + M(2,0) = -s; + } + } + } + else if (y == 0.0F) { + if (z == 0.0F) { + optimized = GL_TRUE; + /* rotate only around x-axis */ + M(1,1) = c; + M(2,2) = c; + if (x < 0.0F) { + M(1,2) = s; + M(2,1) = -s; + } + else { + M(1,2) = -s; + M(2,1) = s; + } + } + } + + if (!optimized) { + const GLfloat mag = SQRTF(x * x + y * y + z * z); + + if (mag <= 1.0e-4) { + /* no rotation, leave mat as-is */ + return; + } + + x /= mag; + y /= mag; + z /= mag; + + + /* + * Arbitrary axis rotation matrix. + * + * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied + * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation + * (which is about the X-axis), and the two composite transforms + * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary + * from the arbitrary axis to the X-axis then back. They are + * all elementary rotations. + * + * Rz' is a rotation about the Z-axis, to bring the axis vector + * into the x-z plane. Then Ry' is applied, rotating about the + * Y-axis to bring the axis vector parallel with the X-axis. The + * rotation about the X-axis is then performed. Ry and Rz are + * simply the respective inverse transforms to bring the arbitrary + * axis back to it's original orientation. The first transforms + * Rz' and Ry' are considered inverses, since the data from the + * arbitrary axis gives you info on how to get to it, not how + * to get away from it, and an inverse must be applied. + * + * The basic calculation used is to recognize that the arbitrary + * axis vector (x, y, z), since it is of unit length, actually + * represents the sines and cosines of the angles to rotate the + * X-axis to the same orientation, with theta being the angle about + * Z and phi the angle about Y (in the order described above) + * as follows: + * + * cos ( theta ) = x / sqrt ( 1 - z^2 ) + * sin ( theta ) = y / sqrt ( 1 - z^2 ) + * + * cos ( phi ) = sqrt ( 1 - z^2 ) + * sin ( phi ) = z + * + * Note that cos ( phi ) can further be inserted to the above + * formulas: + * + * cos ( theta ) = x / cos ( phi ) + * sin ( theta ) = y / sin ( phi ) + * + * ...etc. Because of those relations and the standard trigonometric + * relations, it is pssible to reduce the transforms down to what + * is used below. It may be that any primary axis chosen will give the + * same results (modulo a sign convention) using thie method. + * + * Particularly nice is to notice that all divisions that might + * have caused trouble when parallel to certain planes or + * axis go away with care paid to reducing the expressions. + * After checking, it does perform correctly under all cases, since + * in all the cases of division where the denominator would have + * been zero, the numerator would have been zero as well, giving + * the expected result. + */ + + xx = x * x; + yy = y * y; + zz = z * z; + xy = x * y; + yz = y * z; + zx = z * x; + xs = x * s; + ys = y * s; + zs = z * s; + one_c = 1.0F - c; + + /* We already hold the identity-matrix so we can skip some statements */ + M(0,0) = (one_c * xx) + c; + M(0,1) = (one_c * xy) - zs; + M(0,2) = (one_c * zx) + ys; + /* M(0,3) = 0.0F; */ + + M(1,0) = (one_c * xy) + zs; + M(1,1) = (one_c * yy) + c; + M(1,2) = (one_c * yz) - xs; + /* M(1,3) = 0.0F; */ + + M(2,0) = (one_c * zx) - ys; + M(2,1) = (one_c * yz) + xs; + M(2,2) = (one_c * zz) + c; + /* M(2,3) = 0.0F; */ + + /* + M(3,0) = 0.0F; + M(3,1) = 0.0F; + M(3,2) = 0.0F; + M(3,3) = 1.0F; + */ + } +#undef M + + matrix_multf( mat, m, MAT_FLAG_ROTATION ); +} + +/** + * Apply a perspective projection matrix. + * + * \param mat matrix to apply the projection. + * \param left left clipping plane coordinate. + * \param right right clipping plane coordinate. + * \param bottom bottom clipping plane coordinate. + * \param top top clipping plane coordinate. + * \param nearval distance to the near clipping plane. + * \param farval distance to the far clipping plane. + * + * Creates the projection matrix and multiplies it with \p mat, marking the + * MAT_FLAG_PERSPECTIVE flag. + */ +void +_math_matrix_frustum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, a, b, c, d; + GLfloat m[16]; + + x = (2.0F*nearval) / (right-left); + y = (2.0F*nearval) / (top-bottom); + a = (right+left) / (right-left); + b = (top+bottom) / (top-bottom); + c = -(farval+nearval) / ( farval-nearval); + d = -(2.0F*farval*nearval) / (farval-nearval); /* error? */ + + if (0) + { + c /= farval; // linearize z in vs by gl_Position.z *= gl_Position.w + d /= farval; + } + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; +#undef M + + matrix_multf( mat, m, MAT_FLAG_PERSPECTIVE ); +} + +/** + * Apply an orthographic projection matrix. + * + * \param mat matrix to apply the projection. + * \param left left clipping plane coordinate. + * \param right right clipping plane coordinate. + * \param bottom bottom clipping plane coordinate. + * \param top top clipping plane coordinate. + * \param nearval distance to the near clipping plane. + * \param farval distance to the far clipping plane. + * + * Creates the projection matrix and multiplies it with \p mat, marking the + * MAT_FLAG_GENERAL_SCALE and MAT_FLAG_TRANSLATION flags. + */ +void +_math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat m[16]; + +#define M(row,col) m[col*4+row] + M(0,0) = 2.0F / (right-left); + M(0,1) = 0.0F; + M(0,2) = 0.0F; + M(0,3) = -(right+left) / (right-left); + + M(1,0) = 0.0F; + M(1,1) = 2.0F / (top-bottom); + M(1,2) = 0.0F; + M(1,3) = -(top+bottom) / (top-bottom); + + M(2,0) = 0.0F; + M(2,1) = 0.0F; + M(2,2) = -2.0F / (farval-nearval); + M(2,3) = -(farval+nearval) / (farval-nearval); + + M(3,0) = 0.0F; + M(3,1) = 0.0F; + M(3,2) = 0.0F; + M(3,3) = 1.0F; +#undef M + + matrix_multf( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION)); +} + +// multiplies mat by a perspective transform matrix +void _math_matrix_perspective(GLmatrix * mat, GLfloat fovy, GLfloat aspect, + GLfloat zNear, GLfloat zFar) +{ + GLfloat xmin, xmax, ymin, ymax; + + ymax = zNear * tan(fovy * M_PI / 360.0); + ymin = -ymax; + xmin = ymin * aspect; + xmax = ymax * aspect; + + _math_matrix_frustum(mat, xmin, xmax, ymin, ymax, zNear, zFar); +} + +// multiplies mat by a look at matrix +void _math_matrix_lookat(GLmatrix * mat, GLfloat eyex, GLfloat eyey, GLfloat eyez, + GLfloat centerx, GLfloat centery, GLfloat centerz, + GLfloat upx, GLfloat upy, GLfloat upz) +{ + GLfloat m[16]; + GLfloat x[3], y[3], z[3]; + GLfloat mag; + + /* Make rotation matrix */ + + /* Z vector */ + z[0] = eyex - centerx; + z[1] = eyey - centery; + z[2] = eyez - centerz; + mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); + if (mag) { /* mpichler, 19950515 */ + z[0] /= mag; + z[1] /= mag; + z[2] /= mag; + } + + /* Y vector */ + y[0] = upx; + y[1] = upy; + y[2] = upz; + + /* X vector = Y cross Z */ + x[0] = y[1] * z[2] - y[2] * z[1]; + x[1] = -y[0] * z[2] + y[2] * z[0]; + x[2] = y[0] * z[1] - y[1] * z[0]; + + /* Recompute Y = Z cross X */ + y[0] = z[1] * x[2] - z[2] * x[1]; + y[1] = -z[0] * x[2] + z[2] * x[0]; + y[2] = z[0] * x[1] - z[1] * x[0]; + + /* mpichler, 19950515 */ + /* cross product gives area of parallelogram, which is < 1.0 for + * non-perpendicular unit-length vectors; so normalize x, y here + */ + + mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); + if (mag) { + x[0] /= mag; + x[1] /= mag; + x[2] /= mag; + } + + mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); + if (mag) { + y[0] /= mag; + y[1] /= mag; + y[2] /= mag; + } + +#define M(row,col) m[col*4+row] + M(0, 0) = x[0]; + M(0, 1) = x[1]; + M(0, 2) = x[2]; + M(0, 3) = 0.0; + M(1, 0) = y[0]; + M(1, 1) = y[1]; + M(1, 2) = y[2]; + M(1, 3) = 0.0; + M(2, 0) = z[0]; + M(2, 1) = z[1]; + M(2, 2) = z[2]; + M(2, 3) = 0.0; + M(3, 0) = 0.0; + M(3, 1) = 0.0; + M(3, 2) = 0.0; + M(3, 3) = 1.0; +#undef M + + GLfloat translate[16] = + { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + -eyex, -eyey, -eyez, 1, + }; + + _math_matrix_mul_floats(mat, m); + + _math_matrix_mul_floats(mat, translate); + + /* Translate Eye to Origin */ + // glTranslated(-eyex, -eyey, -eyez); + +} + +/** + * Multiply a matrix with a general scaling matrix. + * + * \param mat matrix. + * \param x x axis scale factor. + * \param y y axis scale factor. + * \param z z axis scale factor. + * + * Multiplies in-place the elements of \p mat by the scale factors. Checks if + * the scales factors are roughly the same, marking the MAT_FLAG_UNIFORM_SCALE + * flag, or MAT_FLAG_GENERAL_SCALE. Marks the MAT_DIRTY_TYPE and + * MAT_DIRTY_INVERSE dirty flags. + */ +void +_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat *m = mat->m; + m[0] *= x; m[4] *= y; m[8] *= z; + m[1] *= x; m[5] *= y; m[9] *= z; + m[2] *= x; m[6] *= y; m[10] *= z; + m[3] *= x; m[7] *= y; m[11] *= z; + + if (FABSF(x - y) < 1e-8 && FABSF(x - z) < 1e-8) + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + else + mat->flags |= MAT_FLAG_GENERAL_SCALE; + + mat->flags |= (MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); +} + +/** + * Multiply a matrix with a translation matrix. + * + * \param mat matrix. + * \param x translation vector x coordinate. + * \param y translation vector y coordinate. + * \param z translation vector z coordinate. + * + * Adds the translation coordinates to the elements of \p mat in-place. Marks + * the MAT_FLAG_TRANSLATION flag, and the MAT_DIRTY_TYPE and MAT_DIRTY_INVERSE + * dirty flags. + */ +void +_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat *m = mat->m; + m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; + m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; + m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; + m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; + + mat->flags |= (MAT_FLAG_TRANSLATION | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); +} + + +/** + * Set matrix to do viewport and depthrange mapping. + * Transforms Normalized Device Coords to window/Z values. + */ +void +_math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height, + GLfloat zNear, GLfloat zFar, GLfloat depthMax) +{ + m->m[MAT_SX] = (GLfloat) width / 2.0F; + m->m[MAT_TX] = m->m[MAT_SX] + x; + m->m[MAT_SY] = (GLfloat) height / 2.0F; + m->m[MAT_TY] = m->m[MAT_SY] + y; + m->m[MAT_SZ] = depthMax * ((zFar - zNear) / 2.0F); + m->m[MAT_TZ] = depthMax * ((zFar - zNear) / 2.0F + zNear); + m->flags = MAT_FLAG_GENERAL_SCALE | MAT_FLAG_TRANSLATION; + m->type = MATRIX_3D_NO_ROT; +} + + +/** + * Set a matrix to the identity matrix. + * + * \param mat matrix. + * + * Copies ::Identity into \p GLmatrix::m, and into GLmatrix::inv if not NULL. + * Sets the matrix type to identity, and clear the dirty flags. + */ +void +_math_matrix_set_identity( GLmatrix *mat ) +{ + memcpy( mat->m, Identity, 16*sizeof(GLfloat) ); + + if (mat->inv) + memcpy( mat->inv, Identity, 16*sizeof(GLfloat) ); + + mat->type = MATRIX_IDENTITY; + mat->flags &= ~(MAT_DIRTY_FLAGS| + MAT_DIRTY_TYPE| + MAT_DIRTY_INVERSE); +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Matrix analysis */ +/*@{*/ + +#define ZERO(x) (1<<x) +#define ONE(x) (1<<(x+16)) + +#define MASK_NO_TRX (ZERO(12) | ZERO(13) | ZERO(14)) +#define MASK_NO_2D_SCALE ( ONE(0) | ONE(5)) + +#define MASK_IDENTITY ( ONE(0) | ZERO(4) | ZERO(8) | ZERO(12) |\ +ZERO(1) | ONE(5) | ZERO(9) | ZERO(13) |\ +ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ +ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + +#define MASK_2D_NO_ROT ( ZERO(4) | ZERO(8) | \ +ZERO(1) | ZERO(9) | \ +ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ +ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + +#define MASK_2D ( ZERO(8) | \ +ZERO(9) | \ +ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\ +ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + + +#define MASK_3D_NO_ROT ( ZERO(4) | ZERO(8) | \ +ZERO(1) | ZERO(9) | \ +ZERO(2) | ZERO(6) | \ +ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + +#define MASK_3D ( \ +\ +\ +ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) ) + + +#define MASK_PERSPECTIVE ( ZERO(4) | ZERO(12) |\ +ZERO(1) | ZERO(13) |\ +ZERO(2) | ZERO(6) | \ +ZERO(3) | ZERO(7) | ZERO(15) ) + +#define SQ(x) ((x)*(x)) + +/** + * Determine type and flags from scratch. + * + * \param mat matrix. + * + * This is expensive enough to only want to do it once. + */ +static void analyse_from_scratch( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + GLuint mask = 0; + GLuint i; + + for (i = 0 ; i < 16 ; i++) { + if (m[i] == 0.0) mask |= (1<<i); + } + + if (m[0] == 1.0F) mask |= (1<<16); + if (m[5] == 1.0F) mask |= (1<<21); + if (m[10] == 1.0F) mask |= (1<<26); + if (m[15] == 1.0F) mask |= (1<<31); + + mat->flags &= ~MAT_FLAGS_GEOMETRY; + + /* Check for translation - no-one really cares + */ + if ((mask & MASK_NO_TRX) != MASK_NO_TRX) + mat->flags |= MAT_FLAG_TRANSLATION; + + /* Do the real work + */ + if (mask == (GLuint) MASK_IDENTITY) { + mat->type = MATRIX_IDENTITY; + } + else if ((mask & MASK_2D_NO_ROT) == (GLuint) MASK_2D_NO_ROT) { + mat->type = MATRIX_2D_NO_ROT; + + if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE) + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + else if ((mask & MASK_2D) == (GLuint) MASK_2D) { + GLfloat mm = DOT2(m, m); + GLfloat m4m4 = DOT2(m+4,m+4); + GLfloat mm4 = DOT2(m,m+4); + + mat->type = MATRIX_2D; + + /* Check for scale */ + if (SQ(mm-1) > SQ(1e-6) || + SQ(m4m4-1) > SQ(1e-6)) + mat->flags |= MAT_FLAG_GENERAL_SCALE; + + /* Check for rotation */ + if (SQ(mm4) > SQ(1e-6)) + mat->flags |= MAT_FLAG_GENERAL_3D; + else + mat->flags |= MAT_FLAG_ROTATION; + + } + else if ((mask & MASK_3D_NO_ROT) == (GLuint) MASK_3D_NO_ROT) { + mat->type = MATRIX_3D_NO_ROT; + + /* Check for scale */ + if (SQ(m[0]-m[5]) < SQ(1e-6) && + SQ(m[0]-m[10]) < SQ(1e-6)) { + if (SQ(m[0]-1.0) > SQ(1e-6)) { + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + } + } + else { + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + } + else if ((mask & MASK_3D) == (GLuint) MASK_3D) { + GLfloat c1 = DOT3(m,m); + GLfloat c2 = DOT3(m+4,m+4); + GLfloat c3 = DOT3(m+8,m+8); + GLfloat d1 = DOT3(m, m+4); + GLfloat cp[3]; + + mat->type = MATRIX_3D; + + /* Check for scale */ + if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) { + if (SQ(c1-1.0) > SQ(1e-6)) + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + /* else no scale at all */ + } + else { + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + + /* Check for rotation */ + if (SQ(d1) < SQ(1e-6)) { + CROSS3( cp, m, m+4 ); + SUB_3V( cp, cp, (m+8) ); + if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) + mat->flags |= MAT_FLAG_ROTATION; + else + mat->flags |= MAT_FLAG_GENERAL_3D; + } + else { + mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */ + } + } + else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) { + mat->type = MATRIX_PERSPECTIVE; + mat->flags |= MAT_FLAG_GENERAL; + } + else { + mat->type = MATRIX_GENERAL; + mat->flags |= MAT_FLAG_GENERAL; + } +} + +/** + * Analyze a matrix given that its flags are accurate. + * + * This is the more common operation, hopefully. + */ +static void analyse_from_flags( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + + if (TEST_MAT_FLAGS(mat, 0)) { + mat->type = MATRIX_IDENTITY; + } + else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION | + MAT_FLAG_UNIFORM_SCALE | + MAT_FLAG_GENERAL_SCALE))) { + if ( m[10]==1.0F && m[14]==0.0F ) { + mat->type = MATRIX_2D_NO_ROT; + } + else { + mat->type = MATRIX_3D_NO_ROT; + } + } + else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) { + if ( m[ 8]==0.0F + && m[ 9]==0.0F + && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) { + mat->type = MATRIX_2D; + } + else { + mat->type = MATRIX_3D; + } + } + else if ( m[4]==0.0F && m[12]==0.0F + && m[1]==0.0F && m[13]==0.0F + && m[2]==0.0F && m[6]==0.0F + && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) { + mat->type = MATRIX_PERSPECTIVE; + } + else { + mat->type = MATRIX_GENERAL; + } +} + +/** + * Analyze and update a matrix. + * + * \param mat matrix. + * + * If the matrix type is dirty then calls either analyse_from_scratch() or + * analyse_from_flags() to determine its type, according to whether the flags + * are dirty or not, respectively. If the matrix has an inverse and it's dirty + * then calls matrix_invert(). Finally clears the dirty flags. + */ +void +_math_matrix_analyse( GLmatrix *mat ) +{ + if (mat->flags & MAT_DIRTY_TYPE) { + if (mat->flags & MAT_DIRTY_FLAGS) + analyse_from_scratch( mat ); + else + analyse_from_flags( mat ); + } + + if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) { + matrix_invert( mat ); + mat->flags &= ~MAT_DIRTY_INVERSE; + } + + mat->flags &= ~(MAT_DIRTY_FLAGS | MAT_DIRTY_TYPE); +} + +/*@}*/ + + +/** + * Test if the given matrix preserves vector lengths. + */ +GLboolean +_math_matrix_is_length_preserving( const GLmatrix *m ) +{ + return TEST_MAT_FLAGS( m, MAT_FLAGS_LENGTH_PRESERVING); +} + + +/** + * Test if the given matrix does any rotation. + * (or perhaps if the upper-left 3x3 is non-identity) + */ +GLboolean +_math_matrix_has_rotation( const GLmatrix *m ) +{ + if (m->flags & (MAT_FLAG_GENERAL | + MAT_FLAG_ROTATION | + MAT_FLAG_GENERAL_3D | + MAT_FLAG_PERSPECTIVE)) + return GL_TRUE; + else + return GL_FALSE; +} + + +GLboolean +_math_matrix_is_general_scale( const GLmatrix *m ) +{ + return (m->flags & MAT_FLAG_GENERAL_SCALE) ? GL_TRUE : GL_FALSE; +} + + +GLboolean +_math_matrix_is_dirty( const GLmatrix *m ) +{ + return (m->flags & MAT_DIRTY) ? GL_TRUE : GL_FALSE; +} + + +/**********************************************************************/ +/** \name Matrix setup */ +/*@{*/ + +/** + * Copy a matrix. + * + * \param to destination matrix. + * \param from source matrix. + * + * Copies all fields in GLmatrix, creating an inverse array if necessary. + */ +void +_math_matrix_copy( GLmatrix *to, const GLmatrix *from ) +{ + memcpy( to->m, from->m, sizeof(Identity) ); + to->flags = from->flags; + to->type = from->type; + + if (to->inv != 0) { + if (from->inv == 0) { + matrix_invert( to ); + } + else { + memcpy(to->inv, from->inv, sizeof(GLfloat)*16); + } + } +} + +/** + * Loads a matrix array into GLmatrix. + * + * \param m matrix array. + * \param mat matrix. + * + * Copies \p m into GLmatrix::m and marks the MAT_FLAG_GENERAL and MAT_DIRTY + * flags. + */ +void +_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ) +{ + memcpy( mat->m, m, 16*sizeof(GLfloat) ); + mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY); +} + +/** + * Matrix constructor. + * + * \param m matrix. + * + * Initialize the GLmatrix fields. + */ +void +_math_matrix_ctr( GLmatrix *m ) +{ + //m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + if (m->m) + memcpy( m->m, Identity, sizeof(Identity) ); + m->inv = NULL; + m->type = MATRIX_IDENTITY; + m->flags = 0; +} + +/** + * Matrix destructor. + * + * \param m matrix. + * + * Frees the data in a GLmatrix. + */ +void +_math_matrix_dtr( GLmatrix *m ) +{ + if (m->m) { + //ALIGN_FREE( m->m ); + //m->m = NULL; + } + if (m->inv) { + free( m->inv ); + m->inv = NULL; + } +} + +/** + * Allocate a matrix inverse. + * + * \param m matrix. + * + * Allocates the matrix inverse, GLmatrix::inv, and sets it to Identity. + */ +void +_math_matrix_alloc_inv( GLmatrix *m ) +{ + if (!m->inv) { + m->inv = (GLfloat *) malloc( 16 * sizeof(GLfloat)); + if (m->inv) + memcpy( m->inv, Identity, 16 * sizeof(GLfloat) ); + } +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Matrix transpose */ +/*@{*/ + +/** + * Transpose a GLfloat matrix. + * + * \param to destination array. + * \param from source array. + */ +void +_math_transposef( GLfloat to[16], const GLfloat from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} + + +/** + * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This + * function is used for transforming clipping plane equations and spotlight + * directions. + * Mathematically, u = v * m. + * Input: v - input vector + * m - transformation matrix + * Output: u - transformed vector + */ +void +_mesa_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] ) +{ + const GLfloat v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; +#define M(row,col) m[row + col*4] + u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0); + u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1); + u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2); + u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3); +#undef M +} diff --git a/test/m_matrix.h b/test/m_matrix.h new file mode 100644 index 0000000..2e54936 --- /dev/null +++ b/test/m_matrix.h @@ -0,0 +1,217 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \file math/m_matrix.h + * Defines basic structures for matrix-handling. + */ + +#ifndef _M_MATRIX_H +#define _M_MATRIX_H + + + +/** + * \name Symbolic names to some of the entries in the matrix + * + * These are handy for the viewport mapping, which is expressed as a matrix. + */ +/*@{*/ +#define MAT_SX 0 +#define MAT_SY 5 +#define MAT_SZ 10 +#define MAT_TX 12 +#define MAT_TY 13 +#define MAT_TZ 14 +/*@}*/ + + +/** + * Different kinds of 4x4 transformation matrices. + * We use these to select specific optimized vertex transformation routines. + */ +enum GLmatrixtype { + MATRIX_GENERAL, /**< general 4x4 matrix */ + MATRIX_IDENTITY, /**< identity matrix */ + MATRIX_3D_NO_ROT, /**< orthogonal projection and others... */ + MATRIX_PERSPECTIVE, /**< perspective projection matrix */ + MATRIX_2D, /**< 2-D transformation */ + MATRIX_2D_NO_ROT, /**< 2-D scale & translate only */ + MATRIX_3D /**< 3-D transformation */ +} ; + +/** + * Matrix type to represent 4x4 transformation matrices. + */ +typedef struct { + GLfloat m[16]; + //GLfloat *m; /**< 16 matrix elements (16-byte aligned) */ + GLfloat *inv; /**< optional 16-element inverse (16-byte aligned) */ + GLuint flags; /**< possible values determined by (of \link + * MatFlags MAT_FLAG_* flags\endlink) + */ + enum GLmatrixtype type; +} GLmatrix; + + +#ifdef __cplusplus +extern "C" { +#endif + + void + _math_matrix_ctr( GLmatrix *m ); + + void + _math_matrix_dtr( GLmatrix *m ); + + void + _math_matrix_alloc_inv( GLmatrix *m ); + + void + _math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ); + + void + _math_matrix_mul_floats( GLmatrix *dest, const GLfloat *b ); + + void + _math_matrix_loadf( GLmatrix *mat, const GLfloat *m ); + + void + _math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); + + void + _math_matrix_rotate( GLmatrix *m, GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + + void + _math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); + + void + _math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ); + + void + _math_matrix_perspective(GLmatrix * mat, GLfloat fovy, GLfloat aspect, + GLfloat zNear, GLfloat zFar); + + void + _math_matrix_lookat(GLmatrix * mat, GLfloat eyex, GLfloat eyey, GLfloat eyez, + GLfloat centerx, GLfloat centery, GLfloat centerz, + GLfloat upx, GLfloat upy, GLfloat upz); + void + _math_matrix_frustum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ); + + void + _math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height, + GLfloat zNear, GLfloat zFar, GLfloat depthMax); + + void + _math_matrix_set_identity( GLmatrix *dest ); + + void + _math_matrix_copy( GLmatrix *to, const GLmatrix *from ); + + void + _math_matrix_analyse( GLmatrix *mat ); + + void + _math_matrix_print( const GLmatrix *m ); + + GLboolean + _math_matrix_is_length_preserving( const GLmatrix *m ); + + GLboolean + _math_matrix_has_rotation( const GLmatrix *m ); + + GLboolean + _math_matrix_is_general_scale( const GLmatrix *m ); + + GLboolean + _math_matrix_is_dirty( const GLmatrix *m ); + + + /** + * \name Related functions that don't actually operate on GLmatrix structs + */ + /*@{*/ + + void + _math_transposef( GLfloat to[16], const GLfloat from[16] ); + + void + _mesa_transform_vector(GLfloat u[4], const GLfloat v[4], const GLfloat m[16]); + +#ifdef __cplusplus +} +#endif + +/* + * Transform a point (column vector) by a matrix: Q = M * P + */ +#define TRANSFORM_POINT( Q, M, P ) \ +Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; \ +Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; \ +Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; \ +Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; + + +#define TRANSFORM_POINT3( Q, M, P ) \ +Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; \ +Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; \ +Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; \ +Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; + + +/* + * Transform a normal (row vector) by a matrix: [NX NY NZ] = N * MAT + */ +#define TRANSFORM_NORMAL( TO, N, MAT ) \ +do { \ +TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2]; \ +TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6]; \ +TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10]; \ +} while (0) + + +/** + * Transform a direction by a matrix. + */ +#define TRANSFORM_DIRECTION( TO, DIR, MAT ) \ +do { \ +TO[0] = DIR[0] * MAT[0] + DIR[1] * MAT[4] + DIR[2] * MAT[8]; \ +TO[1] = DIR[0] * MAT[1] + DIR[1] * MAT[5] + DIR[2] * MAT[9]; \ +TO[2] = DIR[0] * MAT[2] + DIR[1] * MAT[6] + DIR[2] * MAT[10];\ +} while (0) + + +/*@}*/ + + +#endif diff --git a/test/main.cpp b/test/main.cpp index fd1a561..1011056 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,400 +1,458 @@ -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include <cstdlib> -#include <cstdio> -#include <getopt.h> +#include <assert.h> +#include <stdio.h> #include <stdlib.h> -#include <time.h> #include <string.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> +#include <time.h> +#include <math.h> #include <unistd.h> + +#define DRAW_TO_SCREEN 1 +#define USE_16BPP_TEXTURE 0 // forces texture to load as 16bpp + +#ifdef __arm__ +#define PATH_PREFIX "/data/" +#else +#define PATH_PREFIX "" +#endif + #include <pixelflinger2/pixelflinger2_interface.h> -#include "../src/talloc/hieralloc.h" +#include "image_file.h" +#include "m_matrix.h" + +#ifdef __arm__ +extern "C" int SetupDrawingSurface(unsigned * width, unsigned * height, unsigned * bpp); +extern "C" void * PresentDrawingSurface(); +extern "C" void DisposeDrawingSurface(); +#endif GGLInterface * ggl = NULL; -/* Returned string will have 'ctx' as its hieralloc owner. */ -static char * -load_text_file(void *ctx, const char *file_name) +gl_shader * load_shader(const unsigned type, const char * path) { - char *text = NULL; - struct stat st; - ssize_t total_read = 0; - int fd = open(file_name, O_RDONLY); - - if (fd < 0) { - return NULL; - } + FILE * file = NULL; + file = fopen(path, "rb"); + if (!file) + printf("failed to open '%s' \n", path); + + fseek(file, 0, SEEK_END); + unsigned fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + + char * shader_string = (char *)malloc(fileSize + 1); + printf("fileSize=%dB \n", fileSize); + int read = fread(shader_string, 1, fileSize, file); + shader_string[read] = '\0'; + fclose(file); + + puts(shader_string); + puts("compiling shader..."); + + gl_shader * shader = ggl->ShaderCreate(ggl, type); + const char * infoLog = NULL; + GLboolean compileStatus = ggl->ShaderCompile(ggl, shader, shader_string, &infoLog); + + printf("shader.InfoLog = %s \nshader.CompileStatus = %d \n\n", + infoLog, compileStatus); + if (!compileStatus) + exit(1); + + free(shader_string); + return shader; +} - if (fstat(fd, & st) == 0) { - text = (char *) hieralloc_size(ctx, st.st_size + 1); - if (text != NULL) { - do { - ssize_t bytes = read(fd, text + total_read, - st.st_size - total_read); - if (bytes < 0) { - free(text); - text = NULL; - break; - } +gl_shader_program * init_shader() +{ + puts("\n -- load vertex shader -- \n"); + struct gl_shader * vertShader = load_shader(GL_VERTEX_SHADER, PATH_PREFIX"vs.vert"); - if (bytes == 0) { - break; - } + puts("\n -- load fragment shader -- \n"); + struct gl_shader * fragShader = load_shader(GL_FRAGMENT_SHADER, PATH_PREFIX"fs.frag"); - total_read += bytes; - } while (total_read < st.st_size); + gl_shader_program * program = ggl->ShaderProgramCreate(ggl); + // current scan_test assumes the following attribute layout + ggl->ShaderAttributeBind(ggl, program, 0, "aPosition"); + ggl->ShaderAttributeBind(ggl, program, 1, "aTexCoord"); - text[total_read] = '\0'; - } - } + puts("\n -- linking -- \n"); + ggl->ShaderAttach(ggl, program, vertShader); + ggl->ShaderAttach(ggl, program, fragShader); + const char * infoLog = NULL; + GLboolean linkStatus = ggl->ShaderProgramLink(ggl, program, &infoLog); - close(fd); + printf("finished linking, LinkStatus=%d \n %s \n", linkStatus, infoLog); - return text; -} + if (!linkStatus) + exit(1); -int glsl_es = 0; -int dump_ast = 0; -int dump_hir = 0; -int dump_lir = 0; -int do_link = 0; -int do_jit = 0; - -const struct option compiler_opts[] = { - { "glsl-es", 0, &glsl_es, 1 - }, { "dump-ast", 0, &dump_ast, 1 }, { "dump-hir", 0, &dump_hir, 1 }, { "dump-lir", 0, &dump_lir, 1 }, { "link", 0, &do_link, 1 }, { "do-jit", 0, &do_jit, 1 }, { NULL, 0, NULL, 0 } -}; - -/** - * \brief Print proper usage and exit with failure. - */ -void -usage_fail(const char *name) -{ + ggl->ShaderUse(ggl, program); - const char *header = - "usage: %s [options] <file.vert | file.geom | file.frag>\n" - "\n" - "Possible options are:\n"; - printf(header, name, name); - for (const struct option *o = compiler_opts; o->name != 0; ++o) { - printf(" --%s\n", o->name); - } - exit(EXIT_FAILURE); + return program; } -#define DRAW_TO_SCREEN 1 -#include "image_file.h" - -#if defined __arm__ && defined DRAW_TO_SCREEN -extern "C" int SetupDrawingSurface(unsigned * width, unsigned * height, unsigned * bpp); -extern "C" void * PresentDrawingSurface(); -extern "C" void DisposeDrawingSurface(); -#endif - -void execute(const gl_shader_program * program) +void test_scan() { - puts("execute"); - - //const gl_shader * shader = ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]; - const gl_shader * shader = NULL; + srand(1337); + ggl = CreateGGLInterface(); + + GGLSurface frameSurface = {0}; #if defined __arm__ && DRAW_TO_SCREEN unsigned width = 0, height = 0, bpp = 0; - int err = SetupDrawingSurface(&width, &height, &bpp); - assert(!err); - assert(32 == bpp); - unsigned * frameSurface = (unsigned *)PresentDrawingSurface(); + SetupDrawingSurface(&width, &height, &bpp); + frameSurface.data = PresentDrawingSurface(); #else const unsigned width = 1280, height = 800; - unsigned * frameSurface = new unsigned [width * height]; + frameSurface.data = (unsigned int *)malloc(width * height * 4); #endif - //const unsigned scale = 16, portWidth = 80, portHeight = 50; - unsigned scale = 1, portWidth = width / scale, portHeight = height / scale; - //unsigned scale = 1, portWidth = width / 4, portHeight = height / 4; - - GGLSurface colorSurface = {width, height, GGL_PIXEL_FORMAT_RGBA_8888, frameSurface, width, sizeof(GGLSurface)}; - ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &colorSurface); - ggl->EnableDisable(ggl, GL_DEPTH_TEST, false); - -// float * uniform = (float *)ctx->glCtx->CurrentProgram->ValuesUniform; -// float * attribute = (float *)ctx->glCtx->CurrentProgram->ValuesVertexInput; -// float * varying = (float *)ctx->glCtx->CurrentProgram->ValuesVertexOutput; -// float * output = ((VertexOutput*)ctx->glCtx->CurrentProgram->ValuesVertexOutput)->fragColor[0].f; -// int glFragColorLocation = 0; - int vTexCoordLocation = ggl->ShaderVaryingLocation(ggl, program, "vTexCoord", NULL); -// if (shader->symbols->get_variable("vTexCoord")) -// vTexCoordLocation = shader->symbols->get_variable("vTexCoord")->location; -// int vNormalLocation = -1; -// if (shader->symbols->get_variable("vNormal")) -// vNormalLocation = shader->symbols->get_variable("vNormal")->location; -// if (shader->symbols->get_variable("uRotM") && 0) { -// ir_variable * var = shader->symbols->get_variable("uRotM"); -// float * matrix = uniform + 4 * 1 + 4 * shader->symbols->get_variable("uRotM")->location; -// memset(matrix, 0, 16 * sizeof(*matrix)); -// matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1; -// matrix[28] = 0; -// matrix[29] = 0; -// matrix[30] = 0; -// matrix[31] = 0; -// } -// printf("executing... \n function=%p \n", shader->function); - /* - #ifdef __arm__ - { - volatile unsigned wait = 1; - printf("waiting for attach, set wait(%p) to 0 \n", &wait); - puts(""); - while (wait); + frameSurface.format = GGL_PIXEL_FORMAT_RGBA_8888; + frameSurface.width = width; + frameSurface.height = height; + + GGLSurface depthSurface = {0}; + depthSurface.width = width; + depthSurface.height = height; + depthSurface.format = GGL_PIXEL_FORMAT_Z_32; + depthSurface.data = malloc(width * height * 4); + ggl->SetBuffer(ggl, GL_DEPTH_BUFFER_BIT, &depthSurface); + + GGLSurface stencilSurface = {0}; + stencilSurface.width = width; + stencilSurface.height = height; + stencilSurface.format = GGL_PIXEL_FORMAT_S_8; + stencilSurface.data = malloc(width * height); + + ggl->SetBuffer(ggl, GL_STENCIL_BUFFER_BIT, &stencilSurface); + ggl->ClearStencil(ggl, 0); + ggl->StencilFuncSeparate(ggl, GL_FRONT_AND_BACK, GL_EQUAL, 0, 0xff); + ggl->StencilOpSeparate(ggl, GL_FRONT_AND_BACK, GL_INCR, GL_KEEP, GL_KEEP); + //ggl->EnableDisable(ggl, GL_STENCIL_TEST, true); + + gl_shader_program * program = init_shader(); // change states after to test code cache + + GGLTexture texture = {0}; + LoadTGA(PATH_PREFIX"android.tga", &texture.width, &texture.height, + &texture.levels); +// for (unsigned i = 0; i < texture.width * texture.height; i++) +// { +// const unsigned x = i % 480, y = i / 480; +// ((unsigned *)texture.levels[0])[i] = ((x + y) % 2) * 0xffffff | 0xff000000; +// } +#if USE_16BPP_TEXTURE + texture.format = GGL_PIXEL_FORMAT_RGB_565; +#else + texture.format = GGL_PIXEL_FORMAT_RGBA_8888; +#endif + texture.type = GL_TEXTURE_2D; + texture.levelCount = 1; + texture.wrapS = texture.wrapT = 0; // repeat = 0 fastest, clamp = 1, mirrored = 2 + texture.minFilter = texture.magFilter = 0; // nearest = 0, linear = 1 + //texture.levelCount = GenerateMipmaps(texture.levels, texture.width, texture.height); + + // static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000, + // 0xff00ffff, 0xffffff00, 0xffff00ff}; + // memcpy(texture.levels[0], texels, sizeof texels); + // texture.format = GGL_PIXEL_FORMAT_RGBA_8888; + // texture.width = texture.height = 1; + //texture.height /= 6; + //texture.type = GL_TEXTURE_CUBE_MAP; + + ggl->SetSampler(ggl, 0, &texture); + + //ggl->EnableDisable(ggl, GL_CULL_FACE, true); + ggl->FrontFace(ggl, GL_CW); + ggl->CullFace(ggl, GL_BACK); + + ggl->EnableDisable(ggl, GL_BLEND, true); + ggl->BlendFuncSeparate(ggl, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR, + GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR); + ggl->BlendEquationSeparate(ggl, GL_FUNC_ADD, GL_FUNC_ADD); + ggl->BlendColor(ggl, 0.7, 0.7, 0.7, 1); + + ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &frameSurface); + + + ggl->EnableDisable(ggl, GL_DEPTH_TEST, true); + ggl->DepthFunc(ggl, GL_LESS); + + ggl->DepthRangef(ggl, 0.0f, 1.0f); + ggl->Viewport(ggl, 0, 0, width, height); + + const unsigned scale = 1, portWidth = 640, portHeight = 400; + //const unsigned scale = 1, portWidth = width / scale, portHeight = height / scale; + ggl->Viewport(ggl, 0, 0, portWidth, portHeight); + //ggl->Viewport(ggl, (width - portWidth) / 2, (height - portHeight) / 2, + //portWidth, portHeight); + + GLmatrix m0, m1, m2, m3, m4; + _math_matrix_ctr(&m0); + _math_matrix_ctr(&m1); + _math_matrix_ctr(&m2); + _math_matrix_ctr(&m3); + _math_matrix_ctr(&m4); + + int uMatrixLoc = ggl->ShaderUniformLocation(ggl, program, "uMatrix"); + int uRotMLoc = ggl->ShaderUniformLocation(ggl, program, "uRotM"); + int uTLoc = ggl->ShaderUniformLocation(ggl, program, "t"); + + GGLTexture cubeTexture = {GL_TEXTURE_CUBE_MAP, GGL_PIXEL_FORMAT_RGBA_8888, 1, 1, 1, NULL, 1, 2, 1, 1}; + unsigned cubeTextureSurface [6] = {0xff0000ff, 0xff00ff00, 0xffff0000, + 0xff00ffff, 0xffffff00, 0xffff00ff + }; + void * levels [1] = {cubeTextureSurface}; + cubeTexture.levels = levels; + if (program) { + ggl->ShaderUniformMatrix(ggl, program, 4, 4, uMatrixLoc, 1, GL_FALSE, m0.m); + int sampler2dLoc = ggl->ShaderUniformLocation(ggl, program, "sampler2d"); + int samplercubeLoc = ggl->ShaderUniformLocation(ggl, program, "samplercube"); + int samplerUnit = -1; + if (0 <= sampler2dLoc) { // set 2d texture to sampler if used + samplerUnit = sampler2dLoc;//ggl->ShaderUniformGetiv(ggl, program, sampler2dLoc, &samplerUnit); + ggl->SetSampler(ggl, samplerUnit, &texture); + } + if (0 <= samplercubeLoc) { // set cube texture to sampler if used + samplerUnit = samplercubeLoc;//ggl->ShaderUniformGetiv(ggl, program, samplercubeLoc, &samplerUnit); + ggl->SetSampler(ggl, samplerUnit, &cubeTexture); + } } - #endif - //*/ + VertexInput v0, v1, v2, v3; + const float z = +0.5; +// const float vcMin = -10, vcMax = 10; +// const float tcMin = -4.5, tcMax = 5.5; + const float vcMin = -1, vcMax = 1; + const float tcMin = 0, tcMax = 1; + v0.attributes[0] = Vector4_CTR(vcMin,vcMin,z,1); + v0.attributes[1] = Vector4_CTR(tcMin,tcMin,0,1); + + v1.attributes[0] = Vector4_CTR(vcMin,vcMax,z,1); + v1.attributes[1] = Vector4_CTR(tcMin,tcMax,0,1); + + v2.attributes[0] = Vector4_CTR(vcMax,vcMax,z,1); + v2.attributes[1] = Vector4_CTR(tcMax,tcMax,0,1); + + v3.attributes[0] = Vector4_CTR(vcMax,vcMin,z,1); + v3.attributes[1] = Vector4_CTR(tcMax,tcMin,0,1); + + VertexInput vertices[8] = { + // pos texcoord + {{Vector4_CTR(-1,-1,-1,1), Vector4_CTR(tcMin,tcMin,0,1)}}, + {{Vector4_CTR(-1,-1, 1,1), Vector4_CTR(tcMin,tcMax,0,1)}}, + {{Vector4_CTR( 1,-1, 1,1), Vector4_CTR(tcMax,tcMax,0,1)}}, + {{Vector4_CTR( 1,-1,-1,1), Vector4_CTR(tcMax,tcMin,0,1)}}, + {{Vector4_CTR(-1, 1,-1,1), Vector4_CTR(tcMin,tcMin,0,1)}}, + {{Vector4_CTR(-1, 1, 1,1), Vector4_CTR(tcMin,tcMax,0,1)}}, + {{Vector4_CTR( 1, 1, 1,1), Vector4_CTR(tcMax,tcMax,0,1)}}, + {{Vector4_CTR( 1, 1,-1,1), Vector4_CTR(tcMax,tcMin,0,1)}}, + }; + + unsigned indices[] = { + 0,1,2, 0,2,3, + 4,5,6, 4,6,7, + 0,3,4, 3,4,7, + 1,2,5, 2,5,6, + 0,1,4, 1,4,5, + 2,3,6, 3,6,7, + }; + + Vector4 pos = v0.attributes[0]; + ggl->ViewportTransform(ggl, &pos); + + ggl->ClearColor(ggl, 0.8f, 0.8f, 1, 1); + //ggl->ClearDepthf(ggl, pos.z + 0.0001f); // when there is no transform in vs + ggl->ClearDepthf(ggl, 1); + ggl->EnableDisable(ggl, GL_BLEND, false); + //ggl->EnableDisable(ggl, GL_DEPTH_TEST, false); + ggl->EnableDisable(ggl, GL_STENCIL_TEST, false); + + + ggl->DrawTriangle(ggl, &v0, &v0, &v0); // cause re-JIT to not mess up timing + puts("\n -- begin rendering -- \n"); - unsigned frames = 1; + unsigned frames = 0; clock_t c0 = clock(); - //while(true) - for (frames = 1; frames <= 10; frames++) { - for (unsigned y = 0; y < portHeight; y++) { - VertexOutput v0, v1; - v0.position = Vector4(0, y, 0, 0); - v1.position = Vector4(portWidth - 1, y ,0 ,0); - if (vTexCoordLocation > -1) { - v0.varyings[vTexCoordLocation - 2] = Vector4(0, (float)y / (portHeight - 1), 0, 1); - v1.varyings[vTexCoordLocation - 2] = Vector4(1, (float)y / (portHeight - 1), 0, 1); - } - ggl->ScanLine(ggl, &v0, &v1); - -// for (unsigned x = 0; x < portWidth; x++) { -// if (vTexCoordLocation > -1) +#ifdef __arm__ + //while (true) +#endif + for ( +#ifdef __arm__ + unsigned i = 0; i <= 100; i++ +#else + unsigned i = 0; i <= 1; i+= 1 +#endif + ) { + + ggl->Clear(ggl, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //ggl->Clear(ggl, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + _math_matrix_set_identity(&m0); + _math_matrix_set_identity(&m1); + _math_matrix_set_identity(&m2); + //_math_matrix_set_identity(&m3); + + + //_math_matrix_ortho(&m0, 0, 480, 0, 800, 0.1, 1); + _math_matrix_perspective(&m0, 60, (float)width / height, 0.1f, 100); + //float ratio = (float)width / height; + //_math_matrix_frustum(&m0, -ratio, ratio, -1, 1, 3, 7); + + _math_matrix_lookat(&m1, 0, 0, -6, + 0, 0, 2, + 0, 1, 0); + + //_math_matrix_scale(&m0, 0.2, 0.2, 0.2); + //_math_matrix_translate(&m2, 1, 1, 1); + _math_matrix_rotate(&m2, i, 1, 2, 3); + //_math_matrix_rotate(&m2, i, 0, 0, 1); + + // matrix on the right is applied to vector first + _math_matrix_mul_matrix(&m3, &m1, &m2); + _math_matrix_mul_matrix(&m4, &m0, &m3); + + + float t = i * 0.6f; + if (program) { + ggl->ShaderUniformMatrix(ggl, program, 4, 4, uMatrixLoc, 1, GL_FALSE, m4.m); + ggl->ShaderUniformMatrix(ggl, program, 4, 4, uRotMLoc, 1, GL_FALSE, m2.m); + ggl->ShaderUniform(ggl, program, uTLoc, 1, &t, GL_FLOAT); + } + + //ggl->EnableDisable(ggl, GL_BLEND, true); + //ggl->EnableDisable(ggl, GL_BLEND, false); + //ggl->EnableDisable(ggl, GL_BLEND, (i + 1) % 2); + //ggl->EnableDisable(ggl, GL_STENCIL_TEST, i / 2 % 2); + //ggl->BlendColor(ggl,(float)i / 10, (float) i / 15, (float)i < 20, 1); + + for (unsigned j = 0; j < sizeof(indices) / sizeof(*indices); j += 3) + ggl->DrawTriangle(ggl, vertices + indices[j], vertices + indices[j+1], vertices + indices[j+2]); + + // including clear, depth, and other ops, direct ScanLine calls are 4% faster than DrawTriangle + // X86 memcpy is 0.60ms vs 4.90ms for 480*800 fs texturing + // Nexus One memcpy is 8.7ms vs 71ms for 480*800 fs texturing + // Nexus One fixed point 480*800 fs texturing is 61ms + // texture * vtexcoord is 70ms, floating texture * vtexcoord is 170ms + //memcpy(((GGLContext *)ggl)->frameSurface.data, ((GGLContext *)ggl)->textureState.textures[0].levels[0], width * height * 4); + +// ggl->DrawTriangle(ggl, &v0, &v1, &v2); +// ggl->DrawTriangle(ggl, &v2, &v3, &v0); + +// VertexOutput tl = {0, Vector4(0,0,0,1), Vector4(0,0,0,1)}; +// VertexOutput tr = {0, Vector4(portWidth - 1,0,0,1), Vector4(1,0,0,1)}; +// VertexOutput bl = {0, Vector4(0, portHeight-1,0,1), Vector4(0,1,0,1)}; +// VertexOutput br = {0, Vector4(portWidth - 1, portHeight - 1,0,1), Vector4(1,1,0,1)}; +// ggl->RasterTrapezoid(ggl, &tl, &tr, &bl, &br); +// +// for (unsigned y = 0; y < portHeight; y++) +// { +// VertexOutput vo0 = {0, Vector4(0,y,0,1), Vector4(0,float(y) / (portHeight - 1),0,1)}; +// VertexOutput vo1 = {0, Vector4(portWidth - 1,y,0,1), Vector4(1,float(y) / (portHeight - 1),0,1)}; +// ggl->ScanLine(ggl, &vo0, &vo1); +// } + +//#if !USE_LLVM_TEXTURE_SAMPLER +// extern const GGLContext * textureGGLContext; +// textureGGLContext = (GGLContext *)ggl; +//#endif +// for (unsigned y = 0; y < height; y++) +// for (unsigned x = 0; x < width; x++) // { -// varying[vTexCoordLocation * 4 + 0] = ((float)x) / (portWidth - 1); -// varying[vTexCoordLocation * 4 + 1] = ((float)y) / (portHeight - 1); -// varying[vTexCoordLocation * 4 + 2] = 0; -// varying[vTexCoordLocation * 4 + 3] = 1; +// const unsigned index = y * width + x; +//// ((unsigned *)frameSurface.data)[index] = ((unsigned *)textureGGLContext->textureState.textures[0].levels[0])[index]; +// Vector4 tc(float(x) / (width - 1), float(y) / (height - 1), 0, 0); +// unsigned color[4]; +// tex2d_int32<GGL_PIXEL_FORMAT_RGBA_8888>(color, (const float *)&tc, 0); +// ((unsigned *)frameSurface.data)[index] = color[0]; // } -//// if (vNormalLocation > -1) -//// { -//// varying[vNormalLocation * 4 + 0] = 0; -//// varying[vNormalLocation * 4 + 1] = 1; -//// varying[vNormalLocation * 4 + 2] = 0; -//// varying[vNormalLocation * 4 + 3] = 1; -//// } -// shader->function(); -// unsigned r = output[0] * 255; -// unsigned g = output[1] * 255; -// unsigned b = output[2] * 255; -// unsigned a = output[3] * 255; -// frameSurface[y * width + x] = (a << 24) | (b << 16) | (g << 8) | r; -// } - } - //* +//#if !USE_LLVM_TEXTURE_SAMPLER +// textureGGLContext = NULL; +//#endif + + frames++; if (scale > 1) for (int y = portHeight - 1; y >= 0; y--) for (int x = portWidth - 1; x >= 0; x--) { - unsigned pixel = ((unsigned *)frameSurface)[y * width + x]; + unsigned pixel = ((unsigned *)frameSurface.data)[y * width + x]; for (unsigned xx = 0; xx < scale; xx++) for (unsigned yy = 0; yy < scale; yy++) - ((unsigned *)frameSurface)[(y * scale + yy) * width + x * scale + xx] = pixel; + ((unsigned *)frameSurface.data)[(y * scale + yy) * width + x * scale + xx] = pixel; } - //*/ + #if defined __arm__ && DRAW_TO_SCREEN - frameSurface = (unsigned *)PresentDrawingSurface(); - colorSurface.data = frameSurface; - ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &colorSurface); + frameSurface.data = PresentDrawingSurface(); + ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, &frameSurface); #endif + //puts("frame completed, press ENTER"); getchar(); + } + + /* + #ifndef __arm__ + __attribute__ ((aligned (16))) // LLVM generates movaps on X86, needs 16 bytes align + #endif + float data [64]; + ShaderFunction_t function = ((GGLContext *)ggl)->glCtx->Shader.CurrentProgram->GLVMFP->function; + float * inputs = data; + float * outputs = data + 24; + float * constants = data + 48; + const unsigned wd = 200, ht = 200; + for (unsigned y = 0; y < ht; y++) + for (unsigned x = 0; x < wd; x++) + { + inputs[4] = ((float)x) / wd; + inputs[5] = ((float)y) / ht; + inputs[6] = 0; + inputs[7] = 1; + constants[0] = 0.0f; + function(inputs, outputs, constants); + unsigned r = outputs[0] * 255; + unsigned g = outputs[1] * 255; + unsigned b = outputs[2] * 255; + unsigned a = outputs[3] * 255; + ((unsigned *)frameSurface.data)[y * width + x] = (a << 24) | (b << 16) | (g << 8) | r; } + printf("gl_FragColor=%.2f, %.2f, %.2f %.2f \n", outputs[0], outputs[1], outputs[2], outputs[3]); + frames = 1; + //*/ float elapsed = (float)(clock() - c0) / CLOCKS_PER_SEC; printf ("\n *** test_scan elapsed CPU time: %fs \n *** fps=%.2f, tpf=%.2fms \n", elapsed, frames / elapsed, elapsed / frames * 1000); - //printf("gl_FragColor=%.2f, %.2f, %.2f %.2f \n", output[0], output[1], output[2], output[3]); -#if defined __arm__ - SaveBMP("/sdcard/mesa.bmp", frameSurface, width, height); -#else - SaveBMP("mesa.bmp", frameSurface, width, height); +#if USE_16BPP_TEXTURE + puts("USE_16BPP_TEXTURE"); #endif - //assert(0.1f < output[3]); -#if DRAW_TO_SCREEN - void DisposeDrawingSurface(); +#ifdef __arm__ + SaveBMP("/sdcard/mesa.bmp", (unsigned *)frameSurface.data, frameSurface.width, frameSurface.height); #else - delete frameSurface; + SaveBMP("mesa.bmp", (unsigned *)frameSurface.data, frameSurface.width, frameSurface.height); #endif -} - -extern "C" int cmain(int,char**); -int -main(int argc, char **argv) -{ - cmain(0,NULL); - - static char basePath [256] = {0}; - static char texturePath [256] = {0}; - static char fragPath [256] = {0}; - static char vertPath [256] = {0}; - static char cubeTexturePath [256] = {0}; - static const char fragFile[] = "fs.frag"; - static const char vertFile[] = "vs.vert"; - static const char textureFile[] = "android.tga"; - static const char cubeTextureFile[] = "cube.tga"; - - strncpy(basePath, argv[0], strrchr(argv[0], '/') - argv[0] + 1); - strcpy(fragPath, basePath); - strcat(fragPath, fragFile); - strcpy(vertPath, basePath); - strcat(vertPath, vertFile); - strcpy(texturePath, basePath); - strcat(texturePath, textureFile); - strcpy(cubeTexturePath, basePath); - strcat(cubeTexturePath, cubeTextureFile); - //* - if (1 == argc) { - const char * args [] = {argv[0], "--dump-hir", "--do-jit", "--link", "--glsl-es", fragPath, vertPath}; - argc = sizeof(args) / sizeof(*args); - argv = (char **)args; - } - //*/ - int status = EXIT_SUCCESS; - int c; - int idx = 0; - while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1) - /* empty */ ; - - - if (argc <= optind) - usage_fail(argv[0]); - - //initialize_context(ctx, (glsl_es) ? API_OPENGLES2 : API_OPENGL); - ggl = CreateGGLInterface(); - - struct gl_shader_program * program = ggl->ShaderProgramCreate(ggl); - for (/* empty */; argc > optind; optind++) { - const unsigned len = strlen(argv[optind]); - if (len < 6) - usage_fail(argv[0]); - - const char *const ext = & argv[optind][len - 5]; - GLenum Type; - if (strncmp(".vert", ext, 5) == 0) - Type = GL_VERTEX_SHADER; - else if (strncmp(".geom", ext, 5) == 0) - //Type = GL_GEOMETRY_SHADER; - assert(0); - else if (strncmp(".frag", ext, 5) == 0) - Type = GL_FRAGMENT_SHADER; - else - usage_fail(argv[0]); - - struct gl_shader * shader = ggl->ShaderCreate(ggl, Type); - - - char * source = load_text_file(program, argv[optind]); - if (source == NULL) { - printf("File \"%s\" does not exist.\n", argv[optind]); - exit(EXIT_FAILURE); - } - - const char * infoLog = NULL; - if (!ggl->ShaderCompile(ggl, shader, source, &infoLog)) { - printf("Info log for %s:\n%s\n", argv[optind], infoLog); - status = EXIT_FAILURE; - break; - } - hieralloc_free(source); - ggl->ShaderAttach(ggl, program, shader); - } - - puts("link"); - - if ((status == EXIT_SUCCESS) && do_link) { - const char * infoLog = NULL; - bool linkStatus = ggl->ShaderProgramLink(ggl, program, &infoLog); - status = linkStatus ? EXIT_SUCCESS : EXIT_FAILURE; - assert(linkStatus); - if (strlen(infoLog) > 0) - printf("Info log for linking:\n%s\n", infoLog); - } - - puts("jit"); - - GGLTexture texture = {0}; - LoadTGA(texturePath, &texture.width, &texture.height, &texture.levels); - texture.format = GGL_PIXEL_FORMAT_RGBA_8888; - texture.type = GL_TEXTURE_2D; - texture.levelCount = 1; - texture.wrapS = texture.wrapT = 0; // repeat = 0 fastest, clamp = 1, mirrored = 2 - texture.minFilter = texture.magFilter = 0; // nearest = 0, linear = 1 - ggl->SetSampler(ggl, 0, &texture); - - ggl->ShaderUse(ggl, program); - - texture.minFilter = texture.magFilter = 1; // nearest = 0, linear = 1 - ggl->SetSampler(ggl, 0, &texture); - - ggl->ShaderUse(ggl, program); - - static unsigned cubeTextureSurface [6] = {0xff0000ff, 0xff00ff00, 0xffff0000, - 0xff00ffff, 0xffffff00, 0xffff00ff - }; - GGLTexture cubeTexture = {GL_TEXTURE_CUBE_MAP, GGL_PIXEL_FORMAT_RGBA_8888, 1, 1, 1, cubeTextureSurface, 1, 2, 1, 1}; + ggl->SetBuffer(ggl, GL_COLOR_BUFFER_BIT, NULL); +#if defined __arm__ && DRAW_TO_SCREEN + //DisposeDrawingSurface(); +#else + free(frameSurface.data); +#endif + ggl->SetBuffer(ggl, GL_DEPTH_BUFFER_BIT, NULL); + free(depthSurface.data); - int samplerLocation = -1; - if (0 <= (samplerLocation = ggl->ShaderUniformLocation(ggl, program, "samp2D"))) - ggl->SetSampler(ggl, samplerLocation, &texture); - if (0 <= (samplerLocation = ggl->ShaderUniformLocation(ggl, program, "samp2DA"))) - ggl->SetSampler(ggl, samplerLocation, &texture); - if (0 <= (samplerLocation = ggl->ShaderUniformLocation(ggl, program, "sampCube"))) - ggl->SetSampler(ggl, samplerLocation, &texture); + ggl->SetBuffer(ggl, GL_STENCIL_BUFFER_BIT, NULL); + free(stencilSurface.data); - execute(program); -// puts("\n *** IR for JIT *** \n"); -// //_mesa_print_ir(ir, NULL); -// -// shader->executable = hieralloc_zero(shader, Executable); -// llvm::Module * module = glsl_ir_to_llvm_module(shader->ir, (GGLContext *)ggl); -// assert(module); -// shader->executable->module = module; -// puts("\n *** Module for JIT *** \n"); -// //module->dump(); -// jit(shader, program, (GGLContext *)ggl); -// puts("jitted"); + if (program) + ggl->ShaderProgramDelete(ggl, program); free(texture.levels); - ggl->ShaderProgramDelete(ggl, program); + DestroyGGLInterface(ggl); + ggl = NULL; +} - DestroyGGLInterface((GGLInterface *)ggl); - printf("mesa exit(%d) \n", status); - hieralloc_report_brief(NULL, stdout); - return status; +int main (int argc, char * const argv[]) +{ + test_scan(); + puts("mesa done"); + return 0; } diff --git a/test/mesa.project b/test/mesa.project index 384df00..f88f153 100644 --- a/test/mesa.project +++ b/test/mesa.project @@ -12,6 +12,8 @@ <File Name="main.cpp"/> <File Name="egl.cpp"/> <File Name="cmain.c"/> + <File Name="m_matrix.c"/> + <File Name="m_matrix.h"/> </VirtualDirectory> <Settings Type="Executable"> <Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append"> |