1 /* 2 * Mesa 3-D graphics library 3 * Version: 4.1 4 * 5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Keith Whitwell <keith (at) tungstengraphics.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", __FUNCTION__); 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