Home | History | Annotate | Download | only in radeon
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Keith Whitwell <keithw (at) vmware.com>
     26  */
     27 
     28 #ifndef LOCALVARS
     29 #define LOCALVARS
     30 #endif
     31 
     32 #undef TCL_DEBUG
     33 #ifndef TCL_DEBUG
     34 #define TCL_DEBUG 0
     35 #endif
     36 
     37 static void TAG(emit)( struct gl_context *ctx,
     38 		       GLuint start, GLuint end,
     39 		       void *dest )
     40 {
     41    LOCALVARS
     42       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
     43    GLuint (*tc0)[4], (*tc1)[4], (*tc2)[4];
     44    GLfloat (*col)[4], (*spec)[4];
     45    GLfloat (*fog)[4];
     46    GLuint (*norm)[4];
     47    GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
     48    GLuint tc2_stride, norm_stride;
     49    GLuint fill_tex = 0;
     50    GLuint rqcoordsnoswap = 0;
     51    GLuint (*coord)[4];
     52    GLuint coord_stride; /* object coordinates */
     53    int i;
     54 
     55    union emit_union *v = (union emit_union *)dest;
     56 
     57    radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
     58 
     59    coord = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_POS]->data;
     60    coord_stride = VB->AttribPtr[_TNL_ATTRIB_POS]->stride;
     61 
     62    if (DO_TEX2) {
     63       if (VB->AttribPtr[_TNL_ATTRIB_TEX2]) {
     64 	 const GLuint t2 = GET_TEXSOURCE(2);
     65 	 tc2 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->data;
     66 	 tc2_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->stride;
     67 	 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 3) {
     68 	    fill_tex |= (1<<2);
     69 	 }
     70 	 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 4) {
     71 	    rqcoordsnoswap |= (1<<2);
     72 	 }
     73       } else {
     74 	 tc2 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX2];
     75 	 tc2_stride = 0;
     76       }
     77    }
     78 
     79    if (DO_TEX1) {
     80       if (VB->AttribPtr[_TNL_ATTRIB_TEX1]) {
     81 	 const GLuint t1 = GET_TEXSOURCE(1);
     82 	 tc1 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data;
     83 	 tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride;
     84 	 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 3) {
     85 	    fill_tex |= (1<<1);
     86 	 }
     87 	 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 4) {
     88 	    rqcoordsnoswap |= (1<<1);
     89 	 }
     90       } else {
     91 	 tc1 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX1];
     92 	 tc1_stride = 0;
     93       }
     94    }
     95 
     96    if (DO_TEX0) {
     97       if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) {
     98 	 const GLuint t0 = GET_TEXSOURCE(0);
     99 	 tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride;
    100 	 tc0 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data;
    101 	 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 3) {
    102 	    fill_tex |= (1<<0);
    103 	 }
    104 	 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 4) {
    105 	    rqcoordsnoswap |= (1<<0);
    106 	 }
    107       } else {
    108 	 tc0 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX0];
    109 	 tc0_stride = 0;
    110       }
    111 
    112    }
    113 
    114    if (DO_NORM) {
    115       if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]) {
    116 	 norm_stride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
    117 	 norm = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
    118       } else {
    119 	 norm_stride = 0;
    120 	 norm = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
    121       }
    122    }
    123 
    124    if (DO_RGBA) {
    125       if (VB->AttribPtr[_TNL_ATTRIB_COLOR0]) {
    126 	 col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
    127 	 col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
    128       } else {
    129 	 col = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
    130 	 col_stride = 0;
    131       }
    132    }
    133 
    134    if (DO_SPEC_OR_FOG) {
    135       if (VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
    136 	 spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
    137 	 spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
    138       } else {
    139 	 spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
    140 	 spec_stride = 0;
    141       }
    142    }
    143 
    144    if (DO_SPEC_OR_FOG) {
    145       if (VB->AttribPtr[_TNL_ATTRIB_FOG]) {
    146 	 fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
    147 	 fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
    148       } else {
    149 	 fog = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_FOG];
    150 	 fog_stride = 0;
    151       }
    152    }
    153 
    154 
    155    if (start) {
    156       coord =  (GLuint (*)[4])((GLubyte *)coord + start * coord_stride);
    157       if (DO_TEX0)
    158 	 tc0 =  (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride);
    159       if (DO_TEX1)
    160 	 tc1 =  (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride);
    161       if (DO_TEX2)
    162 	 tc2 =  (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride);
    163       if (DO_NORM)
    164 	 norm =  (GLuint (*)[4])((GLubyte *)norm + start * norm_stride);
    165       if (DO_RGBA)
    166 	 STRIDE_4F(col, start * col_stride);
    167       if (DO_SPEC)
    168 	 STRIDE_4F(spec, start * spec_stride);
    169       if (DO_FOG)
    170 	 STRIDE_4F(fog, start * fog_stride);
    171    }
    172 
    173 
    174    {
    175       for (i=start; i < end; i++) {
    176 
    177 	 v[0].ui = coord[0][0];
    178 	 v[1].ui = coord[0][1];
    179 	 v[2].ui = coord[0][2];
    180 	 if (DO_W) {
    181 	    v[3].ui = coord[0][3];
    182 	    v += 4;
    183 	 }
    184 	 else
    185 	    v += 3;
    186 	 coord =  (GLuint (*)[4])((GLubyte *)coord +  coord_stride);
    187 
    188 	 if (DO_NORM) {
    189 	    v[0].ui = norm[0][0];
    190 	    v[1].ui = norm[0][1];
    191 	    v[2].ui = norm[0][2];
    192 	    v += 3;
    193 	    norm =  (GLuint (*)[4])((GLubyte *)norm +  norm_stride);
    194 	 }
    195 	 if (DO_RGBA) {
    196 	    UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.red, col[0][0]);
    197 	    UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.green, col[0][1]);
    198 	    UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.blue, col[0][2]);
    199 	    UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, col[0][3]);
    200 	    STRIDE_4F(col, col_stride);
    201 	    v++;
    202 	 }
    203 	 if (DO_SPEC_OR_FOG) {
    204 	    if (DO_SPEC) {
    205 	       UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.red, spec[0][0]);
    206 	       UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.green, spec[0][1]);
    207 	       UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.blue, spec[0][2]);
    208 	       STRIDE_4F(spec, spec_stride);
    209 	    }
    210 	    if (DO_FOG) {
    211 	       UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, radeonComputeFogBlendFactor(ctx, fog[0][0]));
    212 	       STRIDE_4F(fog, fog_stride);
    213 	    }
    214 	    if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
    215 	    v++;
    216 	 }
    217 	 if (DO_TEX0) {
    218 	    v[0].ui = tc0[0][0];
    219 	    v[1].ui = tc0[0][1];
    220 	    if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f);
    221 	    if (DO_PTEX) {
    222 	       if (fill_tex & (1<<0))
    223 		  v[2].f = 1.0;
    224 	       else if (rqcoordsnoswap & (1<<0))
    225 		  v[2].ui = tc0[0][2];
    226 	       else
    227 		  v[2].ui = tc0[0][3];
    228 	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
    229 	       v += 3;
    230 	    }
    231 	    else
    232 	       v += 2;
    233 	    tc0 =  (GLuint (*)[4])((GLubyte *)tc0 +  tc0_stride);
    234 	 }
    235 	 if (DO_TEX1) {
    236 	    v[0].ui = tc1[0][0];
    237 	    v[1].ui = tc1[0][1];
    238 	    if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f);
    239 	    if (DO_PTEX) {
    240 	       if (fill_tex & (1<<1))
    241 		  v[2].f = 1.0;
    242 	       else if (rqcoordsnoswap & (1<<1))
    243 		  v[2].ui = tc1[0][2];
    244 	       else
    245 		  v[2].ui = tc1[0][3];
    246 	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
    247 	       v += 3;
    248 	    }
    249 	    else
    250 	       v += 2;
    251 	    tc1 =  (GLuint (*)[4])((GLubyte *)tc1 +  tc1_stride);
    252 	 }
    253 	 if (DO_TEX2) {
    254 	    v[0].ui = tc2[0][0];
    255 	    v[1].ui = tc2[0][1];
    256 	    if (TCL_DEBUG) fprintf(stderr, "t2: %.2f %.2f ", v[0].f, v[1].f);
    257 	    if (DO_PTEX) {
    258 	       if (fill_tex & (1<<2))
    259 		  v[2].f = 1.0;
    260 	       else if (rqcoordsnoswap & (1<<2))
    261 		  v[2].ui = tc2[0][2];
    262 	       else
    263 		  v[2].ui = tc2[0][3];
    264 	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
    265 	       v += 3;
    266 	    }
    267 	    else
    268 	       v += 2;
    269 	    tc2 =  (GLuint (*)[4])((GLubyte *)tc2 +  tc2_stride);
    270 	 }
    271 	 if (TCL_DEBUG) fprintf(stderr, "\n");
    272       }
    273    }
    274 }
    275 
    276 
    277 
    278 static void TAG(init)( void )
    279 {
    280    int sz = 3;
    281    if (DO_W) sz++;
    282    if (DO_NORM) sz += 3;
    283    if (DO_RGBA) sz++;
    284    if (DO_SPEC_OR_FOG) sz++;
    285    if (DO_TEX0) sz += 2;
    286    if (DO_TEX0 && DO_PTEX) sz++;
    287    if (DO_TEX1) sz += 2;
    288    if (DO_TEX1 && DO_PTEX) sz++;
    289    if (DO_TEX2) sz += 2;
    290    if (DO_TEX2 && DO_PTEX) sz++;
    291 
    292    setup_tab[IDX].emit = TAG(emit);
    293    setup_tab[IDX].vertex_format = IND;
    294    setup_tab[IDX].vertex_size = sz;
    295 }
    296 
    297 
    298 #undef IND
    299 #undef TAG
    300 #undef IDX
    301