/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 I915_STATE_INLINES_H #define I915_STATE_INLINES_H #include "p_defines.h" #include "i915_reg.h" static INLINE unsigned i915_translate_compare_func(unsigned func) { switch (func) { case PIPE_FUNC_NEVER: return COMPAREFUNC_NEVER; case PIPE_FUNC_LESS: return COMPAREFUNC_LESS; case PIPE_FUNC_LEQUAL: return COMPAREFUNC_LEQUAL; case PIPE_FUNC_GREATER: return COMPAREFUNC_GREATER; case PIPE_FUNC_GEQUAL: return COMPAREFUNC_GEQUAL; case PIPE_FUNC_NOTEQUAL: return COMPAREFUNC_NOTEQUAL; case PIPE_FUNC_EQUAL: return COMPAREFUNC_EQUAL; case PIPE_FUNC_ALWAYS: return COMPAREFUNC_ALWAYS; default: return COMPAREFUNC_ALWAYS; } } static INLINE unsigned i915_translate_stencil_op(unsigned op) { switch (op) { case PIPE_STENCIL_OP_KEEP: return STENCILOP_KEEP; case PIPE_STENCIL_OP_ZERO: return STENCILOP_ZERO; case PIPE_STENCIL_OP_REPLACE: return STENCILOP_REPLACE; case PIPE_STENCIL_OP_INCR: return STENCILOP_INCRSAT; case PIPE_STENCIL_OP_DECR: return STENCILOP_DECRSAT; case PIPE_STENCIL_OP_INCR_WRAP: return STENCILOP_INCR; case PIPE_STENCIL_OP_DECR_WRAP: return STENCILOP_DECR; case PIPE_STENCIL_OP_INVERT: return STENCILOP_INVERT; default: return STENCILOP_ZERO; } } static INLINE unsigned i915_translate_blend_factor(unsigned factor) { switch (factor) { case PIPE_BLENDFACTOR_ZERO: return BLENDFACT_ZERO; case PIPE_BLENDFACTOR_SRC_ALPHA: return BLENDFACT_SRC_ALPHA; case PIPE_BLENDFACTOR_ONE: return BLENDFACT_ONE; case PIPE_BLENDFACTOR_SRC_COLOR: return BLENDFACT_SRC_COLR; case PIPE_BLENDFACTOR_INV_SRC_COLOR: return BLENDFACT_INV_SRC_COLR; case PIPE_BLENDFACTOR_DST_COLOR: return BLENDFACT_DST_COLR; case PIPE_BLENDFACTOR_INV_DST_COLOR: return BLENDFACT_INV_DST_COLR; case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return BLENDFACT_INV_SRC_ALPHA; case PIPE_BLENDFACTOR_DST_ALPHA: return BLENDFACT_DST_ALPHA; case PIPE_BLENDFACTOR_INV_DST_ALPHA: return BLENDFACT_INV_DST_ALPHA; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return BLENDFACT_SRC_ALPHA_SATURATE; case PIPE_BLENDFACTOR_CONST_COLOR: return BLENDFACT_CONST_COLOR; case PIPE_BLENDFACTOR_INV_CONST_COLOR: return BLENDFACT_INV_CONST_COLOR; case PIPE_BLENDFACTOR_CONST_ALPHA: return BLENDFACT_CONST_ALPHA; case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return BLENDFACT_INV_CONST_ALPHA; default: return BLENDFACT_ZERO; } } static INLINE unsigned i915_translate_blend_func(unsigned mode) { switch (mode) { case PIPE_BLEND_ADD: return BLENDFUNC_ADD; case PIPE_BLEND_MIN: return BLENDFUNC_MIN; case PIPE_BLEND_MAX: return BLENDFUNC_MAX; case PIPE_BLEND_SUBTRACT: return BLENDFUNC_SUBTRACT; case PIPE_BLEND_REVERSE_SUBTRACT: return BLENDFUNC_REVERSE_SUBTRACT; default: return 0; } } static INLINE unsigned i915_translate_logic_op(unsigned opcode) { switch (opcode) { case PIPE_LOGICOP_CLEAR: return LOGICOP_CLEAR; case PIPE_LOGICOP_AND: return LOGICOP_AND; case PIPE_LOGICOP_AND_REVERSE: return LOGICOP_AND_RVRSE; case PIPE_LOGICOP_COPY: return LOGICOP_COPY; case PIPE_LOGICOP_COPY_INVERTED: return LOGICOP_COPY_INV; case PIPE_LOGICOP_AND_INVERTED: return LOGICOP_AND_INV; case PIPE_LOGICOP_NOOP: return LOGICOP_NOOP; case PIPE_LOGICOP_XOR: return LOGICOP_XOR; case PIPE_LOGICOP_OR: return LOGICOP_OR; case PIPE_LOGICOP_OR_INVERTED: return LOGICOP_OR_INV; case PIPE_LOGICOP_NOR: return LOGICOP_NOR; case PIPE_LOGICOP_EQUIV: return LOGICOP_EQUIV; case PIPE_LOGICOP_INVERT: return LOGICOP_INV; case PIPE_LOGICOP_OR_REVERSE: return LOGICOP_OR_RVRSE; case PIPE_LOGICOP_NAND: return LOGICOP_NAND; case PIPE_LOGICOP_SET: return LOGICOP_SET; default: return LOGICOP_SET; } } static INLINE GLboolean i915_validate_vertices( GLuint hw_prim, GLuint nr ) { GLboolean ok; switch (hw_prim) { case PRIM3D_POINTLIST: ok = (nr >= 1); assert(ok); break; case PRIM3D_LINELIST: ok = (nr >= 2) && (nr % 2) == 0; assert(ok); break; case PRIM3D_LINESTRIP: ok = (nr >= 2); assert(ok); break; case PRIM3D_TRILIST: ok = (nr >= 3) && (nr % 3) == 0; assert(ok); break; case PRIM3D_TRISTRIP: ok = (nr >= 3); assert(ok); break; case PRIM3D_TRIFAN: ok = (nr >= 3); assert(ok); break; case PRIM3D_POLY: ok = (nr >= 3); assert(ok); break; default: assert(0); ok = 0; break; } return ok; } #endif a> 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
/*
 * Mesa 3-D graphics library
 * Version:  5.1
 *
 * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


/*
 * Matrix/vertex/vector transformation stuff
 *
 *
 * NOTES:
 * 1. 4x4 transformation matrices are stored in memory in column major order.
 * 2. Points/vertices are to be thought of as column vectors.
 * 3. Transformation of a point p by a matrix M is: p' = M * p
 */

