Minor r200 vertex program cleanups. Remove disabled leftovers from r300 vertex progra...
[mesa.git] / src / mesa / drivers / dri / i810 / i810texstate.c
1 /*
2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25 #include "glheader.h"
26 #include "macros.h"
27 #include "mtypes.h"
28 #include "texformat.h"
29 #include "simple_list.h"
30 #include "enums.h"
31
32 #include "mm.h"
33
34 #include "i810screen.h"
35 #include "i810_dri.h"
36
37 #include "i810context.h"
38 #include "i810tex.h"
39 #include "i810state.h"
40 #include "i810ioctl.h"
41
42
43
44
45 static void i810SetTexImages( i810ContextPtr imesa,
46 struct gl_texture_object *tObj )
47 {
48 GLuint height, width, pitch, i, textureFormat, log_pitch;
49 i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
50 const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
51 GLint numLevels;
52 GLint log2Width, log2Height;
53
54 /* fprintf(stderr, "%s\n", __FUNCTION__); */
55
56 t->texelBytes = 2;
57 switch (baseImage->TexFormat->MesaFormat) {
58 case MESA_FORMAT_ARGB1555:
59 textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB1555;
60 break;
61 case MESA_FORMAT_ARGB4444:
62 textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
63 break;
64 case MESA_FORMAT_RGB565:
65 textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
66 break;
67 case MESA_FORMAT_AL88:
68 textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_AY88;
69 break;
70 case MESA_FORMAT_YCBCR:
71 textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y
72 | MI1_COLOR_CONV_ENABLE;
73 break;
74 case MESA_FORMAT_YCBCR_REV:
75 textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB
76 | MI1_COLOR_CONV_ENABLE;
77 break;
78 case MESA_FORMAT_CI8:
79 textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
80 t->texelBytes = 1;
81 break;
82
83 default:
84 fprintf(stderr, "i810SetTexImages: bad image->Format\n" );
85 return;
86 }
87
88 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
89
90 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
91
92 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
93 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
94
95 /* Figure out the amount of memory required to hold all the mipmap
96 * levels. Choose the smallest pitch to accomodate the largest
97 * mipmap:
98 */
99 width = tObj->Image[0][t->base.firstLevel]->Width * t->texelBytes;
100 for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
101 log_pitch++;
102
103 /* All images must be loaded at this pitch. Count the number of
104 * lines required:
105 */
106 for ( height = i = 0 ; i < numLevels ; i++ ) {
107 t->image[i].image = tObj->Image[0][t->base.firstLevel + i];
108 t->image[i].offset = height * pitch;
109 t->image[i].internalFormat = baseImage->_BaseFormat;
110 height += t->image[i].image->Height;
111 }
112
113 t->Pitch = pitch;
114 t->base.totalSize = height*pitch;
115 t->max_level = i-1;
116 t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;
117 t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch);
118 t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
119 MLL_MAP_0 |
120 MLL_UPDATE_MAX_MIP |
121 MLL_UPDATE_MIN_MIP |
122 ((numLevels - 1) << MLL_MIN_MIP_SHIFT));
123
124 LOCK_HARDWARE( imesa );
125 i810UploadTexImagesLocked( imesa, t );
126 UNLOCK_HARDWARE( imesa );
127 }
128
129 /* ================================================================
130 * Texture combine functions
131 */
132
133
134 static void set_color_stage( unsigned color, int stage,
135 i810ContextPtr imesa )
136 {
137 if ( color != imesa->Setup[I810_CTXREG_MC0 + stage] ) {
138 I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
139 imesa->Setup[I810_CTXREG_MC0 + stage] = color;
140 }
141 }
142
143
144 static void set_alpha_stage( unsigned alpha, int stage,
145 i810ContextPtr imesa )
146 {
147 if ( alpha != imesa->Setup[I810_CTXREG_MA0 + stage] ) {
148 I810_STATECHANGE( imesa, I810_UPLOAD_CTX );
149 imesa->Setup[I810_CTXREG_MA0 + stage] = alpha;
150 }
151 }
152
153
154 static const unsigned operand_modifiers[] = {
155 0, MC_ARG_INVERT,
156 MC_ARG_REPLICATE_ALPHA, MC_ARG_INVERT | MC_ARG_REPLICATE_ALPHA
157 };
158
159 /**
160 * Configure the hardware bits for the specified texture environment.
161 *
162 * Configures the hardware bits for the texture environment state for the
163 * specified texture unit. As combine stages are added, the values pointed
164 * to by \c color_stage and \c alpha_stage are incremented.
165 *
166 * \param ctx GL context pointer.
167 * \param unit Texture unit to be added.
168 * \param color_stage Next available hardware color combine stage.
169 * \param alpha_stage Next available hardware alpha combine stage.
170 *
171 * \returns
172 * If the combine mode for the specified texture unit could be added without
173 * requiring a software fallback, \c GL_TRUE is returned. Otherwise,
174 * \c GL_FALSE is returned.
175 *
176 * \todo
177 * If the mode is (GL_REPLACE, GL_PREVIOUS), treat it as though the texture
178 * stage is disabled. That is, don't emit any combine stages.
179 *
180 * \todo
181 * Add support for ATI_texture_env_combine3 modes. This will require using
182 * two combine stages.
183 *
184 * \todo
185 * Add support for the missing \c GL_INTERPOLATE modes. This will require
186 * using all three combine stages. There is a comment in the function
187 * describing how this might work.
188 *
189 * \todo
190 * If, after all the combine stages have been emitted, a texture is never
191 * actually used, disable the texture unit. That should save texture some
192 * memory bandwidth. This won't happen in this function, but this seems like
193 * a reasonable place to make note of it.
194 */
195 static GLboolean
196 i810UpdateTexEnvCombine( GLcontext *ctx, GLuint unit,
197 int * color_stage, int * alpha_stage )
198 {
199 i810ContextPtr imesa = I810_CONTEXT(ctx);
200 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
201 GLuint color_arg[3] = {
202 MC_ARG_ONE, MC_ARG_ONE, MC_ARG_ONE
203 };
204 GLuint alpha_arg[3] = {
205 MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA
206 };
207 GLuint i;
208 GLuint color_combine, alpha_combine;
209 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
210 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
211 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
212 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
213
214
215 if ( !texUnit->_ReallyEnabled ) {
216 return GL_TRUE;
217 }
218
219
220 if ((*color_stage >= 3) || (*alpha_stage >= 3)) {
221 return GL_FALSE;
222 }
223
224
225 /* Step 1:
226 * Extract the color and alpha combine function arguments.
227 */
228
229 for ( i = 0 ; i < numColorArgs ; i++ ) {
230 unsigned op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
231 assert(op >= 0);
232 assert(op <= 3);
233 switch ( texUnit->_CurrentCombine->SourceRGB[i] ) {
234 case GL_TEXTURE0:
235 color_arg[i] = MC_ARG_TEX0_COLOR;
236 break;
237 case GL_TEXTURE1:
238 color_arg[i] = MC_ARG_TEX1_COLOR;
239 break;
240 case GL_TEXTURE:
241 color_arg[i] = (unit == 0)
242 ? MC_ARG_TEX0_COLOR : MC_ARG_TEX1_COLOR;
243 break;
244 case GL_CONSTANT:
245 color_arg[i] = MC_ARG_COLOR_FACTOR;
246 break;
247 case GL_PRIMARY_COLOR:
248 color_arg[i] = MC_ARG_ITERATED_COLOR;
249 break;
250 case GL_PREVIOUS:
251 color_arg[i] = (unit == 0)
252 ? MC_ARG_ITERATED_COLOR : MC_ARG_CURRENT_COLOR;
253 break;
254 case GL_ZERO:
255 /* Toggle the low bit of the op value. The is the 'invert' bit,
256 * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op.
257 */
258 op ^= 1;
259
260 /*FALLTHROUGH*/
261
262 case GL_ONE:
263 color_arg[i] = MC_ARG_ONE;
264 break;
265 default:
266 return GL_FALSE;
267 }
268
269 color_arg[i] |= operand_modifiers[op];
270 }
271
272
273 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
274 unsigned op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
275 assert(op >= 0);
276 assert(op <= 1);
277 switch ( texUnit->_CurrentCombine->SourceA[i] ) {
278 case GL_TEXTURE0:
279 alpha_arg[i] = MA_ARG_TEX0_ALPHA;
280 break;
281 case GL_TEXTURE1:
282 alpha_arg[i] = MA_ARG_TEX1_ALPHA;
283 break;
284 case GL_TEXTURE:
285 alpha_arg[i] = (unit == 0)
286 ? MA_ARG_TEX0_ALPHA : MA_ARG_TEX1_ALPHA;
287 break;
288 case GL_CONSTANT:
289 alpha_arg[i] = MA_ARG_ALPHA_FACTOR;
290 break;
291 case GL_PRIMARY_COLOR:
292 alpha_arg[i] = MA_ARG_ITERATED_ALPHA;
293 break;
294 case GL_PREVIOUS:
295 alpha_arg[i] = (unit == 0)
296 ? MA_ARG_ITERATED_ALPHA : MA_ARG_CURRENT_ALPHA;
297 break;
298 case GL_ZERO:
299 /* Toggle the low bit of the op value. The is the 'invert' bit,
300 * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op.
301 */
302 op ^= 1;
303
304 /*FALLTHROUGH*/
305
306 case GL_ONE:
307 if (i != 2) {
308 return GL_FALSE;
309 }
310
311 alpha_arg[i] = MA_ARG_ONE;
312 break;
313 default:
314 return GL_FALSE;
315 }
316
317 alpha_arg[i] |= operand_modifiers[op];
318 }
319
320
321 /* Step 2:
322 * Build up the color and alpha combine functions.
323 */
324 switch ( texUnit->_CurrentCombine->ModeRGB ) {
325 case GL_REPLACE:
326 color_combine = MC_OP_ARG1;
327 break;
328 case GL_MODULATE:
329 color_combine = MC_OP_MODULATE + RGBshift;
330 RGBshift = 0;
331 break;
332 case GL_ADD:
333 color_combine = MC_OP_ADD;
334 break;
335 case GL_ADD_SIGNED:
336 color_combine = MC_OP_ADD_SIGNED;
337 break;
338 case GL_SUBTRACT:
339 color_combine = MC_OP_SUBTRACT;
340 break;
341 case GL_INTERPOLATE:
342 /* For interpolation, the i810 hardware has some limitations. It
343 * can't handle using the secondary or diffuse color (diffuse alpha
344 * is okay) for the third argument.
345 *
346 * It is possible to emulate the missing modes by using multiple
347 * combine stages. Unfortunately it requires all three stages to
348 * emulate a single interpolate stage. The (arg0*arg2) portion is
349 * done in stage zero and writes to MC_DEST_ACCUMULATOR. The
350 * (arg1*(1-arg2)) portion is done in stage 1, and the final stage is
351 * (MC_ARG1_ACCUMULATOR | MC_ARG2_CURRENT_COLOR | MC_OP_ADD).
352 *
353 * It can also be done without using the accumulator by rearranging
354 * the equation as (arg1 + (arg2 * (arg0 - arg1))). Too bad the i810
355 * doesn't support the MODULATE_AND_ADD mode that the i830 supports.
356 * If it did, the interpolate could be done in only two stages.
357 */
358
359 if ( (color_arg[2] & MC_ARG_INVERT) != 0 ) {
360 unsigned temp = color_arg[0];
361
362 color_arg[0] = color_arg[1];
363 color_arg[1] = temp;
364 color_arg[2] &= ~MC_ARG_INVERT;
365 }
366
367 switch (color_arg[2]) {
368 case (MC_ARG_ONE):
369 case (MC_ARG_ONE | MC_ARG_REPLICATE_ALPHA):
370 color_combine = MC_OP_ARG1;
371 color_arg[1] = MC_ARG_ONE;
372 break;
373
374 case (MC_ARG_COLOR_FACTOR):
375 return GL_FALSE;
376
377 case (MC_ARG_COLOR_FACTOR | MC_ARG_REPLICATE_ALPHA):
378 color_combine = MC_OP_LIN_BLEND_ALPHA_FACTOR;
379 break;
380
381 case (MC_ARG_ITERATED_COLOR):
382 return GL_FALSE;
383
384 case (MC_ARG_ITERATED_COLOR | MC_ARG_REPLICATE_ALPHA):
385 color_combine = MC_OP_LIN_BLEND_ITER_ALPHA;
386 break;
387
388 case (MC_ARG_SPECULAR_COLOR):
389 case (MC_ARG_SPECULAR_COLOR | MC_ARG_REPLICATE_ALPHA):
390 return GL_FALSE;
391
392 case (MC_ARG_TEX0_COLOR):
393 color_combine = MC_OP_LIN_BLEND_TEX0_COLOR;
394 break;
395
396 case (MC_ARG_TEX0_COLOR | MC_ARG_REPLICATE_ALPHA):
397 color_combine = MC_OP_LIN_BLEND_TEX0_ALPHA;
398 break;
399
400 case (MC_ARG_TEX1_COLOR):
401 color_combine = MC_OP_LIN_BLEND_TEX1_COLOR;
402 break;
403
404 case (MC_ARG_TEX1_COLOR | MC_ARG_REPLICATE_ALPHA):
405 color_combine = MC_OP_LIN_BLEND_TEX1_ALPHA;
406 break;
407
408 default:
409 return GL_FALSE;
410 }
411 break;
412
413 default:
414 return GL_FALSE;
415 }
416
417
418 switch ( texUnit->_CurrentCombine->ModeA ) {
419 case GL_REPLACE:
420 alpha_combine = MA_OP_ARG1;
421 break;
422 case GL_MODULATE:
423 alpha_combine = MA_OP_MODULATE + Ashift;
424 Ashift = 0;
425 break;
426 case GL_ADD:
427 alpha_combine = MA_OP_ADD;
428 break;
429 case GL_ADD_SIGNED:
430 alpha_combine = MA_OP_ADD_SIGNED;
431 break;
432 case GL_SUBTRACT:
433 alpha_combine = MA_OP_SUBTRACT;
434 break;
435 case GL_INTERPOLATE:
436 if ( (alpha_arg[2] & MA_ARG_INVERT) != 0 ) {
437 unsigned temp = alpha_arg[0];
438
439 alpha_arg[0] = alpha_arg[1];
440 alpha_arg[1] = temp;
441 alpha_arg[2] &= ~MA_ARG_INVERT;
442 }
443
444 switch (alpha_arg[2]) {
445 case MA_ARG_ONE:
446 alpha_combine = MA_OP_ARG1;
447 alpha_arg[1] = MA_ARG_ITERATED_ALPHA;
448 break;
449
450 case MA_ARG_ALPHA_FACTOR:
451 alpha_combine = MA_OP_LIN_BLEND_ALPHA_FACTOR;
452 break;
453
454 case MA_ARG_ITERATED_ALPHA:
455 alpha_combine = MA_OP_LIN_BLEND_ITER_ALPHA;
456 break;
457
458 case MA_ARG_TEX0_ALPHA:
459 alpha_combine = MA_OP_LIN_BLEND_TEX0_ALPHA;
460 break;
461
462 case MA_ARG_TEX1_ALPHA:
463 alpha_combine = MA_OP_LIN_BLEND_TEX1_ALPHA;
464 break;
465
466 default:
467 return GL_FALSE;
468 }
469 break;
470
471 default:
472 return GL_FALSE;
473 }
474
475
476 color_combine |= GFX_OP_MAP_COLOR_STAGES | (*color_stage << MC_STAGE_SHIFT)
477 | MC_UPDATE_DEST | MC_DEST_CURRENT
478 | MC_UPDATE_ARG1 | (color_arg[0] << MC_ARG1_SHIFT)
479 | MC_UPDATE_ARG2 | (color_arg[1] << MC_ARG2_SHIFT)
480 | MC_UPDATE_OP;
481
482 alpha_combine |= GFX_OP_MAP_ALPHA_STAGES | (*alpha_stage << MA_STAGE_SHIFT)
483 | MA_UPDATE_ARG1 | (alpha_arg[0] << MA_ARG1_SHIFT)
484 | MA_UPDATE_ARG2 | (alpha_arg[1] << MA_ARG2_SHIFT)
485 | MA_UPDATE_OP;
486
487 set_color_stage( color_combine, *color_stage, imesa );
488 set_alpha_stage( alpha_combine, *alpha_stage, imesa );
489 (*color_stage)++;
490 (*alpha_stage)++;
491
492
493 /* Step 3:
494 * Apply the scale factor.
495 */
496 /* The only operation where the i810 directly supports adding a post-
497 * scale factor is modulate. For all the other modes the post-scale is
498 * emulated by inserting and extra modulate stage. For the modulate
499 * case, the scaling is handled above when color_combine / alpha_combine
500 * are initially set.
501 */
502
503 if ( RGBshift != 0 ) {
504 const unsigned color_scale = GFX_OP_MAP_COLOR_STAGES
505 | (*color_stage << MC_STAGE_SHIFT)
506 | MC_UPDATE_DEST | MC_DEST_CURRENT
507 | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT)
508 | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
509 | MC_UPDATE_OP | (MC_OP_MODULATE + RGBshift);
510
511 if ( *color_stage >= 3 ) {
512 return GL_FALSE;
513 }
514
515 set_color_stage( color_scale, *color_stage, imesa );
516 (*color_stage)++;
517 }
518
519
520 if ( Ashift != 0 ) {
521 const unsigned alpha_scale = GFX_OP_MAP_ALPHA_STAGES
522 | (*alpha_stage << MA_STAGE_SHIFT)
523 | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
524 | MA_UPDATE_ARG2 | (MA_ARG_ONE << MA_ARG2_SHIFT)
525 | MA_UPDATE_OP | (MA_OP_MODULATE + Ashift);
526
527 if ( *alpha_stage >= 3 ) {
528 return GL_FALSE;
529 }
530
531 set_alpha_stage( alpha_scale, *alpha_stage, imesa );
532 (*alpha_stage)++;
533 }
534
535 return GL_TRUE;
536 }
537
538 static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
539 {
540 i810ContextPtr imesa = I810_CONTEXT(ctx);
541 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
542 struct gl_texture_object *tObj = texUnit->_Current;
543 i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
544
545 if (tObj->Image[0][tObj->BaseLevel]->Border > 0) {
546 return GL_FALSE;
547 }
548
549 /* Upload teximages (not pipelined)
550 */
551 if (t->base.dirty_images[0]) {
552 I810_FIREVERTICES(imesa);
553 i810SetTexImages( imesa, tObj );
554 if (!t->base.memBlock) {
555 return GL_FALSE;
556 }
557 }
558
559 /* Update state if this is a different texture object to last
560 * time.
561 */
562 if (imesa->CurrentTexObj[unit] != t) {
563 I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
564 imesa->CurrentTexObj[unit] = t;
565 t->base.bound |= (1U << unit);
566
567 /* XXX: should be locked */
568 driUpdateTextureLRU( (driTextureObject *) t );
569 }
570
571 imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
572 return GL_TRUE;
573 }
574
575 static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
576 {
577 i810ContextPtr imesa = I810_CONTEXT(ctx);
578 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
579 struct gl_texture_object *tObj = texUnit->_Current;
580 i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
581 GLint Width, Height;
582
583 Width = tObj->Image[0][t->base.firstLevel]->Width - 1;
584 Height = tObj->Image[0][t->base.firstLevel]->Height - 1;
585
586 I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
587 t->Setup[I810_TEXREG_MCS] &= ~MCS_NORMALIZED_COORDS;
588 t->Setup[I810_TEXREG_MCS] |= MCS_UPDATE_NORMALIZED;
589 t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_EXACT |
590 (Height << MI2_HEIGHT_SHIFT) | Width);
591
592 return GL_TRUE;
593 }
594
595 static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
596 {
597 i810ContextPtr imesa = I810_CONTEXT(ctx);
598 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
599 struct gl_texture_object *tObj = texUnit->_Current;
600 i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
601 GLint log2Width, log2Height;
602
603
604 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
605 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
606
607 I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<<unit));
608 t->Setup[I810_TEXREG_MCS] |= MCS_NORMALIZED_COORDS | MCS_UPDATE_NORMALIZED;
609 t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 |
610 (log2Height << MI2_HEIGHT_SHIFT) | log2Width);
611
612 return GL_TRUE;
613 }
614
615 static void disable_tex( GLcontext *ctx, GLuint unit )
616 {
617 i810ContextPtr imesa = I810_CONTEXT(ctx);
618
619 imesa->CurrentTexObj[unit] = 0;
620 imesa->TexEnvImageFmt[unit] = 0;
621 imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit);
622
623 }
624
625 /**
626 * Update hardware state for a texture unit.
627 *
628 * \todo
629 * 1D textures should be supported! Just use a 2D texture with the second
630 * texture coordinate value fixed at 0.0.
631 */
632 static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit,
633 int * next_color_stage, int * next_alpha_stage )
634 {
635 i810ContextPtr imesa = I810_CONTEXT(ctx);
636 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
637 GLboolean ret;
638
639 switch(texUnit->_ReallyEnabled) {
640 case TEXTURE_2D_BIT:
641 ret = enable_tex_common( ctx, unit);
642 ret &= enable_tex_2d(ctx, unit);
643 if (ret == GL_FALSE) {
644 FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
645 }
646 break;
647 case TEXTURE_RECT_BIT:
648 ret = enable_tex_common( ctx, unit);
649 ret &= enable_tex_rect(ctx, unit);
650 if (ret == GL_FALSE) {
651 FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
652 }
653 break;
654 case 0:
655 disable_tex(ctx, unit);
656 break;
657 }
658
659
660 if (!i810UpdateTexEnvCombine( ctx, unit,
661 next_color_stage, next_alpha_stage )) {
662 FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );
663 }
664
665 return;
666 }
667
668
669 void i810UpdateTextureState( GLcontext *ctx )
670 {
671 static const unsigned color_pass[3] = {
672 GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | MC_DEST_CURRENT
673 | MC_UPDATE_ARG1 | (MC_ARG_ITERATED_COLOR << MC_ARG1_SHIFT)
674 | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
675 | MC_UPDATE_OP | MC_OP_ARG1,
676 GFX_OP_MAP_COLOR_STAGES | MC_STAGE_1 | MC_UPDATE_DEST | MC_DEST_CURRENT
677 | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT)
678 | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
679 | MC_UPDATE_OP | MC_OP_ARG1,
680 GFX_OP_MAP_COLOR_STAGES | MC_STAGE_2 | MC_UPDATE_DEST | MC_DEST_CURRENT
681 | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT)
682 | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
683 | MC_UPDATE_OP | MC_OP_ARG1
684 };
685 static const unsigned alpha_pass[3] = {
686 GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0
687 | MA_UPDATE_ARG1 | (MA_ARG_ITERATED_ALPHA << MA_ARG1_SHIFT)
688 | MA_UPDATE_ARG2 | (MA_ARG_ITERATED_ALPHA << MA_ARG2_SHIFT)
689 | MA_UPDATE_OP | MA_OP_ARG1,
690 GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_1
691 | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
692 | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT)
693 | MA_UPDATE_OP | MA_OP_ARG1,
694 GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_2
695 | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
696 | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT)
697 | MA_UPDATE_OP | MA_OP_ARG1
698 };
699 i810ContextPtr imesa = I810_CONTEXT(ctx);
700 int next_color_stage = 0;
701 int next_alpha_stage = 0;
702
703
704 /* fprintf(stderr, "%s\n", __FUNCTION__); */
705 FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_FALSE );
706
707 i810UpdateTexUnit( ctx, 0, & next_color_stage, & next_alpha_stage );
708 i810UpdateTexUnit( ctx, 1, & next_color_stage, & next_alpha_stage );
709
710 /* There needs to be at least one combine stage emitted that just moves
711 * the incoming primary color to the current color register. In addition,
712 * there number be the same number of color and alpha stages emitted.
713 * Finally, if there are less than 3 combine stages, a MC_OP_DISABLE stage
714 * must be emitted.
715 */
716
717 while ( (next_color_stage == 0) ||
718 (next_color_stage < next_alpha_stage) ) {
719 set_color_stage( color_pass[ next_color_stage ], next_color_stage,
720 imesa );
721 next_color_stage++;
722 }
723
724 assert( next_color_stage <= 3 );
725
726 while ( next_alpha_stage < next_color_stage ) {
727 set_alpha_stage( alpha_pass[ next_alpha_stage ], next_alpha_stage,
728 imesa );
729 next_alpha_stage++;
730 }
731
732 assert( next_alpha_stage <= 3 );
733 assert( next_color_stage == next_alpha_stage );
734
735 if ( next_color_stage < 3 ) {
736 const unsigned color = GFX_OP_MAP_COLOR_STAGES
737 | (next_color_stage << MC_STAGE_SHIFT)
738 | MC_UPDATE_DEST | MC_DEST_CURRENT
739 | MC_UPDATE_ARG1 | (MC_ARG_ONE << MC_ARG1_SHIFT)
740 | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT)
741 | MC_UPDATE_OP | (MC_OP_DISABLE);
742
743 const unsigned alpha = GFX_OP_MAP_ALPHA_STAGES
744 | (next_color_stage << MC_STAGE_SHIFT)
745 | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT)
746 | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT)
747 | MA_UPDATE_OP | (MA_OP_ARG1);
748
749 set_color_stage( color, next_color_stage, imesa );
750 set_alpha_stage( alpha, next_alpha_stage, imesa );
751 }
752 }