Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

View file

@ -0,0 +1,15 @@
list(APPEND SOURCE
m_debug_clip.c
m_debug_norm.c
m_debug_xform.c
m_eval.c
m_matrix.c
m_translate.c
m_vector.c
m_xform.c
precomp.h)
add_library(mesa_math STATIC ${SOURCE})
add_dependencies(mesa_math xdk)
add_pch(mesa_math precomp.h SOURCE)

View file

@ -0,0 +1,243 @@
/*
* 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)
{
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));
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 (-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)
{
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));
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 (-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)
{
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 (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)
{
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);
}

View file

@ -0,0 +1,86 @@
/*
* 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);
}

View file

@ -0,0 +1,42 @@
/*
* 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

View file

@ -0,0 +1,397 @@
/*
* 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 <precomp.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 )
{
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 ( -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)
{
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 ( 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 */

View file

@ -0,0 +1,377 @@
/*
* 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 <precomp.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 */

View file

@ -0,0 +1,320 @@
/*
* 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__ */

View file

@ -0,0 +1,333 @@
/*
* 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 <precomp.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 */

View file

@ -0,0 +1,102 @@
/*
* 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);
}

View file

@ -0,0 +1,458 @@
/*
* 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 <precomp.h>
#include <main/config.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;
}

View file

@ -0,0 +1,103 @@
/*
* 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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,221 @@
/*
* 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"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \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]);
/*@}*/
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,390 @@
/*
* 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);
}

View file

@ -0,0 +1,281 @@
/*
* 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

View file

@ -0,0 +1,747 @@
/*
* 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 <precomp.h>
#include "main/mtypes.h" /* GLchan hack */
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 );
}

View file

@ -0,0 +1,123 @@
/*
* 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 */
#include "swrast/s_chan.h"
/**
* 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

View file

@ -0,0 +1,179 @@
/*
* 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 <precomp.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);
}
}
}

View file

@ -0,0 +1,92 @@
/*
* 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

View file

@ -0,0 +1,121 @@
/*
* 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 <precomp.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
}

View file

@ -0,0 +1,167 @@
/*
* 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 );
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

View file

@ -0,0 +1,810 @@
/*
* 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
}

View file

@ -0,0 +1,14 @@
#ifndef _MESA_MATH_PCH_
#define _MESA_MATH_PCH_
#include <main/context.h>
#include <main/glheader.h>
#include <main/imports.h>
#include <main/macros.h>
#include "m_eval.h"
#include "m_matrix.h"
#include "m_translate.h"
#include "m_xform.h"
#endif /* _MESA_MATH_PCH_ */