patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Kevin E. Martin <martin@valinux.com>
34 * Gareth Hughes <gareth@valinux.com>
35 */
36
37 #include "glheader.h"
38 #include "imports.h"
39 #include "colormac.h"
40 #include "context.h"
41 #include "macros.h"
42 #include "texformat.h"
43 #include "enums.h"
44
45 #include "radeon_context.h"
46 #include "radeon_state.h"
47 #include "radeon_ioctl.h"
48 #include "radeon_swtcl.h"
49 #include "radeon_tex.h"
50 #include "radeon_tcl.h"
51
52
53 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
54 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
55 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
56
57 #define _COLOR(f) \
58 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
59 #define _ALPHA(f) \
60 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
61 #define _YUV(f) \
62 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
63 #define _INVALID(f) \
64 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
65 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
66 && (tx_table[f].format != 0xffffffff) )
67
68 static const struct {
69 GLuint format, filter;
70 }
71 tx_table[] =
72 {
73 _ALPHA(RGBA8888),
74 _ALPHA(ARGB8888),
75 _INVALID(RGB888),
76 _COLOR(RGB565),
77 _ALPHA(ARGB4444),
78 _ALPHA(ARGB1555),
79 _ALPHA(AL88),
80 _INVALID(A8),
81 _INVALID(L8),
82 _COLOR(I8),
83 _INVALID(CI8),
84 _YUV(YCBCR),
85 _YUV(YCBCR_REV),
86 };
87
88 #undef _COLOR
89 #undef _ALPHA
90 #undef _INVALID
91
92 /**
93 * This function computes the number of bytes of storage needed for
94 * the given texture object (all mipmap levels, all cube faces).
95 * The \c image[face][level].x/y/width/height parameters for upload/blitting
96 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
97 * too.
98 *
99 * \param rmesa Context pointer
100 * \param tObj GL texture object whose images are to be posted to
101 * hardware state.
102 */
103 static void radeonSetTexImages( radeonContextPtr rmesa,
104 struct gl_texture_object *tObj )
105 {
106 radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
107 const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
108 GLint curOffset;
109 GLint i;
110 GLint firstLevel=0, lastLevel=0, numLevels;
111 GLint log2Width, log2Height, log2Depth;
112
113 /* Set the hardware texture format
114 */
115
116 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
117 RADEON_TXFORMAT_ALPHA_IN_MAP);
118 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
119
120 if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
121 t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
122 t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
123 }
124 else {
125 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
126 return;
127 }
128
129
130
131 /* Compute which mipmap levels we really want to send to the hardware.
132 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
133 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
134 * Yes, this looks overly complicated, but it's all needed.
135 */
136 switch (tObj->Target) {
137 case GL_TEXTURE_1D:
138 case GL_TEXTURE_2D:
139 firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
140 firstLevel = MAX2(firstLevel, tObj->BaseLevel);
141 lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
142 lastLevel = MAX2(lastLevel, tObj->BaseLevel);
143 lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
144 lastLevel = MIN2(lastLevel, tObj->MaxLevel);
145 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
146 log2Width = tObj->Image[firstLevel]->WidthLog2;
147 log2Height = tObj->Image[firstLevel]->HeightLog2;
148 log2Depth = 0;
149 break;
150 case GL_TEXTURE_RECTANGLE_NV:
151 firstLevel = lastLevel = 0;
152 log2Width = log2Height = 1; /* ? */
153 log2Depth = 0;
154 break;
155 default:
156 return;
157 }
158
159 /* save these values */
160 t->base.firstLevel = firstLevel;
161 t->base.lastLevel = lastLevel;
162
163 numLevels = lastLevel - firstLevel + 1;
164
165 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
166
167 /* Calculate mipmap offsets and dimensions for blitting (uploading)
168 * The idea is that we lay out the mipmap levels within a block of
169 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
170 */
171 curOffset = 0;
172
173 for (i = 0; i < numLevels; i++) {
174 const struct gl_texture_image *texImage;
175 GLuint size;
176
177 texImage = tObj->Image[i + firstLevel];
178 if ( !texImage )
179 break;
180
181 /* find image size in bytes */
182 if (texImage->IsCompressed) {
183 size = texImage->CompressedSize;
184 }
185 else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
186 size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63)
187 & ~63) * texImage->Height;
188 }
189 else {
190 int w = texImage->Width * texImage->TexFormat->TexelBytes;
191 if (w < 32)
192 w = 32;
193 size = w * texImage->Height * texImage->Depth;
194 }
195 assert(size > 0);
196
197 if (curOffset & 0x1f) {
198 /* align to 32-byte offset */
199 curOffset = (curOffset + 0x1f) & ~0x1f;
200 }
201
202 t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
203 t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
204 t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES);
205 t->image[0][i].height = size / t->image[0][i].width;
206
207 #if 0
208 /* for debugging only and only applicable to non-rectangle targets */
209 assert(size % t->image[0][i].width == 0);
210 assert(t->image[0][i].x == 0
211 || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1));
212 #endif
213
214 if (0)
215 fprintf(stderr,
216 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
217 i, texImage->Width, texImage->Height,
218 t->image[0][i].x, t->image[0][i].y,
219 t->image[0][i].width, t->image[0][i].height, size, curOffset);
220
221 curOffset += size;
222
223 }
224
225 /* Align the total size of texture memory block.
226 */
227 t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
228
229 /* Hardware state:
230 */
231 t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
232 t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT;
233
234 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
235 RADEON_TXFORMAT_HEIGHT_MASK |
236 RADEON_TXFORMAT_CUBIC_MAP_ENABLE);
237 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
238 (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
239
240 t->pp_txsize = (((tObj->Image[firstLevel]->Width - 1) << 0) |
241 ((tObj->Image[firstLevel]->Height - 1) << 16));
242
243 /* Only need to round to nearest 32 for textures, but the blitter
244 * requires 64-byte aligned pitches, and we may/may not need the
245 * blitter. NPOT only!
246 */
247 if (baseImage->IsCompressed)
248 t->pp_txpitch = (tObj->Image[firstLevel]->Width + 63) & ~(63);
249 else
250 t->pp_txpitch = ((tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63);
251 t->pp_txpitch -= 32;
252
253 t->dirty_state = TEX_ALL;
254
255 /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
256 }
257
258
259
260 /* ================================================================
261 * Texture combine functions
262 */
263
264 #define RADEON_DISABLE 0
265 #define RADEON_REPLACE 1
266 #define RADEON_MODULATE 2
267 #define RADEON_DECAL 3
268 #define RADEON_BLEND 4
269 #define RADEON_ADD 5
270 #define RADEON_MAX_COMBFUNC 6
271
272 static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
273 {
274 /* Unit 0:
275 */
276 {
277 /* Disable combiner stage
278 */
279 (RADEON_COLOR_ARG_A_ZERO |
280 RADEON_COLOR_ARG_B_ZERO |
281 RADEON_COLOR_ARG_C_CURRENT_COLOR |
282 RADEON_BLEND_CTL_ADD |
283 RADEON_SCALE_1X |
284 RADEON_CLAMP_TX),
285
286 /* GL_REPLACE = 0x00802800
287 */
288 (RADEON_COLOR_ARG_A_ZERO |
289 RADEON_COLOR_ARG_B_ZERO |
290 RADEON_COLOR_ARG_C_T0_COLOR |
291 RADEON_BLEND_CTL_ADD |
292 RADEON_SCALE_1X |
293 RADEON_CLAMP_TX),
294
295 /* GL_MODULATE = 0x00800142
296 */
297 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
298 RADEON_COLOR_ARG_B_T0_COLOR |
299 RADEON_COLOR_ARG_C_ZERO |
300 RADEON_BLEND_CTL_ADD |
301 RADEON_SCALE_1X |
302 RADEON_CLAMP_TX),
303
304 /* GL_DECAL = 0x008c2d42
305 */
306 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
307 RADEON_COLOR_ARG_B_T0_COLOR |
308 RADEON_COLOR_ARG_C_T0_ALPHA |
309 RADEON_BLEND_CTL_BLEND |
310 RADEON_SCALE_1X |
311 RADEON_CLAMP_TX),
312
313 /* GL_BLEND = 0x008c2902
314 */
315 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
316 RADEON_COLOR_ARG_B_TFACTOR_COLOR |
317 RADEON_COLOR_ARG_C_T0_COLOR |
318 RADEON_BLEND_CTL_BLEND |
319 RADEON_SCALE_1X |
320 RADEON_CLAMP_TX),
321
322 /* GL_ADD = 0x00812802
323 */
324 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
325 RADEON_COLOR_ARG_B_ZERO |
326 RADEON_COLOR_ARG_C_T0_COLOR |
327 RADEON_COMP_ARG_B |
328 RADEON_BLEND_CTL_ADD |
329 RADEON_SCALE_1X |
330 RADEON_CLAMP_TX),
331 },
332
333 /* Unit 1:
334 */
335 {
336 /* Disable combiner stage
337 */
338 (RADEON_COLOR_ARG_A_ZERO |
339 RADEON_COLOR_ARG_B_ZERO |
340 RADEON_COLOR_ARG_C_CURRENT_COLOR |
341 RADEON_BLEND_CTL_ADD |
342 RADEON_SCALE_1X |
343 RADEON_CLAMP_TX),
344
345 /* GL_REPLACE = 0x00803000
346 */
347 (RADEON_COLOR_ARG_A_ZERO |
348 RADEON_COLOR_ARG_B_ZERO |
349 RADEON_COLOR_ARG_C_T1_COLOR |
350 RADEON_BLEND_CTL_ADD |
351 RADEON_SCALE_1X |
352 RADEON_CLAMP_TX),
353
354 /* GL_MODULATE = 0x00800182
355 */
356 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
357 RADEON_COLOR_ARG_B_T1_COLOR |
358 RADEON_COLOR_ARG_C_ZERO |
359 RADEON_BLEND_CTL_ADD |
360 RADEON_SCALE_1X |
361 RADEON_CLAMP_TX),
362
363 /* GL_DECAL = 0x008c3582
364 */
365 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
366 RADEON_COLOR_ARG_B_T1_COLOR |
367 RADEON_COLOR_ARG_C_T1_ALPHA |
368 RADEON_BLEND_CTL_BLEND |
369 RADEON_SCALE_1X |
370 RADEON_CLAMP_TX),
371
372 /* GL_BLEND = 0x008c3102
373 */
374 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
375 RADEON_COLOR_ARG_B_TFACTOR_COLOR |
376 RADEON_COLOR_ARG_C_T1_COLOR |
377 RADEON_BLEND_CTL_BLEND |
378 RADEON_SCALE_1X |
379 RADEON_CLAMP_TX),
380
381 /* GL_ADD = 0x00813002
382 */
383 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
384 RADEON_COLOR_ARG_B_ZERO |
385 RADEON_COLOR_ARG_C_T1_COLOR |
386 RADEON_COMP_ARG_B |
387 RADEON_BLEND_CTL_ADD |
388 RADEON_SCALE_1X |
389 RADEON_CLAMP_TX),
390 },
391
392 /* Unit 2:
393 */
394 {
395 /* Disable combiner stage
396 */
397 (RADEON_COLOR_ARG_A_ZERO |
398 RADEON_COLOR_ARG_B_ZERO |
399 RADEON_COLOR_ARG_C_CURRENT_COLOR |
400 RADEON_BLEND_CTL_ADD |
401 RADEON_SCALE_1X |
402 RADEON_CLAMP_TX),
403
404 /* GL_REPLACE = 0x00803800
405 */
406 (RADEON_COLOR_ARG_A_ZERO |
407 RADEON_COLOR_ARG_B_ZERO |
408 RADEON_COLOR_ARG_C_T2_COLOR |
409 RADEON_BLEND_CTL_ADD |
410 RADEON_SCALE_1X |
411 RADEON_CLAMP_TX),
412
413 /* GL_MODULATE = 0x008001c2
414 */
415 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
416 RADEON_COLOR_ARG_B_T2_COLOR |
417 RADEON_COLOR_ARG_C_ZERO |
418 RADEON_BLEND_CTL_ADD |
419 RADEON_SCALE_1X |
420 RADEON_CLAMP_TX),
421
422 /* GL_DECAL = 0x008c3dc2
423 */
424 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
425 RADEON_COLOR_ARG_B_T2_COLOR |
426 RADEON_COLOR_ARG_C_T2_ALPHA |
427 RADEON_BLEND_CTL_BLEND |
428 RADEON_SCALE_1X |
429 RADEON_CLAMP_TX),
430
431 /* GL_BLEND = 0x008c3902
432 */
433 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
434 RADEON_COLOR_ARG_B_TFACTOR_COLOR |
435 RADEON_COLOR_ARG_C_T2_COLOR |
436 RADEON_BLEND_CTL_BLEND |
437 RADEON_SCALE_1X |
438 RADEON_CLAMP_TX),
439
440 /* GL_ADD = 0x00813802
441 */
442 (RADEON_COLOR_ARG_A_CURRENT_COLOR |
443 RADEON_COLOR_ARG_B_ZERO |
444 RADEON_COLOR_ARG_C_T2_COLOR |
445 RADEON_COMP_ARG_B |
446 RADEON_BLEND_CTL_ADD |
447 RADEON_SCALE_1X |
448 RADEON_CLAMP_TX),
449 }
450 };
451
452 static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
453 {
454 /* Unit 0:
455 */
456 {
457 /* Disable combiner stage
458 */
459 (RADEON_ALPHA_ARG_A_ZERO |
460 RADEON_ALPHA_ARG_B_ZERO |
461 RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
462 RADEON_BLEND_CTL_ADD |
463 RADEON_SCALE_1X |
464 RADEON_CLAMP_TX),
465
466 /* GL_REPLACE = 0x00800500
467 */
468 (RADEON_ALPHA_ARG_A_ZERO |
469 RADEON_ALPHA_ARG_B_ZERO |
470 RADEON_ALPHA_ARG_C_T0_ALPHA |
471 RADEON_BLEND_CTL_ADD |
472 RADEON_SCALE_1X |
473 RADEON_CLAMP_TX),
474
475 /* GL_MODULATE = 0x00800051
476 */
477 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
478 RADEON_ALPHA_ARG_B_T0_ALPHA |
479 RADEON_ALPHA_ARG_C_ZERO |
480 RADEON_BLEND_CTL_ADD |
481 RADEON_SCALE_1X |
482 RADEON_CLAMP_TX),
483
484 /* GL_DECAL = 0x00800100
485 */
486 (RADEON_ALPHA_ARG_A_ZERO |
487 RADEON_ALPHA_ARG_B_ZERO |
488 RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
489 RADEON_BLEND_CTL_ADD |
490 RADEON_SCALE_1X |
491 RADEON_CLAMP_TX),
492
493 /* GL_BLEND = 0x00800051
494 */
495 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
496 RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
497 RADEON_ALPHA_ARG_C_T0_ALPHA |
498 RADEON_BLEND_CTL_BLEND |
499 RADEON_SCALE_1X |
500 RADEON_CLAMP_TX),
501
502 /* GL_ADD = 0x00800051
503 */
504 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
505 RADEON_ALPHA_ARG_B_ZERO |
506 RADEON_ALPHA_ARG_C_T0_ALPHA |
507 RADEON_COMP_ARG_B |
508 RADEON_BLEND_CTL_ADD |
509 RADEON_SCALE_1X |
510 RADEON_CLAMP_TX),
511 },
512
513 /* Unit 1:
514 */
515 {
516 /* Disable combiner stage
517 */
518 (RADEON_ALPHA_ARG_A_ZERO |
519 RADEON_ALPHA_ARG_B_ZERO |
520 RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
521 RADEON_BLEND_CTL_ADD |
522 RADEON_SCALE_1X |
523 RADEON_CLAMP_TX),
524
525 /* GL_REPLACE = 0x00800600
526 */
527 (RADEON_ALPHA_ARG_A_ZERO |
528 RADEON_ALPHA_ARG_B_ZERO |
529 RADEON_ALPHA_ARG_C_T1_ALPHA |
530 RADEON_BLEND_CTL_ADD |
531 RADEON_SCALE_1X |
532 RADEON_CLAMP_TX),
533
534 /* GL_MODULATE = 0x00800061
535 */
536 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
537 RADEON_ALPHA_ARG_B_T1_ALPHA |
538 RADEON_ALPHA_ARG_C_ZERO |
539 RADEON_BLEND_CTL_ADD |
540 RADEON_SCALE_1X |
541 RADEON_CLAMP_TX),
542
543 /* GL_DECAL = 0x00800100
544 */
545 (RADEON_ALPHA_ARG_A_ZERO |
546 RADEON_ALPHA_ARG_B_ZERO |
547 RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
548 RADEON_BLEND_CTL_ADD |
549 RADEON_SCALE_1X |
550 RADEON_CLAMP_TX),
551
552 /* GL_BLEND = 0x00800061
553 */
554 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
555 RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
556 RADEON_ALPHA_ARG_C_T1_ALPHA |
557 RADEON_BLEND_CTL_BLEND |
558 RADEON_SCALE_1X |
559 RADEON_CLAMP_TX),
560
561 /* GL_ADD = 0x00800061
562 */
563 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
564 RADEON_ALPHA_ARG_B_ZERO |
565 RADEON_ALPHA_ARG_C_T1_ALPHA |
566 RADEON_COMP_ARG_B |
567 RADEON_BLEND_CTL_ADD |
568 RADEON_SCALE_1X |
569 RADEON_CLAMP_TX),
570 },
571
572 /* Unit 2:
573 */
574 {
575 /* Disable combiner stage
576 */
577 (RADEON_ALPHA_ARG_A_ZERO |
578 RADEON_ALPHA_ARG_B_ZERO |
579 RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
580 RADEON_BLEND_CTL_ADD |
581 RADEON_SCALE_1X |
582 RADEON_CLAMP_TX),
583
584 /* GL_REPLACE = 0x00800700
585 */
586 (RADEON_ALPHA_ARG_A_ZERO |
587 RADEON_ALPHA_ARG_B_ZERO |
588 RADEON_ALPHA_ARG_C_T2_ALPHA |
589 RADEON_BLEND_CTL_ADD |
590 RADEON_SCALE_1X |
591 RADEON_CLAMP_TX),
592
593 /* GL_MODULATE = 0x00800071
594 */
595 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
596 RADEON_ALPHA_ARG_B_T2_ALPHA |
597 RADEON_ALPHA_ARG_C_ZERO |
598 RADEON_BLEND_CTL_ADD |
599 RADEON_SCALE_1X |
600 RADEON_CLAMP_TX),
601
602 /* GL_DECAL = 0x00800100
603 */
604 (RADEON_ALPHA_ARG_A_ZERO |
605 RADEON_ALPHA_ARG_B_ZERO |
606 RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
607 RADEON_BLEND_CTL_ADD |
608 RADEON_SCALE_1X |
609 RADEON_CLAMP_TX),
610
611 /* GL_BLEND = 0x00800071
612 */
613 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
614 RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
615 RADEON_ALPHA_ARG_C_T2_ALPHA |
616 RADEON_BLEND_CTL_BLEND |
617 RADEON_SCALE_1X |
618 RADEON_CLAMP_TX),
619
620 /* GL_ADD = 0x00800021
621 */
622 (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
623 RADEON_ALPHA_ARG_B_ZERO |
624 RADEON_ALPHA_ARG_C_T2_ALPHA |
625 RADEON_COMP_ARG_B |
626 RADEON_BLEND_CTL_ADD |
627 RADEON_SCALE_1X |
628 RADEON_CLAMP_TX),
629 }
630 };
631
632
633 /* GL_ARB_texture_env_combine support
634 */
635
636 /* The color tables have combine functions for GL_SRC_COLOR,
637 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
638 */
639 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
640 {
641 {
642 RADEON_COLOR_ARG_A_T0_COLOR,
643 RADEON_COLOR_ARG_A_T1_COLOR,
644 RADEON_COLOR_ARG_A_T2_COLOR
645 },
646 {
647 RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
648 RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
649 RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
650 },
651 {
652 RADEON_COLOR_ARG_A_T0_ALPHA,
653 RADEON_COLOR_ARG_A_T1_ALPHA,
654 RADEON_COLOR_ARG_A_T2_ALPHA
655 },
656 {
657 RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
658 RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
659 RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
660 },
661 };
662
663 static GLuint radeon_tfactor_color[] =
664 {
665 RADEON_COLOR_ARG_A_TFACTOR_COLOR,
666 RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
667 RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
668 RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
669 };
670
671 static GLuint radeon_primary_color[] =
672 {
673 RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
674 RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
675 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
676 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
677 };
678
679 static GLuint radeon_previous_color[] =
680 {
681 RADEON_COLOR_ARG_A_CURRENT_COLOR,
682 RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
683 RADEON_COLOR_ARG_A_CURRENT_ALPHA,
684 RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
685 };
686
687 /* GL_ZERO table - indices 0-3
688 * GL_ONE table - indices 1-4
689 */
690 static GLuint radeon_zero_color[] =
691 {
692 RADEON_COLOR_ARG_A_ZERO,
693 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
694 RADEON_COLOR_ARG_A_ZERO,
695 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
696 RADEON_COLOR_ARG_A_ZERO
697 };
698
699
700 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
701 */
702 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
703 {
704 {
705 RADEON_ALPHA_ARG_A_T0_ALPHA,
706 RADEON_ALPHA_ARG_A_T1_ALPHA,
707 RADEON_ALPHA_ARG_A_T2_ALPHA
708 },
709 {
710 RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
711 RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
712 RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
713 },
714 };
715
716 static GLuint radeon_tfactor_alpha[] =
717 {
718 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
719 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
720 };
721
722 static GLuint radeon_primary_alpha[] =
723 {
724 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
725 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
726 };
727
728 static GLuint radeon_previous_alpha[] =
729 {
730 RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
731 RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
732 };
733
734 /* GL_ZERO table - indices 0-1
735 * GL_ONE table - indices 1-2
736 */
737 static GLuint radeon_zero_alpha[] =
738 {
739 RADEON_ALPHA_ARG_A_ZERO,
740 RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
741 RADEON_ALPHA_ARG_A_ZERO
742 };
743
744
745 /* Extract the arg from slot A, shift it into the correct argument slot
746 * and set the corresponding complement bit.
747 */
748 #define RADEON_COLOR_ARG( n, arg ) \
749 do { \
750 color_combine |= \
751 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
752 << RADEON_COLOR_ARG_##arg##_SHIFT); \
753 color_combine |= \
754 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
755 << RADEON_COMP_ARG_##arg##_SHIFT); \
756 } while (0)
757
758 #define RADEON_ALPHA_ARG( n, arg ) \
759 do { \
760 alpha_combine |= \
761 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
762 << RADEON_ALPHA_ARG_##arg##_SHIFT); \
763 alpha_combine |= \
764 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
765 << RADEON_COMP_ARG_##arg##_SHIFT); \
766 } while (0)
767
768
769 /* ================================================================
770 * Texture unit state management
771 */
772
773 static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
774 {
775 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
776 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
777 GLuint color_combine, alpha_combine;
778
779 /* texUnit->_Current can be NULL if and only if the texture unit is
780 * not actually enabled.
781 */
782 assert( (texUnit->_ReallyEnabled == 0)
783 || (texUnit->_Current != NULL) );
784
785 if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
786 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit );
787 }
788
789 /* Set the texture environment state. Isn't this nice and clean?
790 * The chip will automagically set the texture alpha to 0xff when
791 * the texture format does not include an alpha component. This
792 * reduces the amount of special-casing we have to do, alpha-only
793 * textures being a notable exception.
794 */
795 if ( !texUnit->_ReallyEnabled ) {
796 /* Don't cache these results.
797 */
798 rmesa->state.texture.unit[unit].format = 0;
799 rmesa->state.texture.unit[unit].envMode = 0;
800 color_combine = radeon_color_combine[unit][RADEON_DISABLE];
801 alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
802 }
803 else {
804 const struct gl_texture_object *tObj = texUnit->_Current;
805 const GLenum format = tObj->Image[tObj->BaseLevel]->Format;
806 GLuint color_arg[3], alpha_arg[3];
807 GLuint i, numColorArgs = 0, numAlphaArgs = 0;
808 GLuint RGBshift = texUnit->CombineScaleShiftRGB;
809 GLuint Ashift = texUnit->CombineScaleShiftA;
810
811 switch ( texUnit->EnvMode ) {
812 case GL_REPLACE:
813 switch ( format ) {
814 case GL_RGBA:
815 case GL_LUMINANCE_ALPHA:
816 case GL_INTENSITY:
817 color_combine = radeon_color_combine[unit][RADEON_REPLACE];
818 alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
819 break;
820 case GL_ALPHA:
821 color_combine = radeon_color_combine[unit][RADEON_DISABLE];
822 alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
823 break;
824 case GL_LUMINANCE:
825 case GL_RGB:
826 case GL_YCBCR_MESA:
827 color_combine = radeon_color_combine[unit][RADEON_REPLACE];
828 alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
829 break;
830 case GL_COLOR_INDEX:
831 default:
832 return GL_FALSE;
833 }
834 break;
835
836 case GL_MODULATE:
837 switch ( format ) {
838 case GL_RGBA:
839 case GL_LUMINANCE_ALPHA:
840 case GL_INTENSITY:
841 color_combine = radeon_color_combine[unit][RADEON_MODULATE];
842 alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
843 break;
844 case GL_ALPHA:
845 color_combine = radeon_color_combine[unit][RADEON_DISABLE];
846 alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
847 break;
848 case GL_RGB:
849 case GL_LUMINANCE:
850 case GL_YCBCR_MESA:
851 color_combine = radeon_color_combine[unit][RADEON_MODULATE];
852 alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
853 break;
854 case GL_COLOR_INDEX:
855 default:
856 return GL_FALSE;
857 }
858 break;
859
860 case GL_DECAL:
861 switch ( format ) {
862 case GL_RGBA:
863 case GL_RGB:
864 case GL_YCBCR_MESA:
865 color_combine = radeon_color_combine[unit][RADEON_DECAL];
866 alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
867 break;
868 case GL_ALPHA:
869 case GL_LUMINANCE:
870 case GL_LUMINANCE_ALPHA:
871 case GL_INTENSITY:
872 color_combine = radeon_color_combine[unit][RADEON_DISABLE];
873 alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
874 break;
875 case GL_COLOR_INDEX:
876 default:
877 return GL_FALSE;
878 }
879 break;
880
881 case GL_BLEND:
882 switch ( format ) {
883 case GL_RGBA:
884 case GL_RGB:
885 case GL_LUMINANCE:
886 case GL_LUMINANCE_ALPHA:
887 case GL_YCBCR_MESA:
888 color_combine = radeon_color_combine[unit][RADEON_BLEND];
889 alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
890 break;
891 case GL_ALPHA:
892 color_combine = radeon_color_combine[unit][RADEON_DISABLE];
893 alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
894 break;
895 case GL_INTENSITY:
896 color_combine = radeon_color_combine[unit][RADEON_BLEND];
897 alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
898 break;
899 case GL_COLOR_INDEX:
900 default:
901 return GL_FALSE;
902 }
903 break;
904
905 case GL_ADD:
906 switch ( format ) {
907 case GL_RGBA:
908 case GL_RGB:
909 case GL_LUMINANCE:
910 case GL_LUMINANCE_ALPHA:
911 case GL_YCBCR_MESA:
912 color_combine = radeon_color_combine[unit][RADEON_ADD];
913 alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
914 break;
915 case GL_ALPHA:
916 color_combine = radeon_color_combine[unit][RADEON_DISABLE];
917 alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
918 break;
919 case GL_INTENSITY:
920 color_combine = radeon_color_combine[unit][RADEON_ADD];
921 alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
922 break;
923 case GL_COLOR_INDEX:
924 default:
925 return GL_FALSE;
926 }
927 break;
928
929 case GL_COMBINE:
930 /* Don't cache these results.
931 */
932 rmesa->state.texture.unit[unit].format = 0;
933 rmesa->state.texture.unit[unit].envMode = 0;
934
935 /* Step 0:
936 * Calculate how many arguments we need to process.
937 */
938 switch ( texUnit->CombineModeRGB ) {
939 case GL_REPLACE:
940 numColorArgs = 1;
941 break;
942 case GL_MODULATE:
943 case GL_ADD:
944 case GL_ADD_SIGNED:
945 case GL_SUBTRACT:
946 case GL_DOT3_RGB:
947 case GL_DOT3_RGBA:
948 case GL_DOT3_RGB_EXT:
949 case GL_DOT3_RGBA_EXT:
950 numColorArgs = 2;
951 break;
952 case GL_INTERPOLATE:
953 case GL_MODULATE_ADD_ATI:
954 case GL_MODULATE_SIGNED_ADD_ATI:
955 case GL_MODULATE_SUBTRACT_ATI:
956 numColorArgs = 3;
957 break;
958 default:
959 return GL_FALSE;
960 }
961
962 switch ( texUnit->CombineModeA ) {
963 case GL_REPLACE:
964 numAlphaArgs = 1;
965 break;
966 case GL_MODULATE:
967 case GL_ADD:
968 case GL_ADD_SIGNED:
969 case GL_SUBTRACT:
970 numAlphaArgs = 2;
971 break;
972 case GL_INTERPOLATE:
973 case GL_MODULATE_ADD_ATI:
974 case GL_MODULATE_SIGNED_ADD_ATI:
975 case GL_MODULATE_SUBTRACT_ATI:
976 numAlphaArgs = 3;
977 break;
978 default:
979 return GL_FALSE;
980 }
981
982 /* Step 1:
983 * Extract the color and alpha combine function arguments.
984 */
985 for ( i = 0 ; i < numColorArgs ; i++ ) {
986 const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
987 assert(op >= 0);
988 assert(op <= 3);
989 switch ( texUnit->CombineSourceRGB[i] ) {
990 case GL_TEXTURE:
991 color_arg[i] = radeon_texture_color[op][unit];
992 break;
993 case GL_CONSTANT:
994 color_arg[i] = radeon_tfactor_color[op];
995 break;
996 case GL_PRIMARY_COLOR:
997 color_arg[i] = radeon_primary_color[op];
998 break;
999 case GL_PREVIOUS:
1000 color_arg[i] = radeon_previous_color[op];
1001 break;
1002 case GL_ZERO:
1003 color_arg[i] = radeon_zero_color[op];
1004 break;
1005 case GL_ONE:
1006 color_arg[i] = radeon_zero_color[op+1];
1007 break;
1008 default:
1009 return GL_FALSE;
1010 }
1011 }
1012
1013 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
1014 const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
1015 assert(op >= 0);
1016 assert(op <= 1);
1017 switch ( texUnit->CombineSourceA[i] ) {
1018 case GL_TEXTURE:
1019 alpha_arg[i] = radeon_texture_alpha[op][unit];
1020 break;
1021 case GL_CONSTANT:
1022 alpha_arg[i] = radeon_tfactor_alpha[op];
1023 break;
1024 case GL_PRIMARY_COLOR:
1025 alpha_arg[i] = radeon_primary_alpha[op];
1026 break;
1027 case GL_PREVIOUS:
1028 alpha_arg[i] = radeon_previous_alpha[op];
1029 break;
1030 case GL_ZERO:
1031 alpha_arg[i] = radeon_zero_alpha[op];
1032 break;
1033 case GL_ONE:
1034 alpha_arg[i] = radeon_zero_alpha[op+1];
1035 break;
1036 default:
1037 return GL_FALSE;
1038 }
1039 }
1040
1041 /* Step 2:
1042 * Build up the color and alpha combine functions.
1043 */
1044 switch ( texUnit->CombineModeRGB ) {
1045 case GL_REPLACE:
1046 color_combine = (RADEON_COLOR_ARG_A_ZERO |
1047 RADEON_COLOR_ARG_B_ZERO |
1048 RADEON_BLEND_CTL_ADD |
1049 RADEON_CLAMP_TX);
1050 RADEON_COLOR_ARG( 0, C );
1051 break;
1052 case GL_MODULATE:
1053 color_combine = (RADEON_COLOR_ARG_C_ZERO |
1054 RADEON_BLEND_CTL_ADD |
1055 RADEON_CLAMP_TX);
1056 RADEON_COLOR_ARG( 0, A );
1057 RADEON_COLOR_ARG( 1, B );
1058 break;
1059 case GL_ADD:
1060 color_combine = (RADEON_COLOR_ARG_B_ZERO |
1061 RADEON_COMP_ARG_B |
1062 RADEON_BLEND_CTL_ADD |
1063 RADEON_CLAMP_TX);
1064 RADEON_COLOR_ARG( 0, A );
1065 RADEON_COLOR_ARG( 1, C );
1066 break;
1067 case GL_ADD_SIGNED:
1068 color_combine = (RADEON_COLOR_ARG_B_ZERO |
1069 RADEON_COMP_ARG_B |
1070 RADEON_BLEND_CTL_ADDSIGNED |
1071 RADEON_CLAMP_TX);
1072 RADEON_COLOR_ARG( 0, A );
1073 RADEON_COLOR_ARG( 1, C );
1074 break;
1075 case GL_SUBTRACT:
1076 color_combine = (RADEON_COLOR_ARG_B_ZERO |
1077 RADEON_COMP_ARG_B |
1078 RADEON_BLEND_CTL_SUBTRACT |
1079 RADEON_CLAMP_TX);
1080 RADEON_COLOR_ARG( 0, A );
1081 RADEON_COLOR_ARG( 1, C );
1082 break;
1083 case GL_INTERPOLATE:
1084 color_combine = (RADEON_BLEND_CTL_BLEND |
1085 RADEON_CLAMP_TX);
1086 RADEON_COLOR_ARG( 0, B );
1087 RADEON_COLOR_ARG( 1, A );
1088 RADEON_COLOR_ARG( 2, C );
1089 break;
1090
1091 case GL_DOT3_RGB_EXT:
1092 case GL_DOT3_RGBA_EXT:
1093 /* The EXT version of the DOT3 extension does not support the
1094 * scale factor, but the ARB version (and the version in OpenGL
1095 * 1.3) does.
1096 */
1097 RGBshift = 0;
1098 Ashift = 0;
1099 /* FALLTHROUGH */
1100
1101 case GL_DOT3_RGB:
1102 case GL_DOT3_RGBA:
1103 /* The R100 / RV200 only support a 1X multiplier in hardware
1104 * w/the ARB version.
1105 */
1106 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
1107 return GL_FALSE;
1108 }
1109
1110 RGBshift += 2;
1111 Ashift = RGBshift;
1112
1113 color_combine = (RADEON_COLOR_ARG_C_ZERO |
1114 RADEON_BLEND_CTL_DOT3 |
1115 RADEON_CLAMP_TX);
1116 RADEON_COLOR_ARG( 0, A );
1117 RADEON_COLOR_ARG( 1, B );
1118 break;
1119
1120 case GL_MODULATE_ADD_ATI:
1121 color_combine = (RADEON_BLEND_CTL_ADD |
1122 RADEON_CLAMP_TX);
1123 RADEON_COLOR_ARG( 0, A );
1124 RADEON_COLOR_ARG( 1, C );
1125 RADEON_COLOR_ARG( 2, B );
1126 break;
1127 case GL_MODULATE_SIGNED_ADD_ATI:
1128 color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
1129 RADEON_CLAMP_TX);
1130 RADEON_COLOR_ARG( 0, A );
1131 RADEON_COLOR_ARG( 1, C );
1132 RADEON_COLOR_ARG( 2, B );
1133 break;
1134 case GL_MODULATE_SUBTRACT_ATI:
1135 color_combine = (RADEON_BLEND_CTL_SUBTRACT |
1136 RADEON_CLAMP_TX);
1137 RADEON_COLOR_ARG( 0, A );
1138 RADEON_COLOR_ARG( 1, C );
1139 RADEON_COLOR_ARG( 2, B );
1140 break;
1141 default:
1142 return GL_FALSE;
1143 }
1144
1145 switch ( texUnit->CombineModeA ) {
1146 case GL_REPLACE:
1147 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
1148 RADEON_ALPHA_ARG_B_ZERO |
1149 RADEON_BLEND_CTL_ADD |
1150 RADEON_CLAMP_TX);
1151 RADEON_ALPHA_ARG( 0, C );
1152 break;
1153 case GL_MODULATE:
1154 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
1155 RADEON_BLEND_CTL_ADD |
1156 RADEON_CLAMP_TX);
1157 RADEON_ALPHA_ARG( 0, A );
1158 RADEON_ALPHA_ARG( 1, B );
1159 break;
1160 case GL_ADD:
1161 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
1162 RADEON_COMP_ARG_B |
1163 RADEON_BLEND_CTL_ADD |
1164 RADEON_CLAMP_TX);
1165 RADEON_ALPHA_ARG( 0, A );
1166 RADEON_ALPHA_ARG( 1, C );
1167 break;
1168 case GL_ADD_SIGNED:
1169 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
1170 RADEON_COMP_ARG_B |
1171 RADEON_BLEND_CTL_ADDSIGNED |
1172 RADEON_CLAMP_TX);
1173 RADEON_ALPHA_ARG( 0, A );
1174 RADEON_ALPHA_ARG( 1, C );
1175 break;
1176 case GL_SUBTRACT:
1177 alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
1178 RADEON_COMP_ARG_B |
1179 RADEON_BLEND_CTL_SUBTRACT |
1180 RADEON_CLAMP_TX);
1181 RADEON_ALPHA_ARG( 0, A );
1182 RADEON_ALPHA_ARG( 1, C );
1183 break;
1184 case GL_INTERPOLATE:
1185 alpha_combine = (RADEON_BLEND_CTL_BLEND |
1186 RADEON_CLAMP_TX);
1187 RADEON_ALPHA_ARG( 0, B );
1188 RADEON_ALPHA_ARG( 1, A );
1189 RADEON_ALPHA_ARG( 2, C );
1190 break;
1191
1192 case GL_MODULATE_ADD_ATI:
1193 alpha_combine = (RADEON_BLEND_CTL_ADD |
1194 RADEON_CLAMP_TX);
1195 RADEON_ALPHA_ARG( 0, A );
1196 RADEON_ALPHA_ARG( 1, C );
1197 RADEON_ALPHA_ARG( 2, B );
1198 break;
1199 case GL_MODULATE_SIGNED_ADD_ATI:
1200 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
1201 RADEON_CLAMP_TX);
1202 RADEON_ALPHA_ARG( 0, A );
1203 RADEON_ALPHA_ARG( 1, C );
1204 RADEON_ALPHA_ARG( 2, B );
1205 break;
1206 case GL_MODULATE_SUBTRACT_ATI:
1207 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
1208 RADEON_CLAMP_TX);
1209 RADEON_ALPHA_ARG( 0, A );
1210 RADEON_ALPHA_ARG( 1, C );
1211 RADEON_ALPHA_ARG( 2, B );
1212 break;
1213 default:
1214 return GL_FALSE;
1215 }
1216
1217 if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
1218 || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) {
1219 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
1220 }
1221
1222 /* Step 3:
1223 * Apply the scale factor.
1224 */
1225 color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
1226 alpha_combine |= (Ashift << RADEON_SCALE_SHIFT);
1227
1228 /* All done!
1229 */
1230 break;
1231
1232 default:
1233 return GL_FALSE;
1234 }
1235 }
1236
1237 if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
1238 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
1239 RADEON_STATECHANGE( rmesa, tex[unit] );
1240 rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
1241 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
1242 }
1243
1244 return GL_TRUE;
1245 }
1246
1247 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
1248 RADEON_MIN_FILTER_MASK | \
1249 RADEON_MAG_FILTER_MASK | \
1250 RADEON_MAX_ANISO_MASK | \
1251 RADEON_YUV_TO_RGB | \
1252 RADEON_YUV_TEMPERATURE_MASK | \
1253 RADEON_CLAMP_S_MASK | \
1254 RADEON_CLAMP_T_MASK | \
1255 RADEON_BORDER_MODE_D3D )
1256
1257 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
1258 RADEON_TXFORMAT_HEIGHT_MASK | \
1259 RADEON_TXFORMAT_FORMAT_MASK | \
1260 RADEON_TXFORMAT_F5_WIDTH_MASK | \
1261 RADEON_TXFORMAT_F5_HEIGHT_MASK | \
1262 RADEON_TXFORMAT_ALPHA_IN_MAP | \
1263 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \
1264 RADEON_TXFORMAT_NON_POWER2)
1265
1266
1267 static void import_tex_obj_state( radeonContextPtr rmesa,
1268 int unit,
1269 radeonTexObjPtr texobj )
1270 {
1271 GLuint *cmd = RADEON_DB_STATE( tex[unit] );
1272
1273 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
1274 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
1275 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1276 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
1277 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
1278 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
1279 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
1280
1281 if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
1282 GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
1283 txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
1284 txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
1285 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
1286 }
1287
1288 texobj->dirty_state &= ~(1<<unit);
1289 }
1290
1291
1292
1293
1294 static void set_texgen_matrix( radeonContextPtr rmesa,
1295 GLuint unit,
1296 const GLfloat *s_plane,
1297 const GLfloat *t_plane )
1298 {
1299 static const GLfloat scale_identity[4] = { 1,1,1,1 };
1300
1301 if (!TEST_EQ_4V( s_plane, scale_identity) ||
1302 !TEST_EQ_4V( t_plane, scale_identity)) {
1303 rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
1304 rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
1305 rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
1306 rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
1307 rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
1308
1309 rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
1310 rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
1311 rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
1312 rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
1313 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1314 }
1315 }
1316
1317 /* Ignoring the Q texcoord for now.
1318 *
1319 * Returns GL_FALSE if fallback required.
1320 */
1321 static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
1322 {
1323 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1324 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1325 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
1326 GLuint tmp = rmesa->TexGenEnabled;
1327
1328 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
1329 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
1330 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
1331 rmesa->TexGenNeedNormals[unit] = 0;
1332
1333 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
1334 /* Disabled, no fallback:
1335 */
1336 rmesa->TexGenEnabled |=
1337 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
1338 return GL_TRUE;
1339 }
1340 else if (texUnit->TexGenEnabled & Q_BIT) {
1341 /* Very easy to do this, in fact would remove a fallback case
1342 * elsewhere, but I haven't done it yet... Fallback:
1343 */
1344 fprintf(stderr, "fallback Q_BIT\n");
1345 return GL_FALSE;
1346 }
1347 else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
1348 texUnit->GenModeS != texUnit->GenModeT) {
1349 /* Mixed modes, fallback:
1350 */
1351 /* fprintf(stderr, "fallback mixed texgen\n"); */
1352 return GL_FALSE;
1353 }
1354 else
1355 rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
1356
1357 switch (texUnit->GenModeS) {
1358 case GL_OBJECT_LINEAR:
1359 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
1360 set_texgen_matrix( rmesa, unit,
1361 texUnit->ObjectPlaneS,
1362 texUnit->ObjectPlaneT);
1363 break;
1364
1365 case GL_EYE_LINEAR:
1366 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
1367 set_texgen_matrix( rmesa, unit,
1368 texUnit->EyePlaneS,
1369 texUnit->EyePlaneT);
1370 break;
1371
1372 case GL_REFLECTION_MAP_NV:
1373 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1374 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
1375 break;
1376
1377 case GL_NORMAL_MAP_NV:
1378 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1379 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
1380 break;
1381
1382 case GL_SPHERE_MAP:
1383 default:
1384 /* Unsupported mode, fallback:
1385 */
1386 /* fprintf(stderr, "fallback unsupported texgen\n"); */
1387 return GL_FALSE;
1388 }
1389
1390 if (tmp != rmesa->TexGenEnabled) {
1391 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1392 }
1393
1394 return GL_TRUE;
1395 }
1396
1397
1398 static void disable_tex( GLcontext *ctx, int unit )
1399 {
1400 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1401
1402 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {
1403 /* Texture unit disabled */
1404 if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1405 /* The old texture is no longer bound to this texture unit.
1406 * Mark it as such.
1407 */
1408
1409 rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
1410 rmesa->state.texture.unit[unit].texobj = NULL;
1411 }
1412
1413 RADEON_STATECHANGE( rmesa, ctx );
1414 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &=
1415 ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);
1416
1417 RADEON_STATECHANGE( rmesa, tcl );
1418 switch (unit) {
1419 case 0:
1420 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 |
1421 RADEON_TCL_VTX_Q0);
1422 break;
1423 case 1:
1424 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 |
1425 RADEON_TCL_VTX_Q1);
1426 break;
1427 default:
1428 break;
1429 }
1430
1431
1432 if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
1433 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
1434 rmesa->recheck_texgen[unit] = GL_TRUE;
1435 }
1436
1437
1438
1439 {
1440 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
1441 GLuint tmp = rmesa->TexGenEnabled;
1442
1443 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
1444 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
1445 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
1446 rmesa->TexGenNeedNormals[unit] = 0;
1447 rmesa->TexGenEnabled |=
1448 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
1449
1450 if (tmp != rmesa->TexGenEnabled) {
1451 rmesa->recheck_texgen[unit] = GL_TRUE;
1452 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1453 }
1454 }
1455 }
1456 }
1457
1458 static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
1459 {
1460 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1461 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1462 struct gl_texture_object *tObj = texUnit->_Current;
1463 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1464
1465 /* Need to load the 2d images associated with this unit.
1466 */
1467 if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
1468 t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
1469 t->base.dirty_images[0] = ~0;
1470 }
1471
1472 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
1473
1474 if ( t->base.dirty_images[0] ) {
1475 RADEON_FIREVERTICES( rmesa );
1476 radeonSetTexImages( rmesa, tObj );
1477 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
1478 if ( !t->base.memBlock )
1479 return GL_FALSE;
1480 }
1481
1482 return GL_TRUE;
1483 }
1484
1485 static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
1486 {
1487 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1488 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1489 struct gl_texture_object *tObj = texUnit->_Current;
1490 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1491
1492 if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) {
1493 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
1494 t->base.dirty_images[0] = ~0;
1495 }
1496
1497 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
1498
1499 if ( t->base.dirty_images[0] ) {
1500 RADEON_FIREVERTICES( rmesa );
1501 radeonSetTexImages( rmesa, tObj );
1502 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
1503 if ( !t->base.memBlock /* && !rmesa->prefer_agp_client_texturing FIXME */ ) {
1504 fprintf(stderr, "%s: upload failed\n", __FUNCTION__);
1505 return GL_FALSE;
1506 }
1507 }
1508
1509 return GL_TRUE;
1510 }
1511
1512
1513 static GLboolean update_tex_common( GLcontext *ctx, int unit )
1514 {
1515 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1516 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1517 struct gl_texture_object *tObj = texUnit->_Current;
1518 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1519 GLenum format;
1520
1521 /* Fallback if there's a texture border */
1522 if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) {
1523 fprintf(stderr, "%s: border\n", __FUNCTION__);
1524 return GL_FALSE;
1525 }
1526
1527 /* Update state if this is a different texture object to last
1528 * time.
1529 */
1530 if ( rmesa->state.texture.unit[unit].texobj != t ) {
1531 if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1532 /* The old texture is no longer bound to this texture unit.
1533 * Mark it as such.
1534 */
1535
1536 rmesa->state.texture.unit[unit].texobj->base.bound &=
1537 ~(1UL << unit);
1538 }
1539
1540 rmesa->state.texture.unit[unit].texobj = t;
1541 t->base.bound |= (1UL << unit);
1542 t->dirty_state |= 1<<unit;
1543 driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
1544 }
1545
1546
1547 /* Newly enabled?
1548 */
1549 if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {
1550 RADEON_STATECHANGE( rmesa, ctx );
1551 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
1552 (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
1553
1554 RADEON_STATECHANGE( rmesa, tcl );
1555
1556 if (unit == 0)
1557 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0;
1558 else
1559 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1;
1560
1561 rmesa->recheck_texgen[unit] = GL_TRUE;
1562 }
1563
1564 if (t->dirty_state & (1<<unit)) {
1565 import_tex_obj_state( rmesa, unit, t );
1566 }
1567
1568 if (rmesa->recheck_texgen[unit]) {
1569 GLboolean fallback = !radeon_validate_texgen( ctx, unit );
1570 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1571 rmesa->recheck_texgen[unit] = 0;
1572 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1573 }
1574
1575 format = tObj->Image[tObj->BaseLevel]->Format;
1576 if ( rmesa->state.texture.unit[unit].format != format ||
1577 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
1578 rmesa->state.texture.unit[unit].format = format;
1579 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
1580 if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
1581 return GL_FALSE;
1582 }
1583 }
1584
1585 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1586 return !t->border_fallback;
1587 }
1588
1589
1590
1591 static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
1592 {
1593 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1594
1595 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 0 );
1596
1597 if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {
1598 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 1 );
1599
1600 return (enable_tex_rect( ctx, unit ) &&
1601 update_tex_common( ctx, unit ));
1602 }
1603 else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
1604 return (enable_tex_2d( ctx, unit ) &&
1605 update_tex_common( ctx, unit ));
1606 }
1607 else if ( texUnit->_ReallyEnabled ) {
1608 return GL_FALSE;
1609 }
1610 else {
1611 disable_tex( ctx, unit );
1612 return GL_TRUE;
1613 }
1614 }
1615
1616 void radeonUpdateTextureState( GLcontext *ctx )
1617 {
1618 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1619 GLboolean ok;
1620
1621 ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
1622 radeonUpdateTextureUnit( ctx, 1 ));
1623
1624 FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
1625
1626 if (rmesa->TclFallback)
1627 radeonChooseVertexState( ctx );
1628 }