Home | History | Annotate | Download | only in tnl_dd
      1 
      2 /*
      3  * Mesa 3-D graphics library
      4  * Version:  3.5
      5  *
      6  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the "Software"),
     10  * to deal in the Software without restriction, including without limitation
     11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  * and/or sell copies of the Software, and to permit persons to whom the
     13  * Software is furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice shall be included
     16  * in all copies or substantial portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  * Authors:
     26  *    Keith Whitwell <keith (at) tungstengraphics.com>
     27  */
     28 #include "math/m_translate.h"
     29 
     30 #if (HAVE_HW_VIEWPORT)
     31 #define UNVIEWPORT_VARS
     32 #define UNVIEWPORT_X(x) x
     33 #define UNVIEWPORT_Y(x) x
     34 #define UNVIEWPORT_Z(x) x
     35 #endif
     36 
     37 #ifndef LOCALVARS
     38 #define LOCALVARS
     39 #endif
     40 
     41 #ifndef CHECK_HW_DIVIDE
     42 #define CHECK_HW_DIVIDE 1
     43 #endif
     44 
     45 /* These don't need to be duplicated, but there's currently nowhere
     46  * really convenient to put them.  Need to build some actual .o files in
     47  * this directory?
     48  */
     49 static void copy_pv_rgba4_spec5( struct gl_context *ctx, GLuint edst, GLuint esrc )
     50 {
     51    LOCALVARS
     52    GLubyte *verts = GET_VERTEX_STORE();
     53    GLuint size = GET_VERTEX_SIZE();
     54    GLuint *dst = (GLuint *)(verts + (edst * size));
     55    GLuint *src = (GLuint *)(verts + (esrc * size));
     56    dst[4] = src[4];
     57    dst[5] = src[5];
     58 }
     59 
     60 static void copy_pv_rgba4( struct gl_context *ctx, GLuint edst, GLuint esrc )
     61 {
     62    LOCALVARS
     63    GLubyte *verts = GET_VERTEX_STORE();
     64    GLuint size = GET_VERTEX_SIZE();
     65    GLuint *dst = (GLuint *)(verts + (edst * size));
     66    GLuint *src = (GLuint *)(verts + (esrc * size));
     67    dst[4] = src[4];
     68 }
     69 
     70 static void copy_pv_rgba3( struct gl_context *ctx, GLuint edst, GLuint esrc )
     71 {
     72    LOCALVARS
     73    GLubyte *verts = GET_VERTEX_STORE();
     74    GLuint size = GET_VERTEX_SIZE();
     75    GLuint *dst = (GLuint *)(verts + (edst * size));
     76    GLuint *src = (GLuint *)(verts + (esrc * size));
     77    dst[3] = src[3];
     78 }
     79 
     80 
     81 void TAG(translate_vertex)(struct gl_context *ctx,
     82 			   const VERTEX *src,
     83 			   SWvertex *dst)
     84 {
     85    LOCALVARS
     86    GLuint format = GET_VERTEX_FORMAT();
     87    GLfloat *s = ctx->Viewport._WindowMap.m;
     88    UNVIEWPORT_VARS;
     89 
     90    if (format == TINY_VERTEX_FORMAT) {
     91       if (HAVE_HW_VIEWPORT) {
     92 	 dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
     93 	 dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
     94 	 dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
     95 	 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
     96       } else {
     97 	 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
     98 	 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
     99 	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
    100 	 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
    101       }
    102 
    103       dst->color[0] = src->tv.color.red;
    104       dst->color[1] = src->tv.color.green;
    105       dst->color[2] = src->tv.color.blue;
    106       dst->color[3] = src->tv.color.alpha;
    107    }
    108    else {
    109       if (HAVE_HW_VIEWPORT) {
    110 	 if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
    111 	    GLfloat oow = 1.0 / src->v.w;
    112 	    dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x * oow + s[12];
    113 	    dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y * oow + s[13];
    114 	    dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z * oow + s[14];
    115 	    dst->attrib[FRAG_ATTRIB_WPOS][3] = oow;
    116 	 } else {
    117 	    dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
    118 	    dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
    119 	    dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
    120 	    dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
    121 	 }
    122       } else {
    123 	 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
    124 	 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
    125 	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
    126 	 dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
    127       }
    128 
    129       dst->color[0] = src->v.color.red;
    130       dst->color[1] = src->v.color.green;
    131       dst->color[2] = src->v.color.blue;
    132       dst->color[3] = src->v.color.alpha;
    133 
    134       dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(src->v.specular.red);
    135       dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(src->v.specular.green);
    136       dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(src->v.specular.blue);
    137 
    138       dst->attrib[FRAG_ATTRIB_FOGC][0] = UBYTE_TO_FLOAT(src->v.specular.alpha);
    139 
    140       if (HAVE_PTEX_VERTICES &&
    141 	  ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) ||
    142 	   (format == PROJ_TEX1_VERTEX_FORMAT))) {
    143 
    144 	 dst->attrib[FRAG_ATTRIB_TEX0][0] = src->pv.u0;
    145 	 dst->attrib[FRAG_ATTRIB_TEX0][1] = src->pv.v0;
    146 	 dst->attrib[FRAG_ATTRIB_TEX0][3] = src->pv.q0;
    147 
    148 	 dst->attrib[FRAG_ATTRIB_TEX1][0] = src->pv.u1;
    149 	 dst->attrib[FRAG_ATTRIB_TEX1][1] = src->pv.v1;
    150 	 dst->attrib[FRAG_ATTRIB_TEX1][3] = src->pv.q1;
    151 
    152 	 if (HAVE_TEX2_VERTICES) {
    153 	    dst->attrib[FRAG_ATTRIB_TEX2][0] = src->pv.u2;
    154 	    dst->attrib[FRAG_ATTRIB_TEX2][1] = src->pv.v2;
    155 	    dst->attrib[FRAG_ATTRIB_TEX2][3] = src->pv.q2;
    156 	 }
    157 
    158 	 if (HAVE_TEX3_VERTICES) {
    159 	    dst->attrib[FRAG_ATTRIB_TEX3][0] = src->pv.u3;
    160 	    dst->attrib[FRAG_ATTRIB_TEX3][1] = src->pv.v3;
    161 	    dst->attrib[FRAG_ATTRIB_TEX3][3] = src->pv.q3;
    162 	 }
    163       }
    164       else {
    165 	 dst->attrib[FRAG_ATTRIB_TEX0][0] = src->v.u0;
    166 	 dst->attrib[FRAG_ATTRIB_TEX0][1] = src->v.v0;
    167 	 dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
    168 
    169 	 dst->attrib[FRAG_ATTRIB_TEX1][0] = src->v.u1;
    170 	 dst->attrib[FRAG_ATTRIB_TEX1][1] = src->v.v1;
    171 	 dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0;
    172 
    173 	 if (HAVE_TEX2_VERTICES) {
    174 	    dst->attrib[FRAG_ATTRIB_TEX2][0] = src->v.u2;
    175 	    dst->attrib[FRAG_ATTRIB_TEX2][1] = src->v.v2;
    176 	    dst->attrib[FRAG_ATTRIB_TEX2][3] = 1.0;
    177 	 }
    178 
    179 	 if (HAVE_TEX3_VERTICES) {
    180 	    dst->attrib[FRAG_ATTRIB_TEX3][0] = src->v.u3;
    181 	    dst->attrib[FRAG_ATTRIB_TEX3][1] = src->v.v3;
    182 	    dst->attrib[FRAG_ATTRIB_TEX3][3] = 1.0;
    183 	 }
    184       }
    185    }
    186 
    187    dst->pointSize = ctx->Point.Size;
    188 }
    189 
    190 
    191 /* prototype to silence warning */
    192 void TAG(print_vertex)( struct gl_context *ctx, const VERTEX *v );
    193 
    194 
    195 void TAG(print_vertex)( struct gl_context *ctx, const VERTEX *v )
    196 {
    197    LOCALVARS
    198    GLuint format = GET_VERTEX_FORMAT();
    199 
    200    fprintf(stderr, "(%x) ", format);
    201 
    202    switch (format) {
    203 #if HAVE_TINY_VERTICES
    204    case TINY_VERTEX_FORMAT:
    205       fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n",
    206 	      v->v.x, v->v.y, v->v.z,
    207 	      v->tv.color.red,
    208 	      v->tv.color.green,
    209 	      v->tv.color.blue,
    210 	      v->tv.color.alpha);
    211       break;
    212 #endif
    213 #if HAVE_NOTEX_VERTICES
    214    case NOTEX_VERTEX_FORMAT:
    215       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n",
    216 	      v->v.x, v->v.y, v->v.z, v->v.w,
    217 	      v->v.color.red,
    218 	      v->v.color.green,
    219 	      v->v.color.blue,
    220 	      v->v.color.alpha,
    221 	      v->v.specular.red,
    222 	      v->v.specular.green,
    223 	      v->v.specular.blue,
    224 	      v->v.specular.alpha);
    225       break;
    226 #endif
    227 #if HAVE_TEX0_VERTICES
    228    case TEX0_VERTEX_FORMAT:
    229       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n",
    230 	      v->v.x, v->v.y, v->v.z, v->v.w,
    231 	      v->v.color.red,
    232 	      v->v.color.green,
    233 	      v->v.color.blue,
    234 	      v->v.color.alpha,
    235 	      v->v.u0,
    236 	      v->v.v0);
    237       break;
    238 #endif
    239 #if HAVE_TEX1_VERTICES
    240    case TEX1_VERTEX_FORMAT:
    241       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n",
    242 	      v->v.x, v->v.y, v->v.z, v->v.w,
    243 	      v->v.color.red,
    244 	      v->v.color.green,
    245 	      v->v.color.blue,
    246 	      v->v.color.alpha,
    247 	      v->v.u0,
    248 	      v->v.v0,
    249 	      v->v.u1,
    250 	      v->v.u2);
    251       break;
    252 #endif
    253 #if HAVE_PTEX_VERTICES
    254    case PROJ_TEX1_VERTEX_FORMAT:
    255       fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n",
    256 	      v->v.x, v->v.y, v->v.z, v->v.w,
    257 	      v->v.color.red,
    258 	      v->v.color.green,
    259 	      v->v.color.blue,
    260 	      v->v.color.alpha,
    261 	      v->pv.u0,
    262 	      v->pv.v0,
    263 	      v->pv.q0,
    264 	      v->pv.u1,
    265 	      v->pv.v1,
    266 	      v->pv.q1);
    267       break;
    268 #endif
    269    default:
    270       fprintf(stderr, "???\n");
    271       break;
    272    }
    273 
    274    fprintf(stderr, "\n");
    275 }
    276 
    277 
    278 
    279 /* Interpolate the elements of the VB not included in typical hardware
    280  * vertices.
    281  *
    282  * NOTE: All these arrays are guarenteed by tnl to be writeable and
    283  * have good stride.
    284  */
    285 #ifndef INTERP_QUALIFIER
    286 #define INTERP_QUALIFIER static
    287 #endif
    288 
    289 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
    290 
    291 
    292 INTERP_QUALIFIER void TAG(interp_extras)( struct gl_context *ctx,
    293 					  GLfloat t,
    294 					  GLuint dst, GLuint out, GLuint in,
    295 					  GLboolean force_boundary )
    296 {
    297    LOCALVARS
    298    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    299 
    300    if (VB->BackfaceColorPtr) {
    301       assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
    302 
    303       INTERP_4F( t,
    304 		    GET_COLOR(VB->BackfaceColorPtr, dst),
    305 		    GET_COLOR(VB->BackfaceColorPtr, out),
    306 		    GET_COLOR(VB->BackfaceColorPtr, in) );
    307 
    308       if (VB->BackfaceSecondaryColorPtr) {
    309 	 INTERP_3F( t,
    310 		       GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
    311 		       GET_COLOR(VB->BackfaceSecondaryColorPtr, out),
    312 		       GET_COLOR(VB->BackfaceSecondaryColorPtr, in) );
    313       }
    314    }
    315 
    316    if (VB->EdgeFlag) {
    317       VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
    318    }
    319 
    320    INTERP_VERTEX(ctx, t, dst, out, in, force_boundary);
    321 }
    322 
    323 INTERP_QUALIFIER void TAG(copy_pv_extras)( struct gl_context *ctx,
    324 					   GLuint dst, GLuint src )
    325 {
    326    LOCALVARS
    327       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    328 
    329    if (VB->BackfaceColorPtr) {
    330       COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst),
    331 		GET_COLOR(VB->BackfaceColorPtr, src) );
    332 
    333       if (VB->BackfaceSecondaryColorPtr) {
    334 	 COPY_4FV( GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
    335 		   GET_COLOR(VB->BackfaceSecondaryColorPtr, src) );
    336       }
    337    }
    338 
    339    COPY_PV_VERTEX(ctx, dst, src);
    340 }
    341 
    342 
    343 #undef INTERP_QUALIFIER
    344 #undef GET_COLOR
    345 
    346 #undef IND
    347 #undef TAG
    348