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