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