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