Fixing *lots* of warning messages, especially concerning unportable
[mesa.git] / src / mesa / drivers / dri / r300 / r300_texstate.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
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 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "context.h"
39 #include "macros.h"
40 #include "texformat.h"
41 #include "enums.h"
42
43 #include "r300_context.h"
44 #include "r300_state.h"
45 #include "r300_ioctl.h"
46 #include "radeon_ioctl.h"
47 //#include "r300_swtcl.h"
48 #include "r300_tex.h"
49 //#include "r300_tcl.h"
50 #include "r300_reg.h"
51
52 #define R200_TXFORMAT_A8 R200_TXFORMAT_I8
53 #define R200_TXFORMAT_L8 R200_TXFORMAT_I8
54 #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88
55 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422
56 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
57
58 #define _COLOR(f) \
59 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
60 #define _COLOR_REV(f) \
61 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
62 #define _ALPHA(f) \
63 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
64 #define _ALPHA_REV(f) \
65 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
66 #define _YUV(f) \
67 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
68 #define _INVALID(f) \
69 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
70 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
71 && (tx_table[f].format != 0xffffffff) )
72
73 static const struct {
74 GLuint format, filter;
75 } tx_table0[] = {
76 _ALPHA(RGBA8888),
77 _ALPHA_REV(RGBA8888),
78 _ALPHA(ARGB8888),
79 _ALPHA_REV(ARGB8888),
80 _INVALID(RGB888),
81 _COLOR(RGB565),
82 _COLOR_REV(RGB565),
83 _ALPHA(ARGB4444),
84 _ALPHA_REV(ARGB4444),
85 _ALPHA(ARGB1555),
86 _ALPHA_REV(ARGB1555),
87 _ALPHA(AL88),
88 _ALPHA_REV(AL88),
89 _ALPHA(A8),
90 _COLOR(L8),
91 _ALPHA(I8),
92 _INVALID(CI8),
93 _YUV(YCBCR),
94 _YUV(YCBCR_REV),
95 };
96
97 static const struct {
98 GLuint format, filter;
99 } tx_table[] = {
100 #ifdef MESA_BIG_ENDIAN
101 /*
102 * NOTE: As we can't do swapping (RBBM_GUI_CNTL doesn't seems to work
103 * on r300) we declare the texture format in swapped form. We
104 * should better find a way to ask the hardware to do the swapping.
105 * Jerome Glisse
106 */
107 {R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8), 0},
108 {R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8), 0},
109 {0xffffff02, 0},
110 {0xffffff03, 0},
111 {0xffffff04, 0},
112 {0xffffff05, 0},
113 {0xffffff06, 0},
114 {0xffffff07, 0},
115 {0xffffff08, 0},
116 {0xffffff09, 0},
117 {0xffffff10, 0},
118 {0xffffff11, 0},
119 {R300_EASY_TX_FORMAT(Y, Y, Y, X, Y8X8), 0},
120 {0xffffff13, 0},
121 {0xffffff14, 0},
122 {0xffffff15, 0},
123 {0xffffff16, 0},
124 {0xffffff17, 0},
125 };
126 #else
127 {R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8), 0},
128 {0xffffff01, 0},
129 {0xffffff02, 0},
130 {0xffffff03, 0},
131 {0xffffff04, 0},
132 {0xffffff05, 0},
133 {R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5), 0},
134 {0xffffff07, 0},
135 {R300_EASY_TX_FORMAT(Y, Z, W, X, W4Z4Y4X4), 0},
136 {0xffffff09, 0},
137 {0xffffff10, 0},
138 {0xffffff11, 0},
139 {R300_EASY_TX_FORMAT(Y, Y, Y, X, Y8X8), 0},
140 {0xffffff13, 0},
141 {0xffffff14, 0},
142 {0xffffff15, 0},
143 {0xffffff16, 0},
144 {0xffffff17, 0},
145 };
146 #endif
147
148 #undef _COLOR
149 #undef _ALPHA
150 #undef _INVALID
151
152
153
154 /**
155 * This function computes the number of bytes of storage needed for
156 * the given texture object (all mipmap levels, all cube faces).
157 * The \c image[face][level].x/y/width/height parameters for upload/blitting
158 * are computed here. \c filter, \c format, etc. will be set here
159 * too.
160 *
161 * \param rmesa Context pointer
162 * \param tObj GL texture object whose images are to be posted to
163 * hardware state.
164 */
165 static void r300SetTexImages(r300ContextPtr rmesa,
166 struct gl_texture_object *tObj)
167 {
168 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
169 const struct gl_texture_image *baseImage =
170 tObj->Image[0][tObj->BaseLevel];
171 GLint curOffset;
172 GLint i;
173 GLint numLevels;
174 GLint log2Width, log2Height, log2Depth;
175
176 /* Set the hardware texture format
177 */
178
179 t->format &= ~(R200_TXFORMAT_FORMAT_MASK |
180 R200_TXFORMAT_ALPHA_IN_MAP);
181 #if 0
182 t->filter &= ~R200_YUV_TO_RGB;
183 #endif
184 if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
185 t->format =
186 tx_table[baseImage->TexFormat->MesaFormat].format;
187 #if 1
188 t->filter |=
189 tx_table[baseImage->TexFormat->MesaFormat].filter;
190 #endif
191 } else {
192 _mesa_problem(NULL, "unexpected texture format in %s",
193 __FUNCTION__);
194 return;
195 }
196
197 /* Compute which mipmap levels we really want to send to the hardware.
198 */
199
200 driCalculateTextureFirstLastLevel((driTextureObject *) t);
201 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
202 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
203 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
204
205 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
206
207 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
208
209 /* Calculate mipmap offsets and dimensions for blitting (uploading)
210 * The idea is that we lay out the mipmap levels within a block of
211 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
212 */
213 curOffset = 0;
214
215 for (i = 0; i < numLevels; i++) {
216 const struct gl_texture_image *texImage;
217 GLuint size;
218
219 texImage = tObj->Image[0][i + t->base.firstLevel];
220 if (!texImage)
221 break;
222
223 /* find image size in bytes */
224 if (texImage->IsCompressed) {
225 size = texImage->CompressedSize;
226 } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
227 size =
228 ((texImage->Width *
229 texImage->TexFormat->TexelBytes + 63)
230 & ~63) * texImage->Height;
231 } else {
232 int w =
233 texImage->Width * texImage->TexFormat->TexelBytes;
234 if (w < 32)
235 w = 32;
236 size = w * texImage->Height * texImage->Depth;
237 }
238 assert(size > 0);
239
240 if(0)
241 fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n", texImage->Width, texImage->Height,
242 texImage->Depth, texImage->TexFormat->TexelBytes,
243 texImage->IntFormat);
244
245 /* Align to 32-byte offset. It is faster to do this unconditionally
246 * (no branch penalty).
247 */
248
249 curOffset = (curOffset + 0x1f) & ~0x1f;
250
251 t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
252 t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
253 t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES);
254 t->image[0][i].height = size / t->image[0][i].width;
255
256 #if 0
257 /* for debugging only and only applicable to non-rectangle targets */
258 assert(size % t->image[0][i].width == 0);
259 assert(t->image[0][i].x == 0
260 || (size < BLIT_WIDTH_BYTES
261 && t->image[0][i].height == 1));
262 #endif
263
264 if (0)
265 fprintf(stderr,
266 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
267 i, texImage->Width, texImage->Height,
268 t->image[0][i].x, t->image[0][i].y,
269 t->image[0][i].width, t->image[0][i].height,
270 size, curOffset);
271
272 curOffset += size;
273
274 }
275
276 /* Align the total size of texture memory block.
277 */
278 t->base.totalSize =
279 (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
280
281 /* Setup remaining cube face blits, if needed */
282 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
283 /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */
284 const GLuint faceSize =
285 (t->base.totalSize + BLIT_WIDTH_BYTES - 1)
286 & ~(BLIT_WIDTH_BYTES - 1);
287 const GLuint lines = faceSize / BLIT_WIDTH_BYTES;
288 GLuint face;
289 /* reuse face 0 x/y/width/height - just adjust y */
290 for (face = 1; face < 6; face++) {
291 for (i = 0; i < numLevels; i++) {
292 t->image[face][i].x = t->image[0][i].x;
293 t->image[face][i].y =
294 t->image[0][i].y + face * lines;
295 t->image[face][i].width = t->image[0][i].width;
296 t->image[face][i].height =
297 t->image[0][i].height;
298 }
299 }
300 t->base.totalSize = 6 * faceSize; /* total texmem needed */
301 }
302
303 /* Hardware state:
304 */
305 #if 0
306 t->filter &= ~R200_MAX_MIP_LEVEL_MASK;
307 t->filter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT;
308 #endif
309 #if 0
310 t->format &= ~(R200_TXFORMAT_WIDTH_MASK |
311 R200_TXFORMAT_HEIGHT_MASK |
312 R200_TXFORMAT_CUBIC_MAP_ENABLE |
313 R200_TXFORMAT_F5_WIDTH_MASK |
314 R200_TXFORMAT_F5_HEIGHT_MASK);
315 t->format |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
316 (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
317 #endif
318
319 t->format_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
320 if (tObj->Target == GL_TEXTURE_3D) {
321 t->format_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
322 t->format_x |= R200_TEXCOORD_VOLUME;
323 } else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
324 ASSERT(log2Width == log2Height);
325 t->format |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
326 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT)
327 | (R200_TXFORMAT_CUBIC_MAP_ENABLE));
328 t->format_x |= R200_TEXCOORD_CUBIC_ENV;
329 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
330 (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
331 (log2Width << R200_FACE_WIDTH_2_SHIFT) |
332 (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
333 (log2Width << R200_FACE_WIDTH_3_SHIFT) |
334 (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
335 (log2Width << R200_FACE_WIDTH_4_SHIFT) |
336 (log2Height << R200_FACE_HEIGHT_4_SHIFT));
337 }
338
339 t->size = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
340 |((tObj->Image[0][t->base.firstLevel]->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)
341 |((log2Width>log2Height)?log2Width:log2Height)<<R300_TX_SIZE_SHIFT);
342
343 /* Only need to round to nearest 32 for textures, but the blitter
344 * requires 64-byte aligned pitches, and we may/may not need the
345 * blitter. NPOT only!
346 */
347 if (baseImage->IsCompressed)
348 t->pitch =
349 (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
350 else
351 t->pitch =
352 ((tObj->Image[0][t->base.firstLevel]->Width *
353 baseImage->TexFormat->TexelBytes) + 63) & ~(63);
354 t->pitch -= 32;
355
356 t->dirty_state = TEX_ALL;
357
358 /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */
359 }
360
361 /* ================================================================
362 * Texture combine functions
363 */
364
365 /* GL_ARB_texture_env_combine support
366 */
367
368 /* The color tables have combine functions for GL_SRC_COLOR,
369 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
370 */
371 static GLuint r300_register_color[][R200_MAX_TEXTURE_UNITS] = {
372 {
373 R200_TXC_ARG_A_R0_COLOR,
374 R200_TXC_ARG_A_R1_COLOR,
375 R200_TXC_ARG_A_R2_COLOR,
376 R200_TXC_ARG_A_R3_COLOR,
377 R200_TXC_ARG_A_R4_COLOR,
378 R200_TXC_ARG_A_R5_COLOR},
379 {
380 R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A,
381 R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A,
382 R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A,
383 R200_TXC_ARG_A_R3_COLOR | R200_TXC_COMP_ARG_A,
384 R200_TXC_ARG_A_R4_COLOR | R200_TXC_COMP_ARG_A,
385 R200_TXC_ARG_A_R5_COLOR | R200_TXC_COMP_ARG_A},
386 {
387 R200_TXC_ARG_A_R0_ALPHA,
388 R200_TXC_ARG_A_R1_ALPHA,
389 R200_TXC_ARG_A_R2_ALPHA,
390 R200_TXC_ARG_A_R3_ALPHA,
391 R200_TXC_ARG_A_R4_ALPHA,
392 R200_TXC_ARG_A_R5_ALPHA},
393 {
394 R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A,
395 R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A,
396 R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A,
397 R200_TXC_ARG_A_R3_ALPHA | R200_TXC_COMP_ARG_A,
398 R200_TXC_ARG_A_R4_ALPHA | R200_TXC_COMP_ARG_A,
399 R200_TXC_ARG_A_R5_ALPHA | R200_TXC_COMP_ARG_A},
400 };
401
402 static GLuint r300_tfactor_color[] = {
403 R200_TXC_ARG_A_TFACTOR_COLOR,
404 R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A,
405 R200_TXC_ARG_A_TFACTOR_ALPHA,
406 R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A
407 };
408
409 static GLuint r300_primary_color[] = {
410 R200_TXC_ARG_A_DIFFUSE_COLOR,
411 R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A,
412 R200_TXC_ARG_A_DIFFUSE_ALPHA,
413 R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A
414 };
415
416 /* GL_ZERO table - indices 0-3
417 * GL_ONE table - indices 1-4
418 */
419 static GLuint r300_zero_color[] = {
420 R200_TXC_ARG_A_ZERO,
421 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
422 R200_TXC_ARG_A_ZERO,
423 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
424 R200_TXC_ARG_A_ZERO
425 };
426
427 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
428 */
429 static GLuint r300_register_alpha[][R200_MAX_TEXTURE_UNITS] = {
430 {
431 R200_TXA_ARG_A_R0_ALPHA,
432 R200_TXA_ARG_A_R1_ALPHA,
433 R200_TXA_ARG_A_R2_ALPHA,
434 R200_TXA_ARG_A_R3_ALPHA,
435 R200_TXA_ARG_A_R4_ALPHA,
436 R200_TXA_ARG_A_R5_ALPHA},
437 {
438 R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A,
439 R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A,
440 R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A,
441 R200_TXA_ARG_A_R3_ALPHA | R200_TXA_COMP_ARG_A,
442 R200_TXA_ARG_A_R4_ALPHA | R200_TXA_COMP_ARG_A,
443 R200_TXA_ARG_A_R5_ALPHA | R200_TXA_COMP_ARG_A},
444 };
445
446 static GLuint r300_tfactor_alpha[] = {
447 R200_TXA_ARG_A_TFACTOR_ALPHA,
448 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
449 };
450
451 static GLuint r300_primary_alpha[] = {
452 R200_TXA_ARG_A_DIFFUSE_ALPHA,
453 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
454 };
455
456 /* GL_ZERO table - indices 0-1
457 * GL_ONE table - indices 1-2
458 */
459 static GLuint r300_zero_alpha[] = {
460 R200_TXA_ARG_A_ZERO,
461 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
462 R200_TXA_ARG_A_ZERO,
463 };
464
465 /* Extract the arg from slot A, shift it into the correct argument slot
466 * and set the corresponding complement bit.
467 */
468 #define R200_COLOR_ARG( n, arg ) \
469 do { \
470 color_combine |= \
471 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
472 << R200_TXC_ARG_##arg##_SHIFT); \
473 color_combine |= \
474 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
475 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
476 } while (0)
477
478 #define R200_ALPHA_ARG( n, arg ) \
479 do { \
480 alpha_combine |= \
481 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
482 << R200_TXA_ARG_##arg##_SHIFT); \
483 alpha_combine |= \
484 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
485 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
486 } while (0)
487
488 /* ================================================================
489 * Texture unit state management
490 */
491
492 static GLboolean r300UpdateTextureEnv(GLcontext * ctx, int unit)
493 {
494 r300ContextPtr rmesa = R300_CONTEXT(ctx);
495 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
496 GLuint color_combine, alpha_combine;
497
498 #if 0 /* disable for now.. */
499 GLuint color_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] &
500 ~(R200_TXC_SCALE_MASK);
501 GLuint alpha_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] &
502 ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK);
503 #endif
504
505 GLuint color_scale=0, alpha_scale=0;
506
507 /* texUnit->_Current can be NULL if and only if the texture unit is
508 * not actually enabled.
509 */
510 assert((texUnit->_ReallyEnabled == 0)
511 || (texUnit->_Current != NULL));
512
513 if (RADEON_DEBUG & DEBUG_TEXTURE) {
514 fprintf(stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx,
515 unit);
516 }
517
518 /* Set the texture environment state. Isn't this nice and clean?
519 * The chip will automagically set the texture alpha to 0xff when
520 * the texture format does not include an alpha component. This
521 * reduces the amount of special-casing we have to do, alpha-only
522 * textures being a notable exception.
523 */
524 /* Don't cache these results.
525 */
526 #if 0
527 rmesa->state.texture.unit[unit].format = 0;
528 #endif
529 rmesa->state.texture.unit[unit].envMode = 0;
530
531
532 if (!texUnit->_ReallyEnabled) {
533 if (unit == 0) {
534 color_combine =
535 R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO |
536 R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
537 alpha_combine =
538 R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO |
539 R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD;
540 } else {
541 color_combine =
542 R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO |
543 R200_TXC_ARG_C_R0_COLOR | R200_TXC_OP_MADD;
544 alpha_combine =
545 R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO |
546 R200_TXA_ARG_C_R0_ALPHA | R200_TXA_OP_MADD;
547 }
548 } else {
549 GLuint color_arg[3], alpha_arg[3];
550 GLuint i;
551 const GLuint numColorArgs =
552 texUnit->_CurrentCombine->_NumArgsRGB;
553 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
554 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
555 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
556
557 /* Step 1:
558 * Extract the color and alpha combine function arguments.
559 */
560 for (i = 0; i < numColorArgs; i++) {
561 const GLint op =
562 texUnit->_CurrentCombine->OperandRGB[i] -
563 GL_SRC_COLOR;
564 assert(op >= 0);
565 assert(op <= 3);
566 switch (texUnit->_CurrentCombine->SourceRGB[i]) {
567 case GL_TEXTURE:
568 color_arg[i] = r300_register_color[op][unit];
569 break;
570 case GL_CONSTANT:
571 color_arg[i] = r300_tfactor_color[op];
572 break;
573 case GL_PRIMARY_COLOR:
574 color_arg[i] = r300_primary_color[op];
575 break;
576 case GL_PREVIOUS:
577 if (unit == 0)
578 color_arg[i] = r300_primary_color[op];
579 else
580 color_arg[i] =
581 r300_register_color[op][0];
582 break;
583 case GL_ZERO:
584 color_arg[i] = r300_zero_color[op];
585 break;
586 case GL_ONE:
587 color_arg[i] = r300_zero_color[op + 1];
588 break;
589 default:
590 return GL_FALSE;
591 }
592 }
593
594 for (i = 0; i < numAlphaArgs; i++) {
595 const GLint op =
596 texUnit->_CurrentCombine->OperandA[i] -
597 GL_SRC_ALPHA;
598 assert(op >= 0);
599 assert(op <= 1);
600 switch (texUnit->_CurrentCombine->SourceA[i]) {
601 case GL_TEXTURE:
602 alpha_arg[i] = r300_register_alpha[op][unit];
603 break;
604 case GL_CONSTANT:
605 alpha_arg[i] = r300_tfactor_alpha[op];
606 break;
607 case GL_PRIMARY_COLOR:
608 alpha_arg[i] = r300_primary_alpha[op];
609 break;
610 case GL_PREVIOUS:
611 if (unit == 0)
612 alpha_arg[i] = r300_primary_alpha[op];
613 else
614 alpha_arg[i] =
615 r300_register_alpha[op][0];
616 break;
617 case GL_ZERO:
618 alpha_arg[i] = r300_zero_alpha[op];
619 break;
620 case GL_ONE:
621 alpha_arg[i] = r300_zero_alpha[op + 1];
622 break;
623 default:
624 return GL_FALSE;
625 }
626 }
627
628 /* Step 2:
629 * Build up the color and alpha combine functions.
630 */
631 switch (texUnit->_CurrentCombine->ModeRGB) {
632 case GL_REPLACE:
633 color_combine = (R200_TXC_ARG_A_ZERO |
634 R200_TXC_ARG_B_ZERO |
635 R200_TXC_OP_MADD);
636 R200_COLOR_ARG(0, C);
637 break;
638 case GL_MODULATE:
639 color_combine = (R200_TXC_ARG_C_ZERO |
640 R200_TXC_OP_MADD);
641 R200_COLOR_ARG(0, A);
642 R200_COLOR_ARG(1, B);
643 break;
644 case GL_ADD:
645 color_combine = (R200_TXC_ARG_B_ZERO |
646 R200_TXC_COMP_ARG_B |
647 R200_TXC_OP_MADD);
648 R200_COLOR_ARG(0, A);
649 R200_COLOR_ARG(1, C);
650 break;
651 case GL_ADD_SIGNED:
652 color_combine = (R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B | R200_TXC_BIAS_ARG_C | /* new */
653 R200_TXC_OP_MADD); /* was ADDSIGNED */
654 R200_COLOR_ARG(0, A);
655 R200_COLOR_ARG(1, C);
656 break;
657 case GL_SUBTRACT:
658 color_combine = (R200_TXC_ARG_B_ZERO |
659 R200_TXC_COMP_ARG_B |
660 R200_TXC_NEG_ARG_C | R200_TXC_OP_MADD);
661 R200_COLOR_ARG(0, A);
662 R200_COLOR_ARG(1, C);
663 break;
664 case GL_INTERPOLATE:
665 color_combine = (R200_TXC_OP_LERP);
666 R200_COLOR_ARG(0, B);
667 R200_COLOR_ARG(1, A);
668 R200_COLOR_ARG(2, C);
669 break;
670
671 case GL_DOT3_RGB_EXT:
672 case GL_DOT3_RGBA_EXT:
673 /* The EXT version of the DOT3 extension does not support the
674 * scale factor, but the ARB version (and the version in OpenGL
675 * 1.3) does.
676 */
677 RGBshift = 0;
678 /* FALLTHROUGH */
679
680 case GL_DOT3_RGB:
681 case GL_DOT3_RGBA:
682 /* DOT3 works differently on R200 than on R100. On R100, just
683 * setting the DOT3 mode did everything for you. On R200, the
684 * driver has to enable the biasing and scale in the inputs to
685 * put them in the proper [-1,1] range. This is what the 4x and
686 * the -0.5 in the DOT3 spec do. The post-scale is then set
687 * normally.
688 */
689
690 color_combine = (R200_TXC_ARG_C_ZERO |
691 R200_TXC_OP_DOT3 |
692 R200_TXC_BIAS_ARG_A |
693 R200_TXC_BIAS_ARG_B |
694 R200_TXC_SCALE_ARG_A |
695 R200_TXC_SCALE_ARG_B);
696 R200_COLOR_ARG(0, A);
697 R200_COLOR_ARG(1, B);
698 break;
699
700 case GL_MODULATE_ADD_ATI:
701 color_combine = (R200_TXC_OP_MADD);
702 R200_COLOR_ARG(0, A);
703 R200_COLOR_ARG(1, C);
704 R200_COLOR_ARG(2, B);
705 break;
706 case GL_MODULATE_SIGNED_ADD_ATI:
707 color_combine = (R200_TXC_BIAS_ARG_C | /* new */
708 R200_TXC_OP_MADD); /* was ADDSIGNED */
709 R200_COLOR_ARG(0, A);
710 R200_COLOR_ARG(1, C);
711 R200_COLOR_ARG(2, B);
712 break;
713 case GL_MODULATE_SUBTRACT_ATI:
714 color_combine = (R200_TXC_NEG_ARG_C | R200_TXC_OP_MADD);
715 R200_COLOR_ARG(0, A);
716 R200_COLOR_ARG(1, C);
717 R200_COLOR_ARG(2, B);
718 break;
719 default:
720 return GL_FALSE;
721 }
722
723 switch (texUnit->_CurrentCombine->ModeA) {
724 case GL_REPLACE:
725 alpha_combine = (R200_TXA_ARG_A_ZERO |
726 R200_TXA_ARG_B_ZERO |
727 R200_TXA_OP_MADD);
728 R200_ALPHA_ARG(0, C);
729 break;
730 case GL_MODULATE:
731 alpha_combine = (R200_TXA_ARG_C_ZERO |
732 R200_TXA_OP_MADD);
733 R200_ALPHA_ARG(0, A);
734 R200_ALPHA_ARG(1, B);
735 break;
736 case GL_ADD:
737 alpha_combine = (R200_TXA_ARG_B_ZERO |
738 R200_TXA_COMP_ARG_B |
739 R200_TXA_OP_MADD);
740 R200_ALPHA_ARG(0, A);
741 R200_ALPHA_ARG(1, C);
742 break;
743 case GL_ADD_SIGNED:
744 alpha_combine = (R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B | R200_TXA_BIAS_ARG_C | /* new */
745 R200_TXA_OP_MADD); /* was ADDSIGNED */
746 R200_ALPHA_ARG(0, A);
747 R200_ALPHA_ARG(1, C);
748 break;
749 case GL_SUBTRACT:
750 alpha_combine = (R200_TXA_ARG_B_ZERO |
751 R200_TXA_COMP_ARG_B |
752 R200_TXA_NEG_ARG_C | R200_TXA_OP_MADD);
753 R200_ALPHA_ARG(0, A);
754 R200_ALPHA_ARG(1, C);
755 break;
756 case GL_INTERPOLATE:
757 alpha_combine = (R200_TXA_OP_LERP);
758 R200_ALPHA_ARG(0, B);
759 R200_ALPHA_ARG(1, A);
760 R200_ALPHA_ARG(2, C);
761 break;
762
763 case GL_MODULATE_ADD_ATI:
764 alpha_combine = (R200_TXA_OP_MADD);
765 R200_ALPHA_ARG(0, A);
766 R200_ALPHA_ARG(1, C);
767 R200_ALPHA_ARG(2, B);
768 break;
769 case GL_MODULATE_SIGNED_ADD_ATI:
770 alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */
771 R200_TXA_OP_MADD); /* was ADDSIGNED */
772 R200_ALPHA_ARG(0, A);
773 R200_ALPHA_ARG(1, C);
774 R200_ALPHA_ARG(2, B);
775 break;
776 case GL_MODULATE_SUBTRACT_ATI:
777 alpha_combine = (R200_TXA_NEG_ARG_C | R200_TXA_OP_MADD);
778 R200_ALPHA_ARG(0, A);
779 R200_ALPHA_ARG(1, C);
780 R200_ALPHA_ARG(2, B);
781 break;
782 default:
783 return GL_FALSE;
784 }
785
786 if ((texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
787 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA)) {
788 alpha_scale |= R200_TXA_DOT_ALPHA;
789 Ashift = RGBshift;
790 }
791
792 /* Step 3:
793 * Apply the scale factor.
794 */
795 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
796 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT);
797
798 /* All done!
799 */
800 }
801
802 #if 0
803 fprintf(stderr, "color_combine=%08x alpha_combine=%08x color_scale=%08x alpha_scale=%08x\n",
804 color_combine, alpha_combine, color_scale, alpha_scale);
805 #endif
806
807 #if 0
808 if (rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine ||
809 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] != alpha_combine ||
810 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] != color_scale ||
811 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] != alpha_scale) {
812 R300_STATECHANGE(rmesa, pix[unit]);
813 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] = color_combine;
814 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] = alpha_combine;
815 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale;
816 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale;
817 }
818
819 #endif
820
821 return GL_TRUE;
822 }
823
824 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
825 R200_MIN_FILTER_MASK | \
826 R200_MAG_FILTER_MASK | \
827 R200_MAX_ANISO_MASK | \
828 R200_YUV_TO_RGB | \
829 R200_YUV_TEMPERATURE_MASK | \
830 R200_CLAMP_S_MASK | \
831 R200_CLAMP_T_MASK | \
832 R200_BORDER_MODE_D3D )
833
834 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
835 R200_TXFORMAT_HEIGHT_MASK | \
836 R200_TXFORMAT_FORMAT_MASK | \
837 R200_TXFORMAT_F5_WIDTH_MASK | \
838 R200_TXFORMAT_F5_HEIGHT_MASK | \
839 R200_TXFORMAT_ALPHA_IN_MAP | \
840 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
841 R200_TXFORMAT_NON_POWER2)
842
843 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
844 R200_TEXCOORD_MASK | \
845 R200_CLAMP_Q_MASK | \
846 R200_VOLUME_FILTER_MASK)
847
848 static void import_tex_obj_state(r300ContextPtr rmesa,
849 int unit, r300TexObjPtr texobj)
850 {
851 #if 0 /* needs fixing.. or should be done elsewhere */
852 GLuint *cmd = R300_DB_STATE(tex[unit]);
853
854 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
855 cmd[TEX_PP_TXFILTER] |= texobj->filter & TEXOBJ_TXFILTER_MASK;
856 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
857 cmd[TEX_PP_TXFORMAT] |= texobj->format & TEXOBJ_TXFORMAT_MASK;
858 cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
859 cmd[TEX_PP_TXFORMAT_X] |=
860 texobj->format_x & TEXOBJ_TXFORMAT_X_MASK;
861 cmd[TEX_PP_TXSIZE] = texobj->size; /* NPOT only! */
862 cmd[TEX_PP_TXPITCH] = texobj->pitch; /* NPOT only! */
863 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
864 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
865 R200_DB_STATECHANGE(rmesa, &rmesa->hw.tex[unit]);
866
867 if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
868 GLuint *cube_cmd = R200_DB_STATE(cube[unit]);
869 GLuint bytesPerFace = texobj->base.totalSize / 6;
870 ASSERT(texobj->totalSize % 6 == 0);
871 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
872 cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] =
873 texobj->pp_txoffset + 1 * bytesPerFace;
874 cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] =
875 texobj->pp_txoffset + 2 * bytesPerFace;
876 cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] =
877 texobj->pp_txoffset + 3 * bytesPerFace;
878 cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] =
879 texobj->pp_txoffset + 4 * bytesPerFace;
880 cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] =
881 texobj->pp_txoffset + 5 * bytesPerFace;
882 R200_DB_STATECHANGE(rmesa, &rmesa->hw.cube[unit]);
883 }
884
885 texobj->dirty_state &= ~(1 << unit);
886 #endif
887 }
888
889 static void set_texgen_matrix(r300ContextPtr rmesa,
890 GLuint unit,
891 const GLfloat * s_plane,
892 const GLfloat * t_plane, const GLfloat * r_plane)
893 {
894 static const GLfloat scale_identity[4] = { 1, 1, 1, 1 };
895
896 if (!TEST_EQ_4V(s_plane, scale_identity) ||
897 !TEST_EQ_4V(t_plane, scale_identity) ||
898 !TEST_EQ_4V(r_plane, scale_identity)) {
899 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE << unit;
900 rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
901 rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
902 rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
903 rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
904
905 rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
906 rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
907 rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
908 rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
909
910 /* NOTE: r_plane goes in the 4th row, not 3rd! */
911 rmesa->TexGenMatrix[unit].m[3] = r_plane[0];
912 rmesa->TexGenMatrix[unit].m[7] = r_plane[1];
913 rmesa->TexGenMatrix[unit].m[11] = r_plane[2];
914 rmesa->TexGenMatrix[unit].m[15] = r_plane[3];
915
916 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
917 }
918 }
919
920 /* Need this special matrix to get correct reflection map coords */
921 static void set_texgen_reflection_matrix(r300ContextPtr rmesa, GLuint unit)
922 {
923 static const GLfloat m[16] = {
924 -1, 0, 0, 0,
925 0, -1, 0, 0,
926 0, 0, 0, -1,
927 0, 0, -1, 0
928 };
929 _math_matrix_loadf(&(rmesa->TexGenMatrix[unit]), m);
930 _math_matrix_analyse(&(rmesa->TexGenMatrix[unit]));
931 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE << unit;
932 }
933
934 /* Need this special matrix to get correct normal map coords */
935 static void set_texgen_normal_map_matrix(r300ContextPtr rmesa, GLuint unit)
936 {
937 static const GLfloat m[16] = {
938 1, 0, 0, 0,
939 0, 1, 0, 0,
940 0, 0, 0, 1,
941 0, 0, 1, 0
942 };
943 _math_matrix_loadf(&(rmesa->TexGenMatrix[unit]), m);
944 _math_matrix_analyse(&(rmesa->TexGenMatrix[unit]));
945 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE << unit;
946 }
947
948 /* Ignoring the Q texcoord for now.
949 *
950 * Returns GL_FALSE if fallback required.
951 */
952 static GLboolean r300_validate_texgen(GLcontext * ctx, GLuint unit)
953 {
954 r300ContextPtr rmesa = R300_CONTEXT(ctx);
955 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
956 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit * 4;
957 GLuint tmp = rmesa->TexGenEnabled;
958
959 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
960 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE << unit);
961 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE << unit);
962 rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK << inputshift);
963 rmesa->TexGenNeedNormals[unit] = 0;
964
965 if (0)
966 fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
967
968 if ((texUnit->TexGenEnabled & (S_BIT | T_BIT | R_BIT)) == 0) {
969 /* Disabled, no fallback:
970 */
971 rmesa->TexGenInputs |=
972 (R200_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
973 return GL_TRUE;
974 } else if (texUnit->TexGenEnabled & Q_BIT) {
975 /* Very easy to do this, in fact would remove a fallback case
976 * elsewhere, but I haven't done it yet... Fallback:
977 */
978 /*fprintf(stderr, "fallback Q_BIT\n"); */
979 return GL_FALSE;
980 } else if (texUnit->TexGenEnabled == (S_BIT | T_BIT) &&
981 texUnit->GenModeS == texUnit->GenModeT) {
982 /* OK */
983 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
984 /* continue */
985 } else if (texUnit->TexGenEnabled == (S_BIT | T_BIT | R_BIT) &&
986 texUnit->GenModeS == texUnit->GenModeT &&
987 texUnit->GenModeT == texUnit->GenModeR) {
988 /* OK */
989 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
990 /* continue */
991 } else {
992 /* Mixed modes, fallback:
993 */
994 /* fprintf(stderr, "fallback mixed texgen\n"); */
995 return GL_FALSE;
996 }
997
998 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
999
1000 switch (texUnit->GenModeS) {
1001 case GL_OBJECT_LINEAR:
1002 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift;
1003 set_texgen_matrix(rmesa, unit,
1004 texUnit->ObjectPlaneS,
1005 texUnit->ObjectPlaneT, texUnit->ObjectPlaneR);
1006 break;
1007
1008 case GL_EYE_LINEAR:
1009 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift;
1010 set_texgen_matrix(rmesa, unit,
1011 texUnit->EyePlaneS,
1012 texUnit->EyePlaneT, texUnit->EyePlaneR);
1013 break;
1014
1015 case GL_REFLECTION_MAP_NV:
1016 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1017 rmesa->TexGenInputs |=
1018 R200_TEXGEN_INPUT_EYE_REFLECT << inputshift;
1019 set_texgen_reflection_matrix(rmesa, unit);
1020 break;
1021
1022 case GL_NORMAL_MAP_NV:
1023 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1024 rmesa->TexGenInputs |=
1025 R200_TEXGEN_INPUT_EYE_NORMAL << inputshift;
1026 set_texgen_normal_map_matrix(rmesa, unit);
1027 break;
1028
1029 case GL_SPHERE_MAP:
1030 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1031 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE << inputshift;
1032 break;
1033
1034 default:
1035 /* Unsupported mode, fallback:
1036 */
1037 /* fprintf(stderr, "fallback unsupported texgen\n"); */
1038 return GL_FALSE;
1039 }
1040
1041 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
1042
1043 if (tmp != rmesa->TexGenEnabled) {
1044 //rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1045 }
1046
1047 return GL_TRUE;
1048 }
1049
1050 static void disable_tex(GLcontext * ctx, int unit)
1051 {
1052 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1053
1054 #if 0 /* This needs to be redone.. or done elsewhere */
1055 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE << unit)) {
1056 /* Texture unit disabled */
1057 if (rmesa->state.texture.unit[unit].texobj != NULL) {
1058 /* The old texture is no longer bound to this texture unit.
1059 * Mark it as such.
1060 */
1061
1062 rmesa->state.texture.unit[unit].texobj->base.bound &=
1063 ~(1UL << unit);
1064 rmesa->state.texture.unit[unit].texobj = NULL;
1065 }
1066
1067 R300_STATECHANGE(rmesa, ctx);
1068 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE |
1069 R200_TEX_BLEND_0_ENABLE) <<
1070 unit);
1071 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE;
1072
1073 R300_STATECHANGE(rmesa, tcl);
1074 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &=
1075 ~(7 << (unit * 3));
1076
1077 if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0 << unit)) {
1078 TCL_FALLBACK(ctx, (RADEON_TCL_FALLBACK_TEXGEN_0 << unit),
1079 GL_FALSE);
1080 }
1081
1082 /* Actually want to keep all units less than max active texture
1083 * enabled, right? Fix this for >2 texunits.
1084 */
1085 /* FIXME: What should happen here if r300UpdateTextureEnv fails? */
1086 if (unit == 0)
1087 r300UpdateTextureEnv(ctx, unit);
1088
1089 {
1090 GLuint inputshift =
1091 R200_TEXGEN_0_INPUT_SHIFT + unit * 4;
1092 GLuint tmp = rmesa->TexGenEnabled;
1093
1094 rmesa->TexGenEnabled &=
1095 ~(R200_TEXGEN_TEXMAT_0_ENABLE << unit);
1096 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE << unit);
1097 rmesa->TexGenEnabled &=
1098 ~(R200_TEXGEN_INPUT_MASK << inputshift);
1099 rmesa->TexGenNeedNormals[unit] = 0;
1100 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1101 rmesa->TexGenInputs &=
1102 ~(R200_TEXGEN_INPUT_MASK << inputshift);
1103
1104 if (tmp != rmesa->TexGenEnabled) {
1105 rmesa->recheck_texgen[unit] = GL_TRUE;
1106 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1107 }
1108 }
1109 }
1110 #endif
1111 }
1112
1113 static GLboolean enable_tex_2d(GLcontext * ctx, int unit)
1114 {
1115 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1116 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1117 struct gl_texture_object *tObj = texUnit->_Current;
1118 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1119
1120 /* Need to load the 2d images associated with this unit.
1121 */
1122 if (t->format & R200_TXFORMAT_NON_POWER2) {
1123 t->format &= ~R200_TXFORMAT_NON_POWER2;
1124 t->base.dirty_images[0] = ~0;
1125 }
1126
1127 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
1128
1129 if (t->base.dirty_images[0]) {
1130 R300_FIREVERTICES(rmesa);
1131 r300SetTexImages(rmesa, tObj);
1132 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
1133 if (!t->base.memBlock)
1134 return GL_FALSE;
1135 }
1136
1137 return GL_TRUE;
1138 }
1139
1140 #if ENABLE_HW_3D_TEXTURE
1141 static GLboolean enable_tex_3d(GLcontext * ctx, int unit)
1142 {
1143 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1144 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1145 struct gl_texture_object *tObj = texUnit->_Current;
1146 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1147
1148 /* Need to load the 3d images associated with this unit.
1149 */
1150 if (t->format & R200_TXFORMAT_NON_POWER2) {
1151 t->format &= ~R200_TXFORMAT_NON_POWER2;
1152 t->base.dirty_images[0] = ~0;
1153 }
1154
1155 ASSERT(tObj->Target == GL_TEXTURE_3D);
1156
1157 /* R100 & R200 do not support mipmaps for 3D textures.
1158 */
1159 if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
1160 return GL_FALSE;
1161 }
1162
1163 if (t->base.dirty_images[0]) {
1164 R300_FIREVERTICES(rmesa);
1165 r300SetTexImages(rmesa, tObj);
1166 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
1167 if (!t->base.memBlock)
1168 return GL_FALSE;
1169 }
1170
1171 return GL_TRUE;
1172 }
1173 #endif
1174
1175 static GLboolean enable_tex_cube(GLcontext * ctx, int unit)
1176 {
1177 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1178 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1179 struct gl_texture_object *tObj = texUnit->_Current;
1180 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1181 GLuint face;
1182
1183 /* Need to load the 2d images associated with this unit.
1184 */
1185 if (t->format & R200_TXFORMAT_NON_POWER2) {
1186 t->format &= ~R200_TXFORMAT_NON_POWER2;
1187 for (face = 0; face < 6; face++)
1188 t->base.dirty_images[face] = ~0;
1189 }
1190
1191 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
1192
1193 if (t->base.dirty_images[0] || t->base.dirty_images[1] ||
1194 t->base.dirty_images[2] || t->base.dirty_images[3] ||
1195 t->base.dirty_images[4] || t->base.dirty_images[5]) {
1196 /* flush */
1197 R300_FIREVERTICES(rmesa);
1198 /* layout memory space, once for all faces */
1199 r300SetTexImages(rmesa, tObj);
1200 }
1201
1202 /* upload (per face) */
1203 for (face = 0; face < 6; face++) {
1204 if (t->base.dirty_images[face]) {
1205 r300UploadTexImages(rmesa,
1206 (r300TexObjPtr) tObj->DriverData,
1207 face);
1208 }
1209 }
1210
1211 if (!t->base.memBlock) {
1212 /* texmem alloc failed, use s/w fallback */
1213 return GL_FALSE;
1214 }
1215
1216 return GL_TRUE;
1217 }
1218
1219 static GLboolean enable_tex_rect(GLcontext * ctx, int unit)
1220 {
1221 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1222 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1223 struct gl_texture_object *tObj = texUnit->_Current;
1224 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1225
1226 if (!(t->format & R200_TXFORMAT_NON_POWER2)) {
1227 t->format |= R200_TXFORMAT_NON_POWER2;
1228 t->base.dirty_images[0] = ~0;
1229 }
1230
1231 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
1232
1233 if (t->base.dirty_images[0]) {
1234 R300_FIREVERTICES(rmesa);
1235 r300SetTexImages(rmesa, tObj);
1236 r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
1237 if (!t->base.memBlock && !rmesa->prefer_gart_client_texturing)
1238 return GL_FALSE;
1239 }
1240
1241 return GL_TRUE;
1242 }
1243
1244 static GLboolean update_tex_common(GLcontext * ctx, int unit)
1245 {
1246 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1247 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1248 struct gl_texture_object *tObj = texUnit->_Current;
1249 r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
1250 GLenum format;
1251
1252 /* Fallback if there's a texture border */
1253 if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
1254 return GL_FALSE;
1255
1256 /* Update state if this is a different texture object to last
1257 * time.
1258 */
1259 if (rmesa->state.texture.unit[unit].texobj != t) {
1260 if (rmesa->state.texture.unit[unit].texobj != NULL) {
1261 /* The old texture is no longer bound to this texture unit.
1262 * Mark it as such.
1263 */
1264
1265 rmesa->state.texture.unit[unit].texobj->base.bound &=
1266 ~(1UL << unit);
1267 }
1268
1269 rmesa->state.texture.unit[unit].texobj = t;
1270 t->base.bound |= (1UL << unit);
1271 t->dirty_state |= 1 << unit;
1272 driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
1273 }
1274
1275 #if 0 /* do elsewhere ? */
1276 /* Newly enabled?
1277 */
1278 if (1
1279 || !(rmesa->hw.ctx.
1280 cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE << unit))) {
1281 R300_STATECHANGE(rmesa, ctx);
1282 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_0_ENABLE |
1283 R200_TEX_BLEND_0_ENABLE) <<
1284 unit;
1285
1286 R300_STATECHANGE(rmesa, vtx);
1287 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1288
1289 rmesa->recheck_texgen[unit] = GL_TRUE;
1290 }
1291
1292 if (t->dirty_state & (1 << unit)) {
1293 import_tex_obj_state(rmesa, unit, t);
1294 }
1295
1296 if (rmesa->recheck_texgen[unit]) {
1297 GLboolean fallback = !r300_validate_texgen(ctx, unit);
1298 TCL_FALLBACK(ctx, (RADEON_TCL_FALLBACK_TEXGEN_0 << unit),
1299 fallback);
1300 rmesa->recheck_texgen[unit] = 0;
1301 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1302 }
1303 #endif
1304
1305 format = tObj->Image[0][tObj->BaseLevel]->Format;
1306 if (rmesa->state.texture.unit[unit].format != format ||
1307 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode) {
1308 //rmesa->state.texture.unit[unit].format = format;
1309 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
1310 if (!r300UpdateTextureEnv(ctx, unit)) {
1311 return GL_FALSE;
1312 }
1313 }
1314
1315 FALLBACK(&rmesa->radeon, RADEON_FALLBACK_BORDER_MODE, t->border_fallback);
1316 return !t->border_fallback;
1317 }
1318
1319 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
1320 {
1321 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1322
1323 if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
1324 return (enable_tex_rect(ctx, unit) &&
1325 update_tex_common(ctx, unit));
1326 } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
1327 return (enable_tex_2d(ctx, unit) &&
1328 update_tex_common(ctx, unit));
1329 }
1330 #if ENABLE_HW_3D_TEXTURE
1331 else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
1332 return (enable_tex_3d(ctx, unit) &&
1333 update_tex_common(ctx, unit));
1334 }
1335 #endif
1336 else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
1337 return (enable_tex_cube(ctx, unit) &&
1338 update_tex_common(ctx, unit));
1339 } else if (texUnit->_ReallyEnabled) {
1340 return GL_FALSE;
1341 } else {
1342 disable_tex(ctx, unit);
1343 return GL_TRUE;
1344 }
1345 }
1346
1347 void r300UpdateTextureState(GLcontext * ctx)
1348 {
1349 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1350 GLboolean ok;
1351 GLuint dbg;
1352 int i;
1353
1354 ok = (r300UpdateTextureUnit(ctx, 0) &&
1355 r300UpdateTextureUnit(ctx, 1) &&
1356 r300UpdateTextureUnit(ctx, 2) &&
1357 r300UpdateTextureUnit(ctx, 3) &&
1358 r300UpdateTextureUnit(ctx, 4) &&
1359 r300UpdateTextureUnit(ctx, 5) &&
1360 r300UpdateTextureUnit(ctx, 6) &&
1361 r300UpdateTextureUnit(ctx, 7)
1362 );
1363
1364 FALLBACK(&rmesa->radeon, RADEON_FALLBACK_TEXTURE, !ok);
1365
1366 /* This needs correction, or just be done elsewhere
1367 if (rmesa->radeon.TclFallback)
1368 r300ChooseVertexState(ctx);
1369 */
1370
1371 #if 0 /* Workaround - disable.. */
1372 if (GET_CHIP(rmesa->radeon.radeonScreen) == RADEON_CHIP_REAL_R200) {
1373 /*
1374 * T0 hang workaround -------------
1375 * not needed for r200 derivatives?
1376 */
1377 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) ==
1378 R200_TEX_0_ENABLE
1379 && (rmesa->hw.tex[0].
1380 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1381 R200_MIN_FILTER_LINEAR) {
1382
1383 R300_STATECHANGE(rmesa, ctx);
1384 R300_STATECHANGE(rmesa, tex[1]);
1385 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1386 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &=
1387 ~TEXOBJ_TXFORMAT_MASK;
1388 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1389 } else {
1390 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE)
1391 && (rmesa->hw.tex[1].
1392 cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1393 R300_STATECHANGE(rmesa, tex[1]);
1394 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &=
1395 ~0x08000000;
1396 }
1397 }
1398
1399 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1400 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1401 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1402 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1403 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1404 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1405 R200_MIN_FILTER_LINEAR)) {
1406 R300_STATECHANGE(rmesa, ctx);
1407 R300_STATECHANGE(rmesa, tex[i+1]);
1408 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1409 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1410 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1411 }
1412 else {
1413 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1414 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1415 R300_STATECHANGE(rmesa, tex[i+1]);
1416 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1417 }
1418 }
1419 } */
1420
1421 /*
1422 * Texture cache LRU hang workaround -------------
1423 * not needed for r200 derivatives?
1424 */
1425 dbg = 0x0;
1426
1427 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE)) &&
1428 ((((rmesa->hw.tex[0].
1429 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04)
1430 == 0))
1431 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE)
1432 &&
1433 ((((rmesa->hw.tex[2].
1434 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1435 0x04) == 0))
1436 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE)
1437 &&
1438 ((((rmesa->hw.tex[4].
1439 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1440 0x04) == 0))) {
1441 dbg |= 0x02;
1442 }
1443
1444 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE)) &&
1445 ((((rmesa->hw.tex[1].
1446 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04)
1447 == 0))
1448 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE)
1449 &&
1450 ((((rmesa->hw.tex[3].
1451 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1452 0x04) == 0))
1453 || ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE)
1454 &&
1455 ((((rmesa->hw.tex[5].
1456 cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1457 0x04) == 0))) {
1458 dbg |= 0x04;
1459 }
1460
1461 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1462 R300_STATECHANGE(rmesa, tam);
1463 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1464 if (0)
1465 printf("TEXCACHE LRU HANG WORKAROUND %x\n",
1466 dbg);
1467 }
1468 }
1469 #endif
1470 }