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