Merge branch 'master' of git://anongit.freedesktop.org/mesa/mesa
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texstate.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/context.h"
38 #include "main/macros.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
41 #include "main/enums.h"
42
43 #include "radeon_common.h"
44 #include "radeon_mipmap_tree.h"
45 #include "r200_context.h"
46 #include "r200_state.h"
47 #include "r200_ioctl.h"
48 #include "r200_swtcl.h"
49 #include "r200_tex.h"
50 #include "r200_tcl.h"
51
52
53 #define R200_TXFORMAT_A8 R200_TXFORMAT_I8
54 #define R200_TXFORMAT_L8 R200_TXFORMAT_I8
55 #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88
56 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422
57 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
58 #define R200_TXFORMAT_RGB_DXT1 R200_TXFORMAT_DXT1
59 #define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
60 #define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
61 #define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
62
63 #define _COLOR(f) \
64 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
65 #define _COLOR_REV(f) \
66 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
67 #define _ALPHA(f) \
68 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
69 #define _ALPHA_REV(f) \
70 [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
71 #define _YUV(f) \
72 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
73 #define _INVALID(f) \
74 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
75 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
76 && (tx_table_be[f].format != 0xffffffff) )
77
78 struct tx_table {
79 GLuint format, filter;
80 };
81
82 static const struct tx_table tx_table_be[] =
83 {
84 [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
85 _ALPHA_REV(RGBA8888),
86 _ALPHA(ARGB8888),
87 _ALPHA_REV(ARGB8888),
88 _INVALID(RGB888),
89 _COLOR(RGB565),
90 _COLOR_REV(RGB565),
91 _ALPHA(ARGB4444),
92 _ALPHA_REV(ARGB4444),
93 _ALPHA(ARGB1555),
94 _ALPHA_REV(ARGB1555),
95 _ALPHA(AL88),
96 _ALPHA_REV(AL88),
97 _ALPHA(A8),
98 _COLOR(L8),
99 _ALPHA(I8),
100 _INVALID(CI8),
101 _YUV(YCBCR),
102 _YUV(YCBCR_REV),
103 _INVALID(RGB_FXT1),
104 _INVALID(RGBA_FXT1),
105 _COLOR(RGB_DXT1),
106 _ALPHA(RGBA_DXT1),
107 _ALPHA(RGBA_DXT3),
108 _ALPHA(RGBA_DXT5),
109 };
110
111 static const struct tx_table tx_table_le[] =
112 {
113 _ALPHA(RGBA8888),
114 [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
115 _ALPHA(ARGB8888),
116 _ALPHA_REV(ARGB8888),
117 [ MESA_FORMAT_RGB888 ] = { R200_TXFORMAT_ARGB8888, 0 },
118 _COLOR(RGB565),
119 _COLOR_REV(RGB565),
120 _ALPHA(ARGB4444),
121 _ALPHA_REV(ARGB4444),
122 _ALPHA(ARGB1555),
123 _ALPHA_REV(ARGB1555),
124 _ALPHA(AL88),
125 _ALPHA_REV(AL88),
126 _ALPHA(A8),
127 _COLOR(L8),
128 _ALPHA(I8),
129 _INVALID(CI8),
130 _YUV(YCBCR),
131 _YUV(YCBCR_REV),
132 _INVALID(RGB_FXT1),
133 _INVALID(RGBA_FXT1),
134 _COLOR(RGB_DXT1),
135 _ALPHA(RGBA_DXT1),
136 _ALPHA(RGBA_DXT3),
137 _ALPHA(RGBA_DXT5),
138 };
139
140 #undef _COLOR
141 #undef _ALPHA
142 #undef _INVALID
143
144 /* ================================================================
145 * Texture combine functions
146 */
147
148 /* GL_ARB_texture_env_combine support
149 */
150
151 /* The color tables have combine functions for GL_SRC_COLOR,
152 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
153 */
154 static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] =
155 {
156 {
157 R200_TXC_ARG_A_R0_COLOR,
158 R200_TXC_ARG_A_R1_COLOR,
159 R200_TXC_ARG_A_R2_COLOR,
160 R200_TXC_ARG_A_R3_COLOR,
161 R200_TXC_ARG_A_R4_COLOR,
162 R200_TXC_ARG_A_R5_COLOR
163 },
164 {
165 R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A,
166 R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A,
167 R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A,
168 R200_TXC_ARG_A_R3_COLOR | R200_TXC_COMP_ARG_A,
169 R200_TXC_ARG_A_R4_COLOR | R200_TXC_COMP_ARG_A,
170 R200_TXC_ARG_A_R5_COLOR | R200_TXC_COMP_ARG_A
171 },
172 {
173 R200_TXC_ARG_A_R0_ALPHA,
174 R200_TXC_ARG_A_R1_ALPHA,
175 R200_TXC_ARG_A_R2_ALPHA,
176 R200_TXC_ARG_A_R3_ALPHA,
177 R200_TXC_ARG_A_R4_ALPHA,
178 R200_TXC_ARG_A_R5_ALPHA
179 },
180 {
181 R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A,
182 R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A,
183 R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A,
184 R200_TXC_ARG_A_R3_ALPHA | R200_TXC_COMP_ARG_A,
185 R200_TXC_ARG_A_R4_ALPHA | R200_TXC_COMP_ARG_A,
186 R200_TXC_ARG_A_R5_ALPHA | R200_TXC_COMP_ARG_A
187 },
188 };
189
190 static GLuint r200_tfactor_color[] =
191 {
192 R200_TXC_ARG_A_TFACTOR_COLOR,
193 R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A,
194 R200_TXC_ARG_A_TFACTOR_ALPHA,
195 R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A
196 };
197
198 static GLuint r200_tfactor1_color[] =
199 {
200 R200_TXC_ARG_A_TFACTOR1_COLOR,
201 R200_TXC_ARG_A_TFACTOR1_COLOR | R200_TXC_COMP_ARG_A,
202 R200_TXC_ARG_A_TFACTOR1_ALPHA,
203 R200_TXC_ARG_A_TFACTOR1_ALPHA | R200_TXC_COMP_ARG_A
204 };
205
206 static GLuint r200_primary_color[] =
207 {
208 R200_TXC_ARG_A_DIFFUSE_COLOR,
209 R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A,
210 R200_TXC_ARG_A_DIFFUSE_ALPHA,
211 R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A
212 };
213
214 /* GL_ZERO table - indices 0-3
215 * GL_ONE table - indices 1-4
216 */
217 static GLuint r200_zero_color[] =
218 {
219 R200_TXC_ARG_A_ZERO,
220 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
221 R200_TXC_ARG_A_ZERO,
222 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
223 R200_TXC_ARG_A_ZERO
224 };
225
226 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
227 */
228 static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] =
229 {
230 {
231 R200_TXA_ARG_A_R0_ALPHA,
232 R200_TXA_ARG_A_R1_ALPHA,
233 R200_TXA_ARG_A_R2_ALPHA,
234 R200_TXA_ARG_A_R3_ALPHA,
235 R200_TXA_ARG_A_R4_ALPHA,
236 R200_TXA_ARG_A_R5_ALPHA
237 },
238 {
239 R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A,
240 R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A,
241 R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A,
242 R200_TXA_ARG_A_R3_ALPHA | R200_TXA_COMP_ARG_A,
243 R200_TXA_ARG_A_R4_ALPHA | R200_TXA_COMP_ARG_A,
244 R200_TXA_ARG_A_R5_ALPHA | R200_TXA_COMP_ARG_A
245 },
246 };
247
248 static GLuint r200_tfactor_alpha[] =
249 {
250 R200_TXA_ARG_A_TFACTOR_ALPHA,
251 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
252 };
253
254 static GLuint r200_tfactor1_alpha[] =
255 {
256 R200_TXA_ARG_A_TFACTOR1_ALPHA,
257 R200_TXA_ARG_A_TFACTOR1_ALPHA | R200_TXA_COMP_ARG_A
258 };
259
260 static GLuint r200_primary_alpha[] =
261 {
262 R200_TXA_ARG_A_DIFFUSE_ALPHA,
263 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
264 };
265
266 /* GL_ZERO table - indices 0-1
267 * GL_ONE table - indices 1-2
268 */
269 static GLuint r200_zero_alpha[] =
270 {
271 R200_TXA_ARG_A_ZERO,
272 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
273 R200_TXA_ARG_A_ZERO,
274 };
275
276
277 /* Extract the arg from slot A, shift it into the correct argument slot
278 * and set the corresponding complement bit.
279 */
280 #define R200_COLOR_ARG( n, arg ) \
281 do { \
282 color_combine |= \
283 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
284 << R200_TXC_ARG_##arg##_SHIFT); \
285 color_combine |= \
286 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
287 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
288 } while (0)
289
290 #define R200_ALPHA_ARG( n, arg ) \
291 do { \
292 alpha_combine |= \
293 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
294 << R200_TXA_ARG_##arg##_SHIFT); \
295 alpha_combine |= \
296 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
297 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
298 } while (0)
299
300
301 /* ================================================================
302 * Texture unit state management
303 */
304
305 static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs )
306 {
307 r200ContextPtr rmesa = R200_CONTEXT(ctx);
308 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
309 GLuint color_combine, alpha_combine;
310 GLuint color_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] &
311 ~(R200_TXC_SCALE_MASK | R200_TXC_OUTPUT_REG_MASK | R200_TXC_TFACTOR_SEL_MASK |
312 R200_TXC_TFACTOR1_SEL_MASK);
313 GLuint alpha_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] &
314 ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK | R200_TXA_OUTPUT_REG_MASK |
315 R200_TXA_TFACTOR_SEL_MASK | R200_TXA_TFACTOR1_SEL_MASK);
316
317 /* texUnit->_Current can be NULL if and only if the texture unit is
318 * not actually enabled.
319 */
320 assert( (texUnit->_ReallyEnabled == 0)
321 || (texUnit->_Current != NULL) );
322
323 if ( R200_DEBUG & RADEON_TEXTURE ) {
324 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
325 }
326
327 /* Set the texture environment state. Isn't this nice and clean?
328 * The chip will automagically set the texture alpha to 0xff when
329 * the texture format does not include an alpha component. This
330 * reduces the amount of special-casing we have to do, alpha-only
331 * textures being a notable exception.
332 */
333
334 color_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXC_OUTPUT_REG_SHIFT) |
335 (unit << R200_TXC_TFACTOR_SEL_SHIFT) |
336 (replaceargs << R200_TXC_TFACTOR1_SEL_SHIFT);
337 alpha_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXA_OUTPUT_REG_SHIFT) |
338 (unit << R200_TXA_TFACTOR_SEL_SHIFT) |
339 (replaceargs << R200_TXA_TFACTOR1_SEL_SHIFT);
340
341 if ( !texUnit->_ReallyEnabled ) {
342 assert( unit == 0);
343 color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO
344 | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
345 alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO
346 | R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD;
347 }
348 else {
349 GLuint color_arg[3], alpha_arg[3];
350 GLuint i;
351 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
352 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
353 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
354 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
355
356
357 const GLint replaceoprgb =
358 ctx->Texture.Unit[replaceargs]._CurrentCombine->OperandRGB[0] - GL_SRC_COLOR;
359 const GLint replaceopa =
360 ctx->Texture.Unit[replaceargs]._CurrentCombine->OperandA[0] - GL_SRC_ALPHA;
361
362 /* Step 1:
363 * Extract the color and alpha combine function arguments.
364 */
365 for ( i = 0 ; i < numColorArgs ; i++ ) {
366 GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
367 const GLint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
368 assert(op >= 0);
369 assert(op <= 3);
370 switch ( srcRGBi ) {
371 case GL_TEXTURE:
372 color_arg[i] = r200_register_color[op][unit];
373 break;
374 case GL_CONSTANT:
375 color_arg[i] = r200_tfactor_color[op];
376 break;
377 case GL_PRIMARY_COLOR:
378 color_arg[i] = r200_primary_color[op];
379 break;
380 case GL_PREVIOUS:
381 if (replaceargs != unit) {
382 const GLint srcRGBreplace =
383 ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceRGB[0];
384 if (op >= 2) {
385 op = op ^ replaceopa;
386 }
387 else {
388 op = op ^ replaceoprgb;
389 }
390 switch (srcRGBreplace) {
391 case GL_TEXTURE:
392 color_arg[i] = r200_register_color[op][replaceargs];
393 break;
394 case GL_CONSTANT:
395 color_arg[i] = r200_tfactor1_color[op];
396 break;
397 case GL_PRIMARY_COLOR:
398 color_arg[i] = r200_primary_color[op];
399 break;
400 case GL_PREVIOUS:
401 if (slot == 0)
402 color_arg[i] = r200_primary_color[op];
403 else
404 color_arg[i] = r200_register_color[op]
405 [rmesa->state.texture.unit[replaceargs - 1].outputreg];
406 break;
407 case GL_ZERO:
408 color_arg[i] = r200_zero_color[op];
409 break;
410 case GL_ONE:
411 color_arg[i] = r200_zero_color[op+1];
412 break;
413 case GL_TEXTURE0:
414 case GL_TEXTURE1:
415 case GL_TEXTURE2:
416 case GL_TEXTURE3:
417 case GL_TEXTURE4:
418 case GL_TEXTURE5:
419 color_arg[i] = r200_register_color[op][srcRGBreplace - GL_TEXTURE0];
420 break;
421 default:
422 return GL_FALSE;
423 }
424 }
425 else {
426 if (slot == 0)
427 color_arg[i] = r200_primary_color[op];
428 else
429 color_arg[i] = r200_register_color[op]
430 [rmesa->state.texture.unit[unit - 1].outputreg];
431 }
432 break;
433 case GL_ZERO:
434 color_arg[i] = r200_zero_color[op];
435 break;
436 case GL_ONE:
437 color_arg[i] = r200_zero_color[op+1];
438 break;
439 case GL_TEXTURE0:
440 case GL_TEXTURE1:
441 case GL_TEXTURE2:
442 case GL_TEXTURE3:
443 case GL_TEXTURE4:
444 case GL_TEXTURE5:
445 color_arg[i] = r200_register_color[op][srcRGBi - GL_TEXTURE0];
446 break;
447 default:
448 return GL_FALSE;
449 }
450 }
451
452 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
453 GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
454 const GLint srcAi = texUnit->_CurrentCombine->SourceA[i];
455 assert(op >= 0);
456 assert(op <= 1);
457 switch ( srcAi ) {
458 case GL_TEXTURE:
459 alpha_arg[i] = r200_register_alpha[op][unit];
460 break;
461 case GL_CONSTANT:
462 alpha_arg[i] = r200_tfactor_alpha[op];
463 break;
464 case GL_PRIMARY_COLOR:
465 alpha_arg[i] = r200_primary_alpha[op];
466 break;
467 case GL_PREVIOUS:
468 if (replaceargs != unit) {
469 const GLint srcAreplace =
470 ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceA[0];
471 op = op ^ replaceopa;
472 switch (srcAreplace) {
473 case GL_TEXTURE:
474 alpha_arg[i] = r200_register_alpha[op][replaceargs];
475 break;
476 case GL_CONSTANT:
477 alpha_arg[i] = r200_tfactor1_alpha[op];
478 break;
479 case GL_PRIMARY_COLOR:
480 alpha_arg[i] = r200_primary_alpha[op];
481 break;
482 case GL_PREVIOUS:
483 if (slot == 0)
484 alpha_arg[i] = r200_primary_alpha[op];
485 else
486 alpha_arg[i] = r200_register_alpha[op]
487 [rmesa->state.texture.unit[replaceargs - 1].outputreg];
488 break;
489 case GL_ZERO:
490 alpha_arg[i] = r200_zero_alpha[op];
491 break;
492 case GL_ONE:
493 alpha_arg[i] = r200_zero_alpha[op+1];
494 break;
495 case GL_TEXTURE0:
496 case GL_TEXTURE1:
497 case GL_TEXTURE2:
498 case GL_TEXTURE3:
499 case GL_TEXTURE4:
500 case GL_TEXTURE5:
501 alpha_arg[i] = r200_register_alpha[op][srcAreplace - GL_TEXTURE0];
502 break;
503 default:
504 return GL_FALSE;
505 }
506 }
507 else {
508 if (slot == 0)
509 alpha_arg[i] = r200_primary_alpha[op];
510 else
511 alpha_arg[i] = r200_register_alpha[op]
512 [rmesa->state.texture.unit[unit - 1].outputreg];
513 }
514 break;
515 case GL_ZERO:
516 alpha_arg[i] = r200_zero_alpha[op];
517 break;
518 case GL_ONE:
519 alpha_arg[i] = r200_zero_alpha[op+1];
520 break;
521 case GL_TEXTURE0:
522 case GL_TEXTURE1:
523 case GL_TEXTURE2:
524 case GL_TEXTURE3:
525 case GL_TEXTURE4:
526 case GL_TEXTURE5:
527 alpha_arg[i] = r200_register_alpha[op][srcAi - GL_TEXTURE0];
528 break;
529 default:
530 return GL_FALSE;
531 }
532 }
533
534 /* Step 2:
535 * Build up the color and alpha combine functions.
536 */
537 switch ( texUnit->_CurrentCombine->ModeRGB ) {
538 case GL_REPLACE:
539 color_combine = (R200_TXC_ARG_A_ZERO |
540 R200_TXC_ARG_B_ZERO |
541 R200_TXC_OP_MADD);
542 R200_COLOR_ARG( 0, C );
543 break;
544 case GL_MODULATE:
545 color_combine = (R200_TXC_ARG_C_ZERO |
546 R200_TXC_OP_MADD);
547 R200_COLOR_ARG( 0, A );
548 R200_COLOR_ARG( 1, B );
549 break;
550 case GL_ADD:
551 color_combine = (R200_TXC_ARG_B_ZERO |
552 R200_TXC_COMP_ARG_B |
553 R200_TXC_OP_MADD);
554 R200_COLOR_ARG( 0, A );
555 R200_COLOR_ARG( 1, C );
556 break;
557 case GL_ADD_SIGNED:
558 color_combine = (R200_TXC_ARG_B_ZERO |
559 R200_TXC_COMP_ARG_B |
560 R200_TXC_BIAS_ARG_C | /* new */
561 R200_TXC_OP_MADD); /* was ADDSIGNED */
562 R200_COLOR_ARG( 0, A );
563 R200_COLOR_ARG( 1, C );
564 break;
565 case GL_SUBTRACT:
566 color_combine = (R200_TXC_ARG_B_ZERO |
567 R200_TXC_COMP_ARG_B |
568 R200_TXC_NEG_ARG_C |
569 R200_TXC_OP_MADD);
570 R200_COLOR_ARG( 0, A );
571 R200_COLOR_ARG( 1, C );
572 break;
573 case GL_INTERPOLATE:
574 color_combine = (R200_TXC_OP_LERP);
575 R200_COLOR_ARG( 0, B );
576 R200_COLOR_ARG( 1, A );
577 R200_COLOR_ARG( 2, C );
578 break;
579
580 case GL_DOT3_RGB_EXT:
581 case GL_DOT3_RGBA_EXT:
582 /* The EXT version of the DOT3 extension does not support the
583 * scale factor, but the ARB version (and the version in OpenGL
584 * 1.3) does.
585 */
586 RGBshift = 0;
587 /* FALLTHROUGH */
588
589 case GL_DOT3_RGB:
590 case GL_DOT3_RGBA:
591 /* DOT3 works differently on R200 than on R100. On R100, just
592 * setting the DOT3 mode did everything for you. On R200, the
593 * driver has to enable the biasing and scale in the inputs to
594 * put them in the proper [-1,1] range. This is what the 4x and
595 * the -0.5 in the DOT3 spec do. The post-scale is then set
596 * normally.
597 */
598
599 color_combine = (R200_TXC_ARG_C_ZERO |
600 R200_TXC_OP_DOT3 |
601 R200_TXC_BIAS_ARG_A |
602 R200_TXC_BIAS_ARG_B |
603 R200_TXC_SCALE_ARG_A |
604 R200_TXC_SCALE_ARG_B);
605 R200_COLOR_ARG( 0, A );
606 R200_COLOR_ARG( 1, B );
607 break;
608
609 case GL_MODULATE_ADD_ATI:
610 color_combine = (R200_TXC_OP_MADD);
611 R200_COLOR_ARG( 0, A );
612 R200_COLOR_ARG( 1, C );
613 R200_COLOR_ARG( 2, B );
614 break;
615 case GL_MODULATE_SIGNED_ADD_ATI:
616 color_combine = (R200_TXC_BIAS_ARG_C | /* new */
617 R200_TXC_OP_MADD); /* was ADDSIGNED */
618 R200_COLOR_ARG( 0, A );
619 R200_COLOR_ARG( 1, C );
620 R200_COLOR_ARG( 2, B );
621 break;
622 case GL_MODULATE_SUBTRACT_ATI:
623 color_combine = (R200_TXC_NEG_ARG_C |
624 R200_TXC_OP_MADD);
625 R200_COLOR_ARG( 0, A );
626 R200_COLOR_ARG( 1, C );
627 R200_COLOR_ARG( 2, B );
628 break;
629 default:
630 return GL_FALSE;
631 }
632
633 switch ( texUnit->_CurrentCombine->ModeA ) {
634 case GL_REPLACE:
635 alpha_combine = (R200_TXA_ARG_A_ZERO |
636 R200_TXA_ARG_B_ZERO |
637 R200_TXA_OP_MADD);
638 R200_ALPHA_ARG( 0, C );
639 break;
640 case GL_MODULATE:
641 alpha_combine = (R200_TXA_ARG_C_ZERO |
642 R200_TXA_OP_MADD);
643 R200_ALPHA_ARG( 0, A );
644 R200_ALPHA_ARG( 1, B );
645 break;
646 case GL_ADD:
647 alpha_combine = (R200_TXA_ARG_B_ZERO |
648 R200_TXA_COMP_ARG_B |
649 R200_TXA_OP_MADD);
650 R200_ALPHA_ARG( 0, A );
651 R200_ALPHA_ARG( 1, C );
652 break;
653 case GL_ADD_SIGNED:
654 alpha_combine = (R200_TXA_ARG_B_ZERO |
655 R200_TXA_COMP_ARG_B |
656 R200_TXA_BIAS_ARG_C | /* new */
657 R200_TXA_OP_MADD); /* was ADDSIGNED */
658 R200_ALPHA_ARG( 0, A );
659 R200_ALPHA_ARG( 1, C );
660 break;
661 case GL_SUBTRACT:
662 alpha_combine = (R200_TXA_ARG_B_ZERO |
663 R200_TXA_COMP_ARG_B |
664 R200_TXA_NEG_ARG_C |
665 R200_TXA_OP_MADD);
666 R200_ALPHA_ARG( 0, A );
667 R200_ALPHA_ARG( 1, C );
668 break;
669 case GL_INTERPOLATE:
670 alpha_combine = (R200_TXA_OP_LERP);
671 R200_ALPHA_ARG( 0, B );
672 R200_ALPHA_ARG( 1, A );
673 R200_ALPHA_ARG( 2, C );
674 break;
675
676 case GL_MODULATE_ADD_ATI:
677 alpha_combine = (R200_TXA_OP_MADD);
678 R200_ALPHA_ARG( 0, A );
679 R200_ALPHA_ARG( 1, C );
680 R200_ALPHA_ARG( 2, B );
681 break;
682 case GL_MODULATE_SIGNED_ADD_ATI:
683 alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */
684 R200_TXA_OP_MADD); /* was ADDSIGNED */
685 R200_ALPHA_ARG( 0, A );
686 R200_ALPHA_ARG( 1, C );
687 R200_ALPHA_ARG( 2, B );
688 break;
689 case GL_MODULATE_SUBTRACT_ATI:
690 alpha_combine = (R200_TXA_NEG_ARG_C |
691 R200_TXA_OP_MADD);
692 R200_ALPHA_ARG( 0, A );
693 R200_ALPHA_ARG( 1, C );
694 R200_ALPHA_ARG( 2, B );
695 break;
696 default:
697 return GL_FALSE;
698 }
699
700 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
701 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
702 alpha_scale |= R200_TXA_DOT_ALPHA;
703 Ashift = RGBshift;
704 }
705
706 /* Step 3:
707 * Apply the scale factor.
708 */
709 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
710 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT);
711
712 /* All done!
713 */
714 }
715
716 if ( rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] != color_combine ||
717 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] != alpha_combine ||
718 rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] != color_scale ||
719 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] != alpha_scale) {
720 R200_STATECHANGE( rmesa, pix[slot] );
721 rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] = color_combine;
722 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] = alpha_combine;
723 rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] = color_scale;
724 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] = alpha_scale;
725 }
726
727 return GL_TRUE;
728 }
729
730 void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
731 unsigned long long offset, GLint depth, GLuint pitch)
732 {
733 r200ContextPtr rmesa = pDRICtx->driverPrivate;
734 struct gl_texture_object *tObj =
735 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
736 radeonTexObjPtr t = radeon_tex_obj(tObj);
737
738 if (!tObj)
739 return;
740
741 t->image_override = GL_TRUE;
742
743 if (!offset)
744 return;
745
746 t->bo = NULL;
747 t->override_offset = offset;
748 t->pp_txpitch = pitch - 32;
749
750 switch (depth) {
751 case 32:
752 t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
753 t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
754 break;
755 case 24:
756 default:
757 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
758 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
759 break;
760 case 16:
761 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
762 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
763 break;
764 }
765 }
766
767 void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
768 __DRIdrawable *dPriv)
769 {
770 struct gl_texture_unit *texUnit;
771 struct gl_texture_object *texObj;
772 struct gl_texture_image *texImage;
773 struct radeon_renderbuffer *rb;
774 radeon_texture_image *rImage;
775 radeonContextPtr radeon;
776 struct radeon_framebuffer *rfb;
777 radeonTexObjPtr t;
778 uint32_t pitch_val;
779 gl_format texFormat;
780
781 radeon = pDRICtx->driverPrivate;
782
783 rfb = dPriv->driverPrivate;
784 texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
785 texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
786 texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
787
788 rImage = get_radeon_texture_image(texImage);
789 t = radeon_tex_obj(texObj);
790 if (t == NULL) {
791 return;
792 }
793
794 radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
795 rb = rfb->color_rb[0];
796 if (rb->bo == NULL) {
797 /* Failed to BO for the buffer */
798 return;
799 }
800
801 _mesa_lock_texture(radeon->glCtx, texObj);
802 if (t->bo) {
803 radeon_bo_unref(t->bo);
804 t->bo = NULL;
805 }
806 if (rImage->bo) {
807 radeon_bo_unref(rImage->bo);
808 rImage->bo = NULL;
809 }
810
811 radeon_miptree_unreference(&t->mt);
812 radeon_miptree_unreference(&rImage->mt);
813
814 rImage->bo = rb->bo;
815 radeon_bo_ref(rImage->bo);
816 t->bo = rb->bo;
817 radeon_bo_ref(t->bo);
818 t->tile_bits = 0;
819 t->image_override = GL_TRUE;
820 t->override_offset = 0;
821 t->pp_txpitch &= (1 << 13) -1;
822 pitch_val = rb->pitch;
823 switch (rb->cpp) {
824 case 4:
825 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
826 texFormat = MESA_FORMAT_RGB888;
827 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
828 }
829 else {
830 texFormat = MESA_FORMAT_ARGB8888;
831 t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
832 }
833 t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
834 break;
835 case 3:
836 default:
837 texFormat = MESA_FORMAT_RGB888;
838 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
839 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
840 break;
841 case 2:
842 texFormat = MESA_FORMAT_RGB565;
843 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
844 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
845 break;
846 }
847
848 _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
849 rb->base.Width, rb->base.Height, 1, 0,
850 rb->cpp, texFormat);
851 texImage->RowStride = rb->pitch / rb->cpp;
852
853
854 t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
855 | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
856
857 if (target == GL_TEXTURE_RECTANGLE_NV) {
858 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
859 t->pp_txpitch = pitch_val;
860 t->pp_txpitch -= 32;
861 } else {
862 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
863 R200_TXFORMAT_HEIGHT_MASK |
864 R200_TXFORMAT_CUBIC_MAP_ENABLE |
865 R200_TXFORMAT_F5_WIDTH_MASK |
866 R200_TXFORMAT_F5_HEIGHT_MASK);
867 t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
868 (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
869 }
870
871 t->validated = GL_TRUE;
872 _mesa_unlock_texture(radeon->glCtx, texObj);
873 return;
874 }
875
876
877 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
878 {
879 r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
880 }
881
882
883 #define REF_COLOR 1
884 #define REF_ALPHA 2
885
886 static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
887 {
888 r200ContextPtr rmesa = R200_CONTEXT(ctx);
889 GLint i, j, currslot;
890 GLint maxunitused = -1;
891 GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
892 GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0};
893 GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0};
894 GLint currentnext = -1;
895 GLboolean ok;
896
897 /* find highest used unit */
898 for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
899 if (ctx->Texture.Unit[j]._ReallyEnabled) {
900 maxunitused = j;
901 }
902 }
903 stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA;
904
905 for ( j = maxunitused; j >= 0; j-- ) {
906 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[j];
907
908 rmesa->state.texture.unit[j].outputreg = -1;
909
910 if (stageref[j + 1]) {
911
912 /* use the lowest available reg. That gets us automatically reg0 for the last stage.
913 need this even for disabled units, as it may get referenced due to the replace
914 optimization */
915 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) {
916 if (texregfree[i]) {
917 rmesa->state.texture.unit[j].outputreg = i;
918 break;
919 }
920 }
921 if (rmesa->state.texture.unit[j].outputreg == -1) {
922 /* no more free regs we can use. Need a fallback :-( */
923 return GL_FALSE;
924 }
925
926 nextunit[j] = currentnext;
927
928 if (!texUnit->_ReallyEnabled) {
929 /* the not enabled stages are referenced "indirectly",
930 must not cut off the lower stages */
931 stageref[j] = REF_COLOR | REF_ALPHA;
932 continue;
933 }
934 currentnext = j;
935
936 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
937 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
938 const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ||
939 (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT);
940
941
942 /* check if we need the color part, special case for dot3_rgba
943 as if only the alpha part is referenced later on it still is using the color part */
944 if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) {
945 for ( i = 0 ; i < numColorArgs ; i++ ) {
946 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
947 const GLuint op = texUnit->_CurrentCombine->OperandRGB[i];
948 switch ( srcRGBi ) {
949 case GL_PREVIOUS:
950 /* op 0/1 are referencing color, op 2/3 alpha */
951 stageref[j] |= (op >> 1) + 1;
952 break;
953 case GL_TEXTURE:
954 texregfree[j] = GL_FALSE;
955 break;
956 case GL_TEXTURE0:
957 case GL_TEXTURE1:
958 case GL_TEXTURE2:
959 case GL_TEXTURE3:
960 case GL_TEXTURE4:
961 case GL_TEXTURE5:
962 texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE;
963 break;
964 default: /* don't care about other sources here */
965 break;
966 }
967 }
968 }
969
970 /* alpha args are ignored for dot3_rgba */
971 if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) {
972
973 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
974 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
975 switch ( srcAi ) {
976 case GL_PREVIOUS:
977 stageref[j] |= REF_ALPHA;
978 break;
979 case GL_TEXTURE:
980 texregfree[j] = GL_FALSE;
981 break;
982 case GL_TEXTURE0:
983 case GL_TEXTURE1:
984 case GL_TEXTURE2:
985 case GL_TEXTURE3:
986 case GL_TEXTURE4:
987 case GL_TEXTURE5:
988 texregfree[srcAi - GL_TEXTURE0] = GL_FALSE;
989 break;
990 default: /* don't care about other sources here */
991 break;
992 }
993 }
994 }
995 }
996 }
997
998 /* don't enable texture sampling for units if the result is not used */
999 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1000 if (ctx->Texture.Unit[i]._ReallyEnabled && !texregfree[i])
1001 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
1002 else rmesa->state.texture.unit[i].unitneeded = 0;
1003 }
1004
1005 ok = GL_TRUE;
1006 currslot = 0;
1007 rmesa->state.envneeded = 1;
1008
1009 i = 0;
1010 while ((i <= maxunitused) && (i >= 0)) {
1011 /* only output instruction if the results are referenced */
1012 if (ctx->Texture.Unit[i]._ReallyEnabled && stageref[i+1]) {
1013 GLuint replaceunit = i;
1014 /* try to optimize GL_REPLACE away (only one level deep though) */
1015 if ( (ctx->Texture.Unit[i]._CurrentCombine->ModeRGB == GL_REPLACE) &&
1016 (ctx->Texture.Unit[i]._CurrentCombine->ModeA == GL_REPLACE) &&
1017 (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftRGB == 0) &&
1018 (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftA == 0) &&
1019 (nextunit[i] > 0) ) {
1020 /* yippie! can optimize it away! */
1021 replaceunit = i;
1022 i = nextunit[i];
1023 }
1024
1025 /* need env instruction slot */
1026 rmesa->state.envneeded |= 1 << currslot;
1027 ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit );
1028 if (!ok) return GL_FALSE;
1029 currslot++;
1030 }
1031 i = i + 1;
1032 }
1033
1034 if (currslot == 0) {
1035 /* need one stage at least */
1036 rmesa->state.texture.unit[0].outputreg = 0;
1037 ok = r200UpdateTextureEnv( ctx, 0, 0, 0 );
1038 }
1039
1040 R200_STATECHANGE( rmesa, ctx );
1041 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE);
1042 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT;
1043
1044 return ok;
1045 }
1046
1047 #undef REF_COLOR
1048 #undef REF_ALPHA
1049
1050
1051 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
1052 R200_MIN_FILTER_MASK | \
1053 R200_MAG_FILTER_MASK | \
1054 R200_MAX_ANISO_MASK | \
1055 R200_YUV_TO_RGB | \
1056 R200_YUV_TEMPERATURE_MASK | \
1057 R200_CLAMP_S_MASK | \
1058 R200_CLAMP_T_MASK | \
1059 R200_BORDER_MODE_D3D )
1060
1061 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
1062 R200_TXFORMAT_HEIGHT_MASK | \
1063 R200_TXFORMAT_FORMAT_MASK | \
1064 R200_TXFORMAT_F5_WIDTH_MASK | \
1065 R200_TXFORMAT_F5_HEIGHT_MASK | \
1066 R200_TXFORMAT_ALPHA_IN_MAP | \
1067 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
1068 R200_TXFORMAT_NON_POWER2)
1069
1070 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
1071 R200_TEXCOORD_MASK | \
1072 R200_MIN_MIP_LEVEL_MASK | \
1073 R200_CLAMP_Q_MASK | \
1074 R200_VOLUME_FILTER_MASK)
1075
1076
1077 static void disable_tex_obj_state( r200ContextPtr rmesa,
1078 int unit )
1079 {
1080
1081 R200_STATECHANGE( rmesa, vtx );
1082 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1083
1084 R200_STATECHANGE( rmesa, ctx );
1085 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
1086 if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
1087 TCL_FALLBACK( rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
1088 }
1089
1090 /* Actually want to keep all units less than max active texture
1091 * enabled, right? Fix this for >2 texunits.
1092 */
1093
1094 {
1095 GLuint tmp = rmesa->TexGenEnabled;
1096
1097 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1098 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1099 rmesa->TexGenNeedNormals[unit] = GL_FALSE;
1100 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1101
1102 if (tmp != rmesa->TexGenEnabled) {
1103 rmesa->recheck_texgen[unit] = GL_TRUE;
1104 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1105 }
1106 }
1107 }
1108 static void import_tex_obj_state( r200ContextPtr rmesa,
1109 int unit,
1110 radeonTexObjPtr texobj )
1111 {
1112 /* do not use RADEON_DB_STATE to avoid stale texture caches */
1113 GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
1114
1115 R200_STATECHANGE( rmesa, tex[unit] );
1116
1117 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
1118 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
1119 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1120 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
1121 cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
1122 cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK;
1123 cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
1124 cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
1125 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
1126
1127 if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
1128 GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
1129
1130 R200_STATECHANGE( rmesa, cube[unit] );
1131 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1132 if (rmesa->radeon.radeonScreen->drmSupportsFragShader) {
1133 /* that value is submitted twice. could change cube atom
1134 to not include that command when new drm is used */
1135 cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1136 }
1137 }
1138
1139 }
1140
1141 static void set_texgen_matrix( r200ContextPtr rmesa,
1142 GLuint unit,
1143 const GLfloat *s_plane,
1144 const GLfloat *t_plane,
1145 const GLfloat *r_plane,
1146 const GLfloat *q_plane )
1147 {
1148 GLfloat m[16];
1149
1150 m[0] = s_plane[0];
1151 m[4] = s_plane[1];
1152 m[8] = s_plane[2];
1153 m[12] = s_plane[3];
1154
1155 m[1] = t_plane[0];
1156 m[5] = t_plane[1];
1157 m[9] = t_plane[2];
1158 m[13] = t_plane[3];
1159
1160 m[2] = r_plane[0];
1161 m[6] = r_plane[1];
1162 m[10] = r_plane[2];
1163 m[14] = r_plane[3];
1164
1165 m[3] = q_plane[0];
1166 m[7] = q_plane[1];
1167 m[11] = q_plane[2];
1168 m[15] = q_plane[3];
1169
1170 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1171 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1172 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1173 }
1174
1175
1176 static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
1177 const GLfloat *planeS,
1178 const GLfloat *planeT,
1179 const GLfloat *planeR,
1180 const GLfloat *planeQ)
1181 {
1182 GLuint needtgenable = 0;
1183
1184 if (!(texGenEnabled & S_BIT)) {
1185 if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) ||
1186 ((texGenEnabled & R_BIT) && planeR[0] != 0.0) ||
1187 ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) {
1188 needtgenable |= S_BIT;
1189 }
1190 }
1191 if (!(texGenEnabled & T_BIT)) {
1192 if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) ||
1193 ((texGenEnabled & R_BIT) && planeR[1] != 0.0) ||
1194 ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) {
1195 needtgenable |= T_BIT;
1196 }
1197 }
1198 if (!(texGenEnabled & R_BIT)) {
1199 if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) ||
1200 ((texGenEnabled & T_BIT) && planeT[2] != 0.0) ||
1201 ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) {
1202 needtgenable |= R_BIT;
1203 }
1204 }
1205 if (!(texGenEnabled & Q_BIT)) {
1206 if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) ||
1207 ((texGenEnabled & T_BIT) && planeT[3] != 0.0) ||
1208 ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) {
1209 needtgenable |= Q_BIT;
1210 }
1211 }
1212
1213 return needtgenable;
1214 }
1215
1216
1217 /*
1218 * Returns GL_FALSE if fallback required.
1219 */
1220 static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
1221 {
1222 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1223 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1224 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
1225 GLuint tgi, tgcm;
1226 GLuint mode = 0;
1227 GLboolean mixed_fallback = GL_FALSE;
1228 static const GLfloat I[16] = {
1229 1, 0, 0, 0,
1230 0, 1, 0, 0,
1231 0, 0, 1, 0,
1232 0, 0, 0, 1 };
1233 static const GLfloat reflect[16] = {
1234 -1, 0, 0, 0,
1235 0, -1, 0, 0,
1236 0, 0, -1, 0,
1237 0, 0, 0, 1 };
1238
1239 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1240 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1241 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1242 rmesa->TexGenNeedNormals[unit] = GL_FALSE;
1243 tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK <<
1244 inputshift);
1245 tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
1246 (unit * 4));
1247
1248 if (0)
1249 fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
1250
1251 if (texUnit->TexGenEnabled & S_BIT) {
1252 mode = texUnit->GenS.Mode;
1253 } else {
1254 tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
1255 }
1256
1257 if (texUnit->TexGenEnabled & T_BIT) {
1258 if (texUnit->GenT.Mode != mode)
1259 mixed_fallback = GL_TRUE;
1260 } else {
1261 tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
1262 }
1263 if (texUnit->TexGenEnabled & R_BIT) {
1264 if (texUnit->GenR.Mode != mode)
1265 mixed_fallback = GL_TRUE;
1266 } else {
1267 tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
1268 }
1269
1270 if (texUnit->TexGenEnabled & Q_BIT) {
1271 if (texUnit->GenQ.Mode != mode)
1272 mixed_fallback = GL_TRUE;
1273 } else {
1274 tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
1275 }
1276
1277 if (mixed_fallback) {
1278 if (R200_DEBUG & RADEON_FALLBACKS)
1279 fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
1280 texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode,
1281 texUnit->GenR.Mode, texUnit->GenQ.Mode);
1282 return GL_FALSE;
1283 }
1284
1285 /* we CANNOT do mixed mode if the texgen mode requires a plane where the input
1286 is not enabled for texgen, since the planes are concatenated into texmat,
1287 and thus the input will come from texcoord rather than tex gen equation!
1288 Either fallback or just hope that those texcoords aren't really needed...
1289 Assuming the former will cause lots of unnecessary fallbacks, the latter will
1290 generate bogus results sometimes - it's pretty much impossible to really know
1291 when a fallback is needed, depends on texmat and what sort of texture is bound
1292 etc, - for now fallback if we're missing either S or T bits, there's a high
1293 probability we need the texcoords in that case.
1294 That's a lot of work for some obscure texgen mixed mode fixup - why oh why
1295 doesn't the chip just directly accept the plane parameters :-(. */
1296 switch (mode) {
1297 case GL_OBJECT_LINEAR: {
1298 GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
1299 texUnit->GenS.ObjectPlane,
1300 texUnit->GenT.ObjectPlane,
1301 texUnit->GenR.ObjectPlane,
1302 texUnit->GenQ.ObjectPlane );
1303 if (needtgenable & (S_BIT | T_BIT)) {
1304 if (R200_DEBUG & RADEON_FALLBACKS)
1305 fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
1306 texUnit->TexGenEnabled);
1307 return GL_FALSE;
1308 }
1309 if (needtgenable & (R_BIT)) {
1310 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1311 }
1312 if (needtgenable & (Q_BIT)) {
1313 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1314 }
1315
1316 tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
1317 set_texgen_matrix( rmesa, unit,
1318 (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.ObjectPlane : I,
1319 (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.ObjectPlane : I + 4,
1320 (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.ObjectPlane : I + 8,
1321 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.ObjectPlane : I + 12);
1322 }
1323 break;
1324
1325 case GL_EYE_LINEAR: {
1326 GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
1327 texUnit->GenS.EyePlane,
1328 texUnit->GenT.EyePlane,
1329 texUnit->GenR.EyePlane,
1330 texUnit->GenQ.EyePlane );
1331 if (needtgenable & (S_BIT | T_BIT)) {
1332 if (R200_DEBUG & RADEON_FALLBACKS)
1333 fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
1334 texUnit->TexGenEnabled);
1335 return GL_FALSE;
1336 }
1337 if (needtgenable & (R_BIT)) {
1338 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1339 }
1340 if (needtgenable & (Q_BIT)) {
1341 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1342 }
1343 tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
1344 set_texgen_matrix( rmesa, unit,
1345 (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.EyePlane : I,
1346 (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.EyePlane : I + 4,
1347 (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.EyePlane : I + 8,
1348 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.EyePlane : I + 12);
1349 }
1350 break;
1351
1352 case GL_REFLECTION_MAP_NV:
1353 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1354 tgi |= R200_TEXGEN_INPUT_EYE_REFLECT << inputshift;
1355 /* pretty weird, must only negate when lighting is enabled? */
1356 if (ctx->Light.Enabled)
1357 set_texgen_matrix( rmesa, unit,
1358 (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
1359 (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
1360 (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
1361 I + 12);
1362 break;
1363
1364 case GL_NORMAL_MAP_NV:
1365 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1366 tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
1367 break;
1368
1369 case GL_SPHERE_MAP:
1370 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1371 tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
1372 break;
1373
1374 case 0:
1375 /* All texgen units were disabled, so just pass coords through. */
1376 tgi |= unit << inputshift;
1377 break;
1378
1379 default:
1380 /* Unsupported mode, fallback:
1381 */
1382 if (R200_DEBUG & RADEON_FALLBACKS)
1383 fprintf(stderr, "fallback unsupported texgen, %d\n",
1384 texUnit->GenS.Mode);
1385 return GL_FALSE;
1386 }
1387
1388 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1389 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
1390
1391 if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] ||
1392 tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
1393 {
1394 R200_STATECHANGE(rmesa, tcg);
1395 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi;
1396 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm;
1397 }
1398
1399 return GL_TRUE;
1400 }
1401
1402 void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
1403 {
1404 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1405
1406 GLuint re_cntl;
1407
1408 re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
1409 if (use_d3d)
1410 re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
1411
1412 if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
1413 R200_STATECHANGE( rmesa, set );
1414 rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
1415 }
1416 }
1417
1418 /**
1419 * Compute the cached hardware register values for the given texture object.
1420 *
1421 * \param rmesa Context pointer
1422 * \param t the r300 texture object
1423 */
1424 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
1425 {
1426 const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
1427 GLint log2Width, log2Height, log2Depth, texelBytes;
1428 uint extra_size = 0;
1429
1430 if ( t->bo ) {
1431 return;
1432 }
1433
1434 log2Width = firstImage->WidthLog2;
1435 log2Height = firstImage->HeightLog2;
1436 log2Depth = firstImage->DepthLog2;
1437 texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
1438
1439 radeon_print(RADEON_TEXTURE, RADEON_TRACE,
1440 "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
1441 __func__, rmesa, t, log2Width, log2Height,
1442 log2Depth, texelBytes, firstImage->TexFormat);
1443
1444 if (!t->image_override) {
1445 if (VALID_FORMAT(firstImage->TexFormat)) {
1446 const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
1447 tx_table_be;
1448
1449 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
1450 R200_TXFORMAT_ALPHA_IN_MAP);
1451 t->pp_txfilter &= ~R200_YUV_TO_RGB;
1452
1453 t->pp_txformat |= table[ firstImage->TexFormat ].format;
1454 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
1455
1456
1457 } else {
1458 _mesa_problem(NULL, "unexpected texture format in %s",
1459 __FUNCTION__);
1460 return;
1461 }
1462 }
1463
1464 t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
1465 t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
1466 & R200_MAX_MIP_LEVEL_MASK;
1467
1468 if ( t->pp_txfilter &
1469 (R200_MIN_FILTER_NEAREST_MIP_NEAREST
1470 | R200_MIN_FILTER_NEAREST_MIP_LINEAR
1471 | R200_MIN_FILTER_LINEAR_MIP_NEAREST
1472 | R200_MIN_FILTER_LINEAR_MIP_LINEAR
1473 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
1474 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
1475 extra_size = t->minLod;
1476
1477 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
1478 R200_TXFORMAT_HEIGHT_MASK |
1479 R200_TXFORMAT_CUBIC_MAP_ENABLE |
1480 R200_TXFORMAT_F5_WIDTH_MASK |
1481 R200_TXFORMAT_F5_HEIGHT_MASK);
1482 t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
1483 ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
1484
1485 t->tile_bits = 0;
1486
1487 t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
1488 | R200_MIN_MIP_LEVEL_MASK);
1489
1490 t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
1491 & R200_MIN_MIP_LEVEL_MASK;
1492
1493 if (t->base.Target == GL_TEXTURE_3D) {
1494 t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
1495 t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
1496
1497 }
1498 else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
1499 ASSERT(log2Width == log2Height);
1500 t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
1501 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
1502 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1503 (R200_TXFORMAT_CUBIC_MAP_ENABLE));
1504 t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
1505 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
1506 (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
1507 (log2Width << R200_FACE_WIDTH_2_SHIFT) |
1508 (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
1509 (log2Width << R200_FACE_WIDTH_3_SHIFT) |
1510 (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
1511 (log2Width << R200_FACE_WIDTH_4_SHIFT) |
1512 (log2Height << R200_FACE_HEIGHT_4_SHIFT));
1513 }
1514 else {
1515 /* If we don't in fact send enough texture coordinates, q will be 1,
1516 * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1517 */
1518 t->pp_txformat_x |= R200_TEXCOORD_PROJ;
1519 }
1520 /* FIXME: NPOT sizes, Is it correct realy? */
1521 t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
1522 | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
1523
1524 if ( !t->image_override ) {
1525 if (_mesa_is_format_compressed(firstImage->TexFormat))
1526 t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1527 else
1528 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1529 t->pp_txpitch -= 32;
1530 }
1531
1532 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1533 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
1534 }
1535
1536 }
1537
1538 static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
1539 {
1540 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1541 radeonTexObj *t = radeon_tex_obj(texObj);
1542
1543 if (!radeon_validate_texture_miptree(ctx, texObj))
1544 return GL_FALSE;
1545
1546 r200_validate_texgen(ctx, unit);
1547 /* Configure the hardware registers (more precisely, the cached version
1548 * of the hardware registers). */
1549 setup_hardware_state(rmesa, t);
1550
1551 if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
1552 texObj->Target == GL_TEXTURE_2D ||
1553 texObj->Target == GL_TEXTURE_1D)
1554 set_re_cntl_d3d( ctx, unit, GL_FALSE );
1555 else
1556 set_re_cntl_d3d( ctx, unit, GL_TRUE );
1557 R200_STATECHANGE( rmesa, ctx );
1558 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
1559
1560 R200_STATECHANGE( rmesa, vtx );
1561 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1562 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1563
1564 rmesa->recheck_texgen[unit] = GL_TRUE;
1565 import_tex_obj_state( rmesa, unit, t );
1566
1567 if (rmesa->recheck_texgen[unit]) {
1568 GLboolean fallback = !r200_validate_texgen( ctx, unit );
1569 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1570 rmesa->recheck_texgen[unit] = 0;
1571 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1572 }
1573
1574 t->validated = GL_TRUE;
1575
1576 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1577
1578 return !t->border_fallback;
1579 }
1580
1581 static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
1582 {
1583 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1584 GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
1585
1586 if (!unitneeded) {
1587 /* disable the unit */
1588 disable_tex_obj_state(rmesa, unit);
1589 return GL_TRUE;
1590 }
1591
1592 if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1593 _mesa_warning(ctx,
1594 "failed to validate texture for unit %d.\n",
1595 unit);
1596 rmesa->state.texture.unit[unit].texobj = NULL;
1597 return GL_FALSE;
1598 }
1599
1600 rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1601 return GL_TRUE;
1602 }
1603
1604
1605 void r200UpdateTextureState( struct gl_context *ctx )
1606 {
1607 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1608 GLboolean ok;
1609 GLuint dbg;
1610
1611 /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
1612 rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
1613 we use these to determine if we want to emit the corresponding state
1614 atoms. */
1615 R200_NEWPRIM( rmesa );
1616
1617 if (ctx->ATIFragmentShader._Enabled) {
1618 GLuint i;
1619 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1620 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
1621 }
1622 ok = GL_TRUE;
1623 }
1624 else {
1625 ok = r200UpdateAllTexEnv( ctx );
1626 }
1627 if (ok) {
1628 ok = (r200UpdateTextureUnit( ctx, 0 ) &&
1629 r200UpdateTextureUnit( ctx, 1 ) &&
1630 r200UpdateTextureUnit( ctx, 2 ) &&
1631 r200UpdateTextureUnit( ctx, 3 ) &&
1632 r200UpdateTextureUnit( ctx, 4 ) &&
1633 r200UpdateTextureUnit( ctx, 5 ));
1634 }
1635
1636 if (ok && ctx->ATIFragmentShader._Enabled) {
1637 r200UpdateFragmentShader(ctx);
1638 }
1639
1640 FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
1641
1642 if (rmesa->radeon.TclFallback)
1643 r200ChooseVertexState( ctx );
1644
1645
1646 if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
1647
1648 /*
1649 * T0 hang workaround -------------
1650 * not needed for r200 derivatives
1651 */
1652 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&
1653 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1654
1655 R200_STATECHANGE(rmesa, ctx);
1656 R200_STATECHANGE(rmesa, tex[1]);
1657 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1658 if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
1659 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1660 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
1661 }
1662 else if (!ctx->ATIFragmentShader._Enabled) {
1663 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
1664 (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {
1665 R200_STATECHANGE(rmesa, tex[1]);
1666 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE;
1667 }
1668 }
1669 /* do the same workaround for the first pass of a fragment shader.
1670 * completely unknown if necessary / sufficient.
1671 */
1672 if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE &&
1673 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1674
1675 R200_STATECHANGE(rmesa, cst);
1676 R200_STATECHANGE(rmesa, tex[1]);
1677 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE;
1678 if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE))
1679 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1680 rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
1681 }
1682
1683 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1684 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1685 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1686 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1687 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1688 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1689 R200_MIN_FILTER_LINEAR)) {
1690 R200_STATECHANGE(rmesa, ctx);
1691 R200_STATECHANGE(rmesa, tex[i+1]);
1692 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1693 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1694 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1695 }
1696 else {
1697 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1698 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1699 R200_STATECHANGE(rmesa, tex[i+1]);
1700 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1701 }
1702 }
1703 } */
1704
1705 /*
1706 * Texture cache LRU hang workaround -------------
1707 * not needed for r200 derivatives
1708 * hopefully this covers first pass of a shader as well
1709 */
1710
1711 /* While the cases below attempt to only enable the workaround in the
1712 * specific cases necessary, they were insufficient. See bugzilla #1519,
1713 * #729, #814. Tests with quake3 showed no impact on performance.
1714 */
1715 dbg = 0x6;
1716
1717 /*
1718 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
1719 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1720 0x04) == 0)) ||
1721 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1722 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1723 0x04) == 0)) ||
1724 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1725 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1726 0x04) == 0)))
1727 {
1728 dbg |= 0x02;
1729 }
1730
1731 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
1732 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1733 0x04) == 0)) ||
1734 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1735 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1736 0x04) == 0)) ||
1737 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1738 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1739 0x04) == 0)))
1740 {
1741 dbg |= 0x04;
1742 }*/
1743
1744 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1745 R200_STATECHANGE( rmesa, tam );
1746 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1747 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);
1748 }
1749 }
1750 }