#include "main/glheader.h"
#include "main/macros.h"

#include "m_eval.h"
#include "m_matrix.h"
#include "m_translate.h"
#include "m_xform.h"
#include "mathmod.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




GLvector4f *_mesa_project_points( GLvector4f *proj_vec,
				  const GLvector4f *clip_vec )
{
   const GLuint stride = clip_vec->stride;
   const GLfloat *from = (GLfloat *)clip_vec->start;
   const GLuint count = clip_vec->count;
   GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start;
   GLuint i;

   for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
   {
	 GLfloat oow = 1.0F / from[3];
	 vProj[i][3] = oow;
	 vProj[i][0] = from[0] * oow;
	 vProj[i][1] = from[1] * oow;
	 vProj[i][2] = from[2] * oow;
   }

   proj_vec->flags |= VEC_SIZE_4;
   proj_vec->size = 3;
   proj_vec->count = clip_vec->count;
   return proj_vec;
}






/*
 * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix.  This
 * function is used for transforming clipping plane equations and spotlight
 * directions.
 * Mathematically,  u = v * m.
 * Input:  v - input vector
 *         m - transformation matrix
 * Output:  u - transformed vector
 */
void _mesa_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] )
{
   GLfloat v0=v[0], v1=v[1], v2=v[2], v3=v[3];
#define M(row,col)  m[row + col*4]
   u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0);
   u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1);
   u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2);
   u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3);
#undef M
}


/* Useful for one-off point transformations, as in clipping.
 * Note that because the matrix isn't analysed we do too many
 * multiplies, and that the result is always 4-clean.
 */
void _mesa_transform_point_sz( GLfloat Q[4], const GLfloat M[16],
			    const GLfloat P[4], GLuint sz )
{
   if (Q == P)
      return;

   if (sz == 4)
   {
      Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] *  P[2] + M[12] * P[3];