Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / i915 / i915_texprog.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * 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
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * 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
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <strings.h>
29
30 #include "glheader.h"
31 #include "macros.h"
32 #include "enums.h"
33
34 #include "tnl/t_context.h"
35 #include "intel_batchbuffer.h"
36
37 #include "i915_reg.h"
38 #include "i915_context.h"
39 #include "i915_program.h"
40
41 static GLuint translate_tex_src_bit( struct i915_fragment_program *p,
42 GLubyte bit )
43 {
44 switch (bit) {
45 case TEXTURE_1D_BIT: return D0_SAMPLE_TYPE_2D;
46 case TEXTURE_2D_BIT: return D0_SAMPLE_TYPE_2D;
47 case TEXTURE_RECT_BIT: return D0_SAMPLE_TYPE_2D;
48 case TEXTURE_3D_BIT: return D0_SAMPLE_TYPE_VOLUME;
49 case TEXTURE_CUBE_BIT: return D0_SAMPLE_TYPE_CUBE;
50 default: i915_program_error(p, "TexSrcBit"); return 0;
51 }
52 }
53
54 static GLuint get_source( struct i915_fragment_program *p,
55 GLenum src, GLuint unit )
56 {
57 switch (src) {
58 case GL_TEXTURE:
59 if (p->src_texture == UREG_BAD) {
60
61 /* TODO: Use D0_CHANNEL_XY where possible.
62 */
63 GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
64 GLuint sampler = i915_emit_decl(p, REG_TYPE_S, unit, dim);
65 GLuint texcoord = i915_emit_decl(p, REG_TYPE_T, unit, D0_CHANNEL_ALL);
66 GLuint tmp = i915_get_temp( p );
67 GLuint op = T0_TEXLD;
68
69 if (p->VB->TexCoordPtr[unit]->size == 4)
70 op = T0_TEXLDP;
71
72 p->src_texture = i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL,
73 sampler, texcoord, op );
74 }
75
76 return p->src_texture;
77 case GL_CONSTANT:
78 return i915_emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor );
79 case GL_PRIMARY_COLOR:
80 return i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
81 case GL_PREVIOUS:
82 default:
83 i915_emit_decl(p,
84 GET_UREG_TYPE(p->src_previous),
85 GET_UREG_NR(p->src_previous), D0_CHANNEL_ALL);
86 return p->src_previous;
87 }
88 }
89
90
91 static GLuint emit_combine_source( struct i915_fragment_program *p,
92 GLuint mask,
93 GLuint unit,
94 GLenum source,
95 GLenum operand )
96 {
97 GLuint arg, src;
98
99 src = get_source(p, source, unit);
100
101 switch (operand) {
102 case GL_ONE_MINUS_SRC_COLOR:
103 /* Get unused tmp,
104 * Emit tmp = 1.0 + arg.-x-y-z-w
105 */
106 arg = i915_get_temp( p );
107 return i915_emit_arith( p, A0_ADD, arg, mask, 0,
108 swizzle(src, ONE, ONE, ONE, ONE ),
109 negate(src, 1,1,1,1), 0);
110
111 case GL_SRC_ALPHA:
112 if (mask == A0_DEST_CHANNEL_W)
113 return src;
114 else
115 return swizzle( src, W, W, W, W );
116 case GL_ONE_MINUS_SRC_ALPHA:
117 /* Get unused tmp,
118 * Emit tmp = 1.0 + arg.-w-w-w-w
119 */
120 arg = i915_get_temp( p );
121 return i915_emit_arith( p, A0_ADD, arg, mask, 0,
122 swizzle(src, ONE, ONE, ONE, ONE ),
123 negate( swizzle(src,W,W,W,W), 1,1,1,1), 0);
124 case GL_SRC_COLOR:
125 default:
126 return src;
127 }
128 }
129
130
131
132 static int nr_args( GLenum mode )
133 {
134 switch (mode) {
135 case GL_REPLACE: return 1;
136 case GL_MODULATE: return 2;
137 case GL_ADD: return 2;
138 case GL_ADD_SIGNED: return 2;
139 case GL_INTERPOLATE: return 3;
140 case GL_SUBTRACT: return 2;
141 case GL_DOT3_RGB_EXT: return 2;
142 case GL_DOT3_RGBA_EXT: return 2;
143 case GL_DOT3_RGB: return 2;
144 case GL_DOT3_RGBA: return 2;
145 default: return 0;
146 }
147 }
148
149
150 static GLboolean args_match( struct gl_texture_unit *texUnit )
151 {
152 int i, nr = nr_args(texUnit->Combine.ModeRGB);
153
154 for (i = 0 ; i < nr ; i++) {
155 if (texUnit->Combine.SourceA[i] != texUnit->Combine.SourceRGB[i])
156 return GL_FALSE;
157
158 switch(texUnit->Combine.OperandA[i]) {
159 case GL_SRC_ALPHA:
160 switch(texUnit->Combine.OperandRGB[i]) {
161 case GL_SRC_COLOR:
162 case GL_SRC_ALPHA:
163 break;
164 default:
165 return GL_FALSE;
166 }
167 break;
168 case GL_ONE_MINUS_SRC_ALPHA:
169 switch(texUnit->Combine.OperandRGB[i]) {
170 case GL_ONE_MINUS_SRC_COLOR:
171 case GL_ONE_MINUS_SRC_ALPHA:
172 break;
173 default:
174 return GL_FALSE;
175 }
176 break;
177 default:
178 return GL_FALSE; /* impossible */
179 }
180 }
181
182 return GL_TRUE;
183 }
184
185
186 static GLuint emit_combine( struct i915_fragment_program *p,
187 GLuint dest,
188 GLuint mask,
189 GLuint saturate,
190 GLuint unit,
191 GLenum mode,
192 const GLenum *source,
193 const GLenum *operand)
194 {
195 int tmp, src[3], nr = nr_args(mode);
196 int i;
197
198 for (i = 0; i < nr; i++)
199 src[i] = emit_combine_source( p, mask, unit, source[i], operand[i] );
200
201 switch (mode) {
202 case GL_REPLACE:
203 if (mask == A0_DEST_CHANNEL_ALL && !saturate)
204 return src[0];
205 else
206 return i915_emit_arith( p, A0_MOV, dest, mask, saturate, src[0], 0, 0 );
207 case GL_MODULATE:
208 return i915_emit_arith( p, A0_MUL, dest, mask, saturate,
209 src[0], src[1], 0 );
210 case GL_ADD:
211 return i915_emit_arith( p, A0_ADD, dest, mask, saturate,
212 src[0], src[1], 0 );
213 case GL_ADD_SIGNED:
214 /* tmp = arg0 + arg1
215 * result = tmp + -.5
216 */
217 tmp = i915_emit_const1f(p, .5);
218 tmp = negate(swizzle(tmp,X,X,X,X),1,1,1,1);
219 i915_emit_arith( p, A0_ADD, dest, mask, 0, src[0], src[1], 0 );
220 i915_emit_arith( p, A0_ADD, dest, mask, saturate, dest, tmp, 0 );
221 return dest;
222 case GL_INTERPOLATE: /* TWO INSTRUCTIONS */
223 /* Arg0 * (Arg2) + Arg1 * (1-Arg2)
224 *
225 * Arg0*Arg2 + Arg1 - Arg1Arg2
226 *
227 * tmp = Arg0*Arg2 + Arg1,
228 * result = (-Arg1)Arg2 + tmp
229 */
230 tmp = i915_get_temp( p );
231 i915_emit_arith( p, A0_MAD, tmp, mask, 0, src[0], src[2], src[1] );
232 i915_emit_arith( p, A0_MAD, dest, mask, saturate,
233 negate(src[1], 1,1,1,1), src[2], tmp );
234 return dest;
235 case GL_SUBTRACT:
236 /* negate src[1] */
237 return i915_emit_arith( p, A0_ADD, dest, mask, saturate, src[0],
238 negate(src[1],1,1,1,1), 0 );
239
240 case GL_DOT3_RGBA:
241 case GL_DOT3_RGBA_EXT:
242 case GL_DOT3_RGB_EXT:
243 case GL_DOT3_RGB: {
244 GLuint tmp0 = i915_get_temp( p );
245 GLuint tmp1 = i915_get_temp( p );
246 GLuint neg1 = negate(swizzle(i915_emit_const1f(p, 1),X,X,X,X), 1,1,1,1);
247 GLuint two = swizzle(i915_emit_const1f(p, 2),X,X,X,X);
248 i915_emit_arith( p, A0_MAD, tmp0, A0_DEST_CHANNEL_ALL, 0,
249 two, src[0], neg1);
250 if (src[0] == src[1])
251 tmp1 = tmp0;
252 else
253 i915_emit_arith( p, A0_MAD, tmp1, A0_DEST_CHANNEL_ALL, 0,
254 two, src[1], neg1);
255 i915_emit_arith( p, A0_DP3, dest, mask, saturate, tmp0, tmp1, 0);
256 return dest;
257 }
258
259 default:
260 return src[0];
261 }
262 }
263
264 static GLuint get_dest( struct i915_fragment_program *p, int unit )
265 {
266 if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
267 return i915_get_temp( p );
268 else if (unit != p->last_tex_stage)
269 return i915_get_temp( p );
270 else
271 return UREG(REG_TYPE_OC, 0);
272 }
273
274
275
276 static GLuint emit_texenv( struct i915_fragment_program *p, int unit )
277 {
278 struct gl_texture_unit *texUnit = &p->ctx->Texture.Unit[unit];
279 GLenum envMode = texUnit->EnvMode;
280 struct gl_texture_object *tObj = texUnit->_Current;
281 GLenum format = tObj->Image[0][tObj->BaseLevel]->Format;
282 GLuint saturate = unit < p->last_tex_stage ? A0_DEST_SATURATE : 0;
283
284 switch(envMode) {
285 case GL_BLEND: {
286 const int cf = get_source(p, GL_PREVIOUS, unit);
287 const int cc = get_source(p, GL_CONSTANT, unit);
288 const int cs = get_source(p, GL_TEXTURE, unit);
289 const int out = get_dest(p, unit);
290
291 if (format == GL_INTENSITY) {
292 /* cv = cf(1 - cs) + cc.cs
293 * cv = cf - cf.cs + cc.cs
294 */
295 /* u[2] = MAD( -cf * cs + cf )
296 * cv = MAD( cc * cs + u[2] )
297 */
298
299 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
300 negate(cf,1,1,1,1), cs, cf );
301
302 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
303 cc, cs, out );
304
305 return out;
306 } else {
307 /* cv = cf(1 - cs) + cc.cs
308 * cv = cf - cf.cs + cc.cs
309 * av = af.as
310 */
311 /* u[2] = MAD( cf.-x-y-zw * cs.xyzw + cf.xyz0 )
312 * oC = MAD( cc.xyz0 * cs.xyz0 + u[2].xyzw )
313 */
314 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
315 negate(cf,1,1,1,0),
316 cs,
317 swizzle(cf,X,Y,Z,ZERO) );
318
319
320 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
321 swizzle(cc,X,Y,Z,ZERO),
322 swizzle(cs,X,Y,Z,ZERO),
323 out );
324
325 return out;
326 }
327 }
328
329 case GL_DECAL: {
330 if (format == GL_RGB ||
331 format == GL_RGBA) {
332 int cf = get_source( p, GL_PREVIOUS, unit );
333 int cs = get_source( p, GL_TEXTURE, unit );
334 int out = get_dest(p, unit);
335
336 /* cv = cf(1-as) + cs.as
337 * cv = cf.(-as) + cf + cs.as
338 * av = af
339 */
340
341 /* u[2] = mad( cf.xyzw * cs.-w-w-w1 + cf.xyz0 )
342 * oc = mad( cs.xyz0 * cs.www0 + u[2].xyzw )
343 */
344 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0,
345 cf,
346 negate(swizzle(cs,W,W,W,ONE),1,1,1,0),
347 swizzle(cf,X,Y,Z,ZERO) );
348
349 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
350 swizzle(cs,X,Y,Z,ZERO),
351 swizzle(cs,W,W,W,ZERO),
352 out );
353 return out;
354 }
355 else {
356 return get_source( p, GL_PREVIOUS, unit );
357 }
358 }
359
360 case GL_REPLACE: {
361 const int cs = get_source( p, GL_TEXTURE, unit ); /* saturated */
362 switch (format) {
363 case GL_ALPHA: {
364 const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */
365 i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_XYZ, 0, cf, 0, 0 );
366 return cs;
367 }
368 case GL_RGB:
369 case GL_LUMINANCE: {
370 const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */
371 i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_W, 0, cf, 0, 0 );
372 return cs;
373 }
374 default:
375 return cs;
376 }
377 }
378
379 case GL_MODULATE: {
380 const int cf = get_source( p, GL_PREVIOUS, unit );
381 const int cs = get_source( p, GL_TEXTURE, unit );
382 const int out = get_dest(p, unit);
383 switch (format) {
384 case GL_ALPHA:
385 i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate,
386 swizzle(cs, ONE, ONE, ONE, W), cf, 0 );
387 break;
388 default:
389 i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate,
390 cs, cf, 0 );
391 break;
392 }
393 return out;
394 }
395 case GL_ADD: {
396 int cf = get_source( p, GL_PREVIOUS, unit );
397 int cs = get_source( p, GL_TEXTURE, unit );
398 const int out = get_dest( p, unit );
399
400 if (format == GL_INTENSITY) {
401 /* output-color.rgba = add( incoming, u[1] )
402 */
403 i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, saturate,
404 cs, cf, 0 );
405 return out;
406 }
407 else {
408 /* cv.xyz = cf.xyz + cs.xyz
409 * cv.w = cf.w * cs.w
410 *
411 * cv.xyzw = MAD( cf.111w * cs.xyzw + cf.xyz0 )
412 */
413 i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate,
414 swizzle(cf,ONE,ONE,ONE,W),
415 cs,
416 swizzle(cf,X,Y,Z,ZERO) );
417 return out;
418 }
419 break;
420 }
421 case GL_COMBINE: {
422 GLuint rgb_shift, alpha_shift, out, shift;
423 GLuint dest = get_dest(p, unit);
424
425 /* The EXT version of the DOT3 extension does not support the
426 * scale factor, but the ARB version (and the version in OpenGL
427 * 1.3) does.
428 */
429 switch (texUnit->Combine.ModeRGB) {
430 case GL_DOT3_RGB_EXT:
431 alpha_shift = texUnit->Combine.ScaleShiftA;
432 rgb_shift = 0;
433 break;
434
435 case GL_DOT3_RGBA_EXT:
436 alpha_shift = 0;
437 rgb_shift = 0;
438 break;
439
440 default:
441 rgb_shift = texUnit->Combine.ScaleShiftRGB;
442 alpha_shift = texUnit->Combine.ScaleShiftA;
443 break;
444 }
445
446
447 /* Emit the RGB and A combine ops
448 */
449 if (texUnit->Combine.ModeRGB == texUnit->Combine.ModeA &&
450 args_match( texUnit )) {
451 out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate,
452 unit,
453 texUnit->Combine.ModeRGB,
454 texUnit->Combine.SourceRGB,
455 texUnit->Combine.OperandRGB );
456 }
457 else if (texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT ||
458 texUnit->Combine.ModeRGB == GL_DOT3_RGBA) {
459
460 out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate,
461 unit,
462 texUnit->Combine.ModeRGB,
463 texUnit->Combine.SourceRGB,
464 texUnit->Combine.OperandRGB );
465 }
466 else {
467 /* Need to do something to stop from re-emitting identical
468 * argument calculations here:
469 */
470 out = emit_combine( p, dest, A0_DEST_CHANNEL_XYZ, saturate,
471 unit,
472 texUnit->Combine.ModeRGB,
473 texUnit->Combine.SourceRGB,
474 texUnit->Combine.OperandRGB );
475 out = emit_combine( p, dest, A0_DEST_CHANNEL_W, saturate,
476 unit,
477 texUnit->Combine.ModeA,
478 texUnit->Combine.SourceA,
479 texUnit->Combine.OperandA );
480 }
481
482 /* Deal with the final shift:
483 */
484 if (alpha_shift || rgb_shift) {
485 if (rgb_shift == alpha_shift) {
486 shift = i915_emit_const1f(p, 1<<rgb_shift);
487 shift = swizzle(shift,X,X,X,X);
488 }
489 else {
490 shift = i915_emit_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
491 shift = swizzle(shift,X,X,X,Y);
492 }
493 return i915_emit_arith( p, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
494 saturate, out, shift, 0 );
495 }
496
497 return out;
498 }
499
500 default:
501 return get_source(p, GL_PREVIOUS, 0);
502 }
503 }
504
505 static void emit_program_fini( struct i915_fragment_program *p )
506 {
507 int cf = get_source( p, GL_PREVIOUS, 0 );
508 int out = UREG( REG_TYPE_OC, 0 );
509
510 if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
511 /* Emit specular add.
512 */
513 GLuint s = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_ALL);
514 i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, 0, cf,
515 swizzle(s, X,Y,Z,ZERO), 0 );
516 }
517 else if (cf != out) {
518 /* Will wind up in here if no texture enabled or a couple of
519 * other scenarios (GL_REPLACE for instance).
520 */
521 i915_emit_arith( p, A0_MOV, out, A0_DEST_CHANNEL_ALL, 0, cf, 0, 0 );
522 }
523 }
524
525
526 static void i915EmitTextureProgram( i915ContextPtr i915 )
527 {
528 GLcontext *ctx = &i915->intel.ctx;
529 struct i915_fragment_program *p = &i915->tex_program;
530 GLuint unit;
531
532 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
533
534 i915_init_program( i915, p );
535
536 if (ctx->Texture._EnabledUnits) {
537 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
538 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
539 p->last_tex_stage = unit;
540 }
541
542 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++)
543 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
544 p->src_previous = emit_texenv( p, unit );
545 p->src_texture = UREG_BAD;
546 p->temp_flag = 0xffff000;
547 p->temp_flag |= 1 << GET_UREG_NR(p->src_previous);
548 }
549 }
550
551 emit_program_fini( p );
552
553 i915_fini_program( p );
554 i915_upload_program( i915, p );
555
556 p->translated = 1;
557 }
558
559
560 void i915ValidateTextureProgram( i915ContextPtr i915 )
561 {
562 intelContextPtr intel = &i915->intel;
563 GLcontext *ctx = &intel->ctx;
564 TNLcontext *tnl = TNL_CONTEXT(ctx);
565 struct vertex_buffer *VB = &tnl->vb;
566 GLuint index = tnl->render_inputs;
567 int i, offset;
568 GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
569 GLuint s2 = S2_TEXCOORD_NONE;
570
571 /* Important:
572 */
573 VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
574 intel->vertex_attr_count = 0;
575 intel->coloroffset = 0;
576 intel->specoffset = 0;
577 offset = 0;
578
579 if (i915->vertex_fog == I915_FOG_PIXEL) {
580 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
581 index &= ~_TNL_BIT_FOG;
582 }
583 else if (index & _TNL_BITS_TEX_ANY) {
584 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 );
585 }
586 else {
587 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12 );
588 }
589
590 /* How undefined is undefined? */
591 if (index & _TNL_BIT_POINTSIZE) {
592 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4 );
593 }
594
595 intel->coloroffset = offset / 4;
596 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4 );
597
598 if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
599 if (index & _TNL_BIT_COLOR1) {
600 intel->specoffset = offset / 4;
601 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3 );
602 } else
603 EMIT_PAD( 3 );
604
605 if (index & _TNL_BIT_FOG)
606 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1 );
607 else
608 EMIT_PAD( 1 );
609 }
610
611 if (index & _TNL_BITS_TEX_ANY) {
612 for (i = 0; i < 8; i++) {
613 if (index & _TNL_BIT_TEX(i)) {
614 int sz = VB->TexCoordPtr[i]->size;
615
616 s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
617 s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
618
619 EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0, sz * 4 );
620 }
621 }
622 }
623
624 /* Only need to change the vertex emit code if there has been a
625 * statechange to a new hardware vertex format:
626 */
627 if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
628 s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
629
630 I915_STATECHANGE( i915, I915_UPLOAD_CTX );
631
632 i915->tex_program.translated = 0;
633
634 /* Must do this *after* statechange, so as not to affect
635 * buffered vertices reliant on the old state:
636 */
637 intel->vertex_size = _tnl_install_attrs( ctx,
638 intel->vertex_attrs,
639 intel->vertex_attr_count,
640 intel->ViewportMatrix.m, 0 );
641
642 intel->vertex_size >>= 2;
643
644 i915->state.Ctx[I915_CTXREG_LIS2] = s2;
645 i915->state.Ctx[I915_CTXREG_LIS4] = s4;
646
647 assert(intel->vtbl.check_vertex_size( intel, intel->vertex_size ));
648 }
649
650 if (!i915->tex_program.translated ||
651 i915->last_ReallyEnabled != ctx->Texture._EnabledUnits) {
652 i915EmitTextureProgram( i915 );
653 i915->last_ReallyEnabled = ctx->Texture._EnabledUnits;
654 }
655 }