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