2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
28 **************************************************************************/
32 * Keith Whitwell <keithw@vmware.com>
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"
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"
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
63 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
64 && (tx_table_be[f].format != 0xffffffff) )
67 GLuint format
, filter
;
70 static const struct tx_table tx_table_be
[] =
72 [ MESA_FORMAT_A8B8G8R8_UNORM
] = { R200_TXFORMAT_ABGR8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
73 [ MESA_FORMAT_R8G8B8A8_UNORM
] = { R200_TXFORMAT_RGBA8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
74 [ MESA_FORMAT_B8G8R8A8_UNORM
] = { R200_TXFORMAT_ARGB8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
75 [ MESA_FORMAT_A8R8G8B8_UNORM
] = { R200_TXFORMAT_ARGB8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
76 [ MESA_FORMAT_BGR_UNORM8
] = { 0xffffffff, 0 },
77 [ MESA_FORMAT_B5G6R5_UNORM
] = { R200_TXFORMAT_RGB565
, 0 },
78 [ MESA_FORMAT_R5G6B5_UNORM
] = { R200_TXFORMAT_RGB565
, 0 },
79 [ MESA_FORMAT_B4G4R4A4_UNORM
] = { R200_TXFORMAT_ARGB4444
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
80 [ MESA_FORMAT_A4R4G4B4_UNORM
] = { R200_TXFORMAT_ARGB4444
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
81 [ MESA_FORMAT_B5G5R5A1_UNORM
] = { R200_TXFORMAT_ARGB1555
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
82 [ MESA_FORMAT_A1R5G5B5_UNORM
] = { R200_TXFORMAT_ARGB1555
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
83 [ MESA_FORMAT_L8A8_UNORM
] = { R200_TXFORMAT_AL88
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
84 [ MESA_FORMAT_A8L8_UNORM
] = { R200_TXFORMAT_AL88
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
85 [ MESA_FORMAT_A_UNORM8
] = { R200_TXFORMAT_A8
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
86 [ MESA_FORMAT_L_UNORM8
] = { R200_TXFORMAT_L8
, 0 },
87 [ MESA_FORMAT_I_UNORM8
] = { R200_TXFORMAT_I8
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
88 [ MESA_FORMAT_YCBCR
] = { R200_TXFORMAT_YCBCR
, R200_YUV_TO_RGB
},
89 [ MESA_FORMAT_YCBCR_REV
] = { R200_TXFORMAT_YCBCR_REV
, R200_YUV_TO_RGB
},
90 [ MESA_FORMAT_RGB_FXT1
] = { 0xffffffff, 0 },
91 [ MESA_FORMAT_RGBA_FXT1
] = { 0xffffffff, 0 },
92 [ MESA_FORMAT_RGB_DXT1
] = { R200_TXFORMAT_RGB_DXT1
, 0 },
93 [ MESA_FORMAT_RGBA_DXT1
] = { R200_TXFORMAT_RGBA_DXT1
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
94 [ MESA_FORMAT_RGBA_DXT3
] = { R200_TXFORMAT_RGBA_DXT3
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
95 [ MESA_FORMAT_RGBA_DXT5
] = { R200_TXFORMAT_RGBA_DXT5
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
98 static const struct tx_table tx_table_le
[] =
100 [ MESA_FORMAT_A8B8G8R8_UNORM
] = { R200_TXFORMAT_RGBA8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
101 [ MESA_FORMAT_R8G8B8A8_UNORM
] = { R200_TXFORMAT_ABGR8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
102 [ MESA_FORMAT_B8G8R8A8_UNORM
] = { R200_TXFORMAT_ARGB8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
103 [ MESA_FORMAT_A8R8G8B8_UNORM
] = { R200_TXFORMAT_ARGB8888
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
104 [ MESA_FORMAT_BGR_UNORM8
] = { R200_TXFORMAT_ARGB8888
, 0 },
105 [ MESA_FORMAT_B5G6R5_UNORM
] = { R200_TXFORMAT_RGB565
, 0 },
106 [ MESA_FORMAT_R5G6B5_UNORM
] = { R200_TXFORMAT_RGB565
, 0 },
107 [ MESA_FORMAT_B4G4R4A4_UNORM
] = { R200_TXFORMAT_ARGB4444
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
108 [ MESA_FORMAT_A4R4G4B4_UNORM
] = { R200_TXFORMAT_ARGB4444
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
109 [ MESA_FORMAT_B5G5R5A1_UNORM
] = { R200_TXFORMAT_ARGB1555
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
110 [ MESA_FORMAT_A1R5G5B5_UNORM
] = { R200_TXFORMAT_ARGB1555
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
111 [ MESA_FORMAT_L8A8_UNORM
] = { R200_TXFORMAT_AL88
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
112 [ MESA_FORMAT_A8L8_UNORM
] = { R200_TXFORMAT_AL88
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
113 [ MESA_FORMAT_A_UNORM8
] = { R200_TXFORMAT_A8
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
114 [ MESA_FORMAT_L_UNORM8
] = { R200_TXFORMAT_L8
, 0 },
115 [ MESA_FORMAT_I_UNORM8
] = { R200_TXFORMAT_I8
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
116 [ MESA_FORMAT_YCBCR
] = { R200_TXFORMAT_YCBCR
, R200_YUV_TO_RGB
},
117 [ MESA_FORMAT_YCBCR_REV
] = { R200_TXFORMAT_YCBCR_REV
, R200_YUV_TO_RGB
},
118 [ MESA_FORMAT_RGB_FXT1
] = { 0xffffffff, 0 },
119 [ MESA_FORMAT_RGBA_FXT1
] = { 0xffffffff, 0 },
120 [ MESA_FORMAT_RGB_DXT1
] = { R200_TXFORMAT_RGB_DXT1
, 0 },
121 [ MESA_FORMAT_RGBA_DXT1
] = { R200_TXFORMAT_RGBA_DXT1
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
122 [ MESA_FORMAT_RGBA_DXT3
] = { R200_TXFORMAT_RGBA_DXT3
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
123 [ MESA_FORMAT_RGBA_DXT5
] = { R200_TXFORMAT_RGBA_DXT5
| R200_TXFORMAT_ALPHA_IN_MAP
, 0 },
126 /* ================================================================
127 * Texture combine functions
130 /* GL_ARB_texture_env_combine support
133 /* The color tables have combine functions for GL_SRC_COLOR,
134 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
136 static GLuint r200_register_color
[][R200_MAX_TEXTURE_UNITS
] =
139 R200_TXC_ARG_A_R0_COLOR
,
140 R200_TXC_ARG_A_R1_COLOR
,
141 R200_TXC_ARG_A_R2_COLOR
,
142 R200_TXC_ARG_A_R3_COLOR
,
143 R200_TXC_ARG_A_R4_COLOR
,
144 R200_TXC_ARG_A_R5_COLOR
147 R200_TXC_ARG_A_R0_COLOR
| R200_TXC_COMP_ARG_A
,
148 R200_TXC_ARG_A_R1_COLOR
| R200_TXC_COMP_ARG_A
,
149 R200_TXC_ARG_A_R2_COLOR
| R200_TXC_COMP_ARG_A
,
150 R200_TXC_ARG_A_R3_COLOR
| R200_TXC_COMP_ARG_A
,
151 R200_TXC_ARG_A_R4_COLOR
| R200_TXC_COMP_ARG_A
,
152 R200_TXC_ARG_A_R5_COLOR
| R200_TXC_COMP_ARG_A
155 R200_TXC_ARG_A_R0_ALPHA
,
156 R200_TXC_ARG_A_R1_ALPHA
,
157 R200_TXC_ARG_A_R2_ALPHA
,
158 R200_TXC_ARG_A_R3_ALPHA
,
159 R200_TXC_ARG_A_R4_ALPHA
,
160 R200_TXC_ARG_A_R5_ALPHA
163 R200_TXC_ARG_A_R0_ALPHA
| R200_TXC_COMP_ARG_A
,
164 R200_TXC_ARG_A_R1_ALPHA
| R200_TXC_COMP_ARG_A
,
165 R200_TXC_ARG_A_R2_ALPHA
| R200_TXC_COMP_ARG_A
,
166 R200_TXC_ARG_A_R3_ALPHA
| R200_TXC_COMP_ARG_A
,
167 R200_TXC_ARG_A_R4_ALPHA
| R200_TXC_COMP_ARG_A
,
168 R200_TXC_ARG_A_R5_ALPHA
| R200_TXC_COMP_ARG_A
172 static GLuint r200_tfactor_color
[] =
174 R200_TXC_ARG_A_TFACTOR_COLOR
,
175 R200_TXC_ARG_A_TFACTOR_COLOR
| R200_TXC_COMP_ARG_A
,
176 R200_TXC_ARG_A_TFACTOR_ALPHA
,
177 R200_TXC_ARG_A_TFACTOR_ALPHA
| R200_TXC_COMP_ARG_A
180 static GLuint r200_tfactor1_color
[] =
182 R200_TXC_ARG_A_TFACTOR1_COLOR
,
183 R200_TXC_ARG_A_TFACTOR1_COLOR
| R200_TXC_COMP_ARG_A
,
184 R200_TXC_ARG_A_TFACTOR1_ALPHA
,
185 R200_TXC_ARG_A_TFACTOR1_ALPHA
| R200_TXC_COMP_ARG_A
188 static GLuint r200_primary_color
[] =
190 R200_TXC_ARG_A_DIFFUSE_COLOR
,
191 R200_TXC_ARG_A_DIFFUSE_COLOR
| R200_TXC_COMP_ARG_A
,
192 R200_TXC_ARG_A_DIFFUSE_ALPHA
,
193 R200_TXC_ARG_A_DIFFUSE_ALPHA
| R200_TXC_COMP_ARG_A
196 /* GL_ZERO table - indices 0-3
197 * GL_ONE table - indices 1-4
199 static GLuint r200_zero_color
[] =
202 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
204 R200_TXC_ARG_A_ZERO
| R200_TXC_COMP_ARG_A
,
208 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
210 static GLuint r200_register_alpha
[][R200_MAX_TEXTURE_UNITS
] =
213 R200_TXA_ARG_A_R0_ALPHA
,
214 R200_TXA_ARG_A_R1_ALPHA
,
215 R200_TXA_ARG_A_R2_ALPHA
,
216 R200_TXA_ARG_A_R3_ALPHA
,
217 R200_TXA_ARG_A_R4_ALPHA
,
218 R200_TXA_ARG_A_R5_ALPHA
221 R200_TXA_ARG_A_R0_ALPHA
| R200_TXA_COMP_ARG_A
,
222 R200_TXA_ARG_A_R1_ALPHA
| R200_TXA_COMP_ARG_A
,
223 R200_TXA_ARG_A_R2_ALPHA
| R200_TXA_COMP_ARG_A
,
224 R200_TXA_ARG_A_R3_ALPHA
| R200_TXA_COMP_ARG_A
,
225 R200_TXA_ARG_A_R4_ALPHA
| R200_TXA_COMP_ARG_A
,
226 R200_TXA_ARG_A_R5_ALPHA
| R200_TXA_COMP_ARG_A
230 static GLuint r200_tfactor_alpha
[] =
232 R200_TXA_ARG_A_TFACTOR_ALPHA
,
233 R200_TXA_ARG_A_TFACTOR_ALPHA
| R200_TXA_COMP_ARG_A
236 static GLuint r200_tfactor1_alpha
[] =
238 R200_TXA_ARG_A_TFACTOR1_ALPHA
,
239 R200_TXA_ARG_A_TFACTOR1_ALPHA
| R200_TXA_COMP_ARG_A
242 static GLuint r200_primary_alpha
[] =
244 R200_TXA_ARG_A_DIFFUSE_ALPHA
,
245 R200_TXA_ARG_A_DIFFUSE_ALPHA
| R200_TXA_COMP_ARG_A
248 /* GL_ZERO table - indices 0-1
249 * GL_ONE table - indices 1-2
251 static GLuint r200_zero_alpha
[] =
254 R200_TXA_ARG_A_ZERO
| R200_TXA_COMP_ARG_A
,
259 /* Extract the arg from slot A, shift it into the correct argument slot
260 * and set the corresponding complement bit.
262 #define R200_COLOR_ARG( n, arg ) \
265 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
266 << R200_TXC_ARG_##arg##_SHIFT); \
268 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
269 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
272 #define R200_ALPHA_ARG( n, arg ) \
275 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
276 << R200_TXA_ARG_##arg##_SHIFT); \
278 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
279 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
283 /* ================================================================
284 * Texture unit state management
287 static GLboolean
r200UpdateTextureEnv( struct gl_context
*ctx
, int unit
, int slot
, GLuint replaceargs
)
289 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
290 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
291 GLuint color_combine
, alpha_combine
;
292 GLuint color_scale
= rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXCBLEND2
] &
293 ~(R200_TXC_SCALE_MASK
| R200_TXC_OUTPUT_REG_MASK
| R200_TXC_TFACTOR_SEL_MASK
|
294 R200_TXC_TFACTOR1_SEL_MASK
);
295 GLuint alpha_scale
= rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXABLEND2
] &
296 ~(R200_TXA_DOT_ALPHA
| R200_TXA_SCALE_MASK
| R200_TXA_OUTPUT_REG_MASK
|
297 R200_TXA_TFACTOR_SEL_MASK
| R200_TXA_TFACTOR1_SEL_MASK
);
299 /* texUnit->_Current can be NULL if and only if the texture unit is
300 * not actually enabled.
302 assert( (texUnit
->_ReallyEnabled
== 0)
303 || (texUnit
->_Current
!= NULL
) );
305 if ( R200_DEBUG
& RADEON_TEXTURE
) {
306 fprintf( stderr
, "%s( %p, %d )\n", __FUNCTION__
, (void *)ctx
, unit
);
309 /* Set the texture environment state. Isn't this nice and clean?
310 * The chip will automagically set the texture alpha to 0xff when
311 * the texture format does not include an alpha component. This
312 * reduces the amount of special-casing we have to do, alpha-only
313 * textures being a notable exception.
316 color_scale
|= ((rmesa
->state
.texture
.unit
[unit
].outputreg
+ 1) << R200_TXC_OUTPUT_REG_SHIFT
) |
317 (unit
<< R200_TXC_TFACTOR_SEL_SHIFT
) |
318 (replaceargs
<< R200_TXC_TFACTOR1_SEL_SHIFT
);
319 alpha_scale
|= ((rmesa
->state
.texture
.unit
[unit
].outputreg
+ 1) << R200_TXA_OUTPUT_REG_SHIFT
) |
320 (unit
<< R200_TXA_TFACTOR_SEL_SHIFT
) |
321 (replaceargs
<< R200_TXA_TFACTOR1_SEL_SHIFT
);
323 if ( !texUnit
->_ReallyEnabled
) {
325 color_combine
= R200_TXC_ARG_A_ZERO
| R200_TXC_ARG_B_ZERO
326 | R200_TXC_ARG_C_DIFFUSE_COLOR
| R200_TXC_OP_MADD
;
327 alpha_combine
= R200_TXA_ARG_A_ZERO
| R200_TXA_ARG_B_ZERO
328 | R200_TXA_ARG_C_DIFFUSE_ALPHA
| R200_TXA_OP_MADD
;
331 GLuint color_arg
[3], alpha_arg
[3];
333 const GLuint numColorArgs
= texUnit
->_CurrentCombine
->_NumArgsRGB
;
334 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
335 GLuint RGBshift
= texUnit
->_CurrentCombine
->ScaleShiftRGB
;
336 GLuint Ashift
= texUnit
->_CurrentCombine
->ScaleShiftA
;
339 const GLint replaceoprgb
=
340 ctx
->Texture
.Unit
[replaceargs
]._CurrentCombine
->OperandRGB
[0] - GL_SRC_COLOR
;
341 const GLint replaceopa
=
342 ctx
->Texture
.Unit
[replaceargs
]._CurrentCombine
->OperandA
[0] - GL_SRC_ALPHA
;
345 * Extract the color and alpha combine function arguments.
347 for ( i
= 0 ; i
< numColorArgs
; i
++ ) {
348 GLint op
= texUnit
->_CurrentCombine
->OperandRGB
[i
] - GL_SRC_COLOR
;
349 const GLint srcRGBi
= texUnit
->_CurrentCombine
->SourceRGB
[i
];
354 color_arg
[i
] = r200_register_color
[op
][unit
];
357 color_arg
[i
] = r200_tfactor_color
[op
];
359 case GL_PRIMARY_COLOR
:
360 color_arg
[i
] = r200_primary_color
[op
];
363 if (replaceargs
!= unit
) {
364 const GLint srcRGBreplace
=
365 ctx
->Texture
.Unit
[replaceargs
]._CurrentCombine
->SourceRGB
[0];
367 op
= op
^ replaceopa
;
370 op
= op
^ replaceoprgb
;
372 switch (srcRGBreplace
) {
374 color_arg
[i
] = r200_register_color
[op
][replaceargs
];
377 color_arg
[i
] = r200_tfactor1_color
[op
];
379 case GL_PRIMARY_COLOR
:
380 color_arg
[i
] = r200_primary_color
[op
];
384 color_arg
[i
] = r200_primary_color
[op
];
386 color_arg
[i
] = r200_register_color
[op
]
387 [rmesa
->state
.texture
.unit
[replaceargs
- 1].outputreg
];
390 color_arg
[i
] = r200_zero_color
[op
];
393 color_arg
[i
] = r200_zero_color
[op
+1];
401 color_arg
[i
] = r200_register_color
[op
][srcRGBreplace
- GL_TEXTURE0
];
409 color_arg
[i
] = r200_primary_color
[op
];
411 color_arg
[i
] = r200_register_color
[op
]
412 [rmesa
->state
.texture
.unit
[unit
- 1].outputreg
];
416 color_arg
[i
] = r200_zero_color
[op
];
419 color_arg
[i
] = r200_zero_color
[op
+1];
427 color_arg
[i
] = r200_register_color
[op
][srcRGBi
- GL_TEXTURE0
];
434 for ( i
= 0 ; i
< numAlphaArgs
; i
++ ) {
435 GLint op
= texUnit
->_CurrentCombine
->OperandA
[i
] - GL_SRC_ALPHA
;
436 const GLint srcAi
= texUnit
->_CurrentCombine
->SourceA
[i
];
441 alpha_arg
[i
] = r200_register_alpha
[op
][unit
];
444 alpha_arg
[i
] = r200_tfactor_alpha
[op
];
446 case GL_PRIMARY_COLOR
:
447 alpha_arg
[i
] = r200_primary_alpha
[op
];
450 if (replaceargs
!= unit
) {
451 const GLint srcAreplace
=
452 ctx
->Texture
.Unit
[replaceargs
]._CurrentCombine
->SourceA
[0];
453 op
= op
^ replaceopa
;
454 switch (srcAreplace
) {
456 alpha_arg
[i
] = r200_register_alpha
[op
][replaceargs
];
459 alpha_arg
[i
] = r200_tfactor1_alpha
[op
];
461 case GL_PRIMARY_COLOR
:
462 alpha_arg
[i
] = r200_primary_alpha
[op
];
466 alpha_arg
[i
] = r200_primary_alpha
[op
];
468 alpha_arg
[i
] = r200_register_alpha
[op
]
469 [rmesa
->state
.texture
.unit
[replaceargs
- 1].outputreg
];
472 alpha_arg
[i
] = r200_zero_alpha
[op
];
475 alpha_arg
[i
] = r200_zero_alpha
[op
+1];
483 alpha_arg
[i
] = r200_register_alpha
[op
][srcAreplace
- GL_TEXTURE0
];
491 alpha_arg
[i
] = r200_primary_alpha
[op
];
493 alpha_arg
[i
] = r200_register_alpha
[op
]
494 [rmesa
->state
.texture
.unit
[unit
- 1].outputreg
];
498 alpha_arg
[i
] = r200_zero_alpha
[op
];
501 alpha_arg
[i
] = r200_zero_alpha
[op
+1];
509 alpha_arg
[i
] = r200_register_alpha
[op
][srcAi
- GL_TEXTURE0
];
517 * Build up the color and alpha combine functions.
519 switch ( texUnit
->_CurrentCombine
->ModeRGB
) {
521 color_combine
= (R200_TXC_ARG_A_ZERO
|
522 R200_TXC_ARG_B_ZERO
|
524 R200_COLOR_ARG( 0, C
);
527 color_combine
= (R200_TXC_ARG_C_ZERO
|
529 R200_COLOR_ARG( 0, A
);
530 R200_COLOR_ARG( 1, B
);
533 color_combine
= (R200_TXC_ARG_B_ZERO
|
534 R200_TXC_COMP_ARG_B
|
536 R200_COLOR_ARG( 0, A
);
537 R200_COLOR_ARG( 1, C
);
540 color_combine
= (R200_TXC_ARG_B_ZERO
|
541 R200_TXC_COMP_ARG_B
|
542 R200_TXC_BIAS_ARG_C
| /* new */
543 R200_TXC_OP_MADD
); /* was ADDSIGNED */
544 R200_COLOR_ARG( 0, A
);
545 R200_COLOR_ARG( 1, C
);
548 color_combine
= (R200_TXC_ARG_B_ZERO
|
549 R200_TXC_COMP_ARG_B
|
552 R200_COLOR_ARG( 0, A
);
553 R200_COLOR_ARG( 1, C
);
556 color_combine
= (R200_TXC_OP_LERP
);
557 R200_COLOR_ARG( 0, B
);
558 R200_COLOR_ARG( 1, A
);
559 R200_COLOR_ARG( 2, C
);
562 case GL_DOT3_RGB_EXT
:
563 case GL_DOT3_RGBA_EXT
:
564 /* The EXT version of the DOT3 extension does not support the
565 * scale factor, but the ARB version (and the version in OpenGL
573 /* DOT3 works differently on R200 than on R100. On R100, just
574 * setting the DOT3 mode did everything for you. On R200, the
575 * driver has to enable the biasing and scale in the inputs to
576 * put them in the proper [-1,1] range. This is what the 4x and
577 * the -0.5 in the DOT3 spec do. The post-scale is then set
581 color_combine
= (R200_TXC_ARG_C_ZERO
|
583 R200_TXC_BIAS_ARG_A
|
584 R200_TXC_BIAS_ARG_B
|
585 R200_TXC_SCALE_ARG_A
|
586 R200_TXC_SCALE_ARG_B
);
587 R200_COLOR_ARG( 0, A
);
588 R200_COLOR_ARG( 1, B
);
591 case GL_MODULATE_ADD_ATI
:
592 color_combine
= (R200_TXC_OP_MADD
);
593 R200_COLOR_ARG( 0, A
);
594 R200_COLOR_ARG( 1, C
);
595 R200_COLOR_ARG( 2, B
);
597 case GL_MODULATE_SIGNED_ADD_ATI
:
598 color_combine
= (R200_TXC_BIAS_ARG_C
| /* new */
599 R200_TXC_OP_MADD
); /* was ADDSIGNED */
600 R200_COLOR_ARG( 0, A
);
601 R200_COLOR_ARG( 1, C
);
602 R200_COLOR_ARG( 2, B
);
604 case GL_MODULATE_SUBTRACT_ATI
:
605 color_combine
= (R200_TXC_NEG_ARG_C
|
607 R200_COLOR_ARG( 0, A
);
608 R200_COLOR_ARG( 1, C
);
609 R200_COLOR_ARG( 2, B
);
615 switch ( texUnit
->_CurrentCombine
->ModeA
) {
617 alpha_combine
= (R200_TXA_ARG_A_ZERO
|
618 R200_TXA_ARG_B_ZERO
|
620 R200_ALPHA_ARG( 0, C
);
623 alpha_combine
= (R200_TXA_ARG_C_ZERO
|
625 R200_ALPHA_ARG( 0, A
);
626 R200_ALPHA_ARG( 1, B
);
629 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
630 R200_TXA_COMP_ARG_B
|
632 R200_ALPHA_ARG( 0, A
);
633 R200_ALPHA_ARG( 1, C
);
636 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
637 R200_TXA_COMP_ARG_B
|
638 R200_TXA_BIAS_ARG_C
| /* new */
639 R200_TXA_OP_MADD
); /* was ADDSIGNED */
640 R200_ALPHA_ARG( 0, A
);
641 R200_ALPHA_ARG( 1, C
);
644 alpha_combine
= (R200_TXA_ARG_B_ZERO
|
645 R200_TXA_COMP_ARG_B
|
648 R200_ALPHA_ARG( 0, A
);
649 R200_ALPHA_ARG( 1, C
);
652 alpha_combine
= (R200_TXA_OP_LERP
);
653 R200_ALPHA_ARG( 0, B
);
654 R200_ALPHA_ARG( 1, A
);
655 R200_ALPHA_ARG( 2, C
);
658 case GL_MODULATE_ADD_ATI
:
659 alpha_combine
= (R200_TXA_OP_MADD
);
660 R200_ALPHA_ARG( 0, A
);
661 R200_ALPHA_ARG( 1, C
);
662 R200_ALPHA_ARG( 2, B
);
664 case GL_MODULATE_SIGNED_ADD_ATI
:
665 alpha_combine
= (R200_TXA_BIAS_ARG_C
| /* new */
666 R200_TXA_OP_MADD
); /* was ADDSIGNED */
667 R200_ALPHA_ARG( 0, A
);
668 R200_ALPHA_ARG( 1, C
);
669 R200_ALPHA_ARG( 2, B
);
671 case GL_MODULATE_SUBTRACT_ATI
:
672 alpha_combine
= (R200_TXA_NEG_ARG_C
|
674 R200_ALPHA_ARG( 0, A
);
675 R200_ALPHA_ARG( 1, C
);
676 R200_ALPHA_ARG( 2, B
);
682 if ( (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
)
683 || (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
) ) {
684 alpha_scale
|= R200_TXA_DOT_ALPHA
;
689 * Apply the scale factor.
691 color_scale
|= (RGBshift
<< R200_TXC_SCALE_SHIFT
);
692 alpha_scale
|= (Ashift
<< R200_TXA_SCALE_SHIFT
);
698 if ( rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXCBLEND
] != color_combine
||
699 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXABLEND
] != alpha_combine
||
700 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXCBLEND2
] != color_scale
||
701 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXABLEND2
] != alpha_scale
) {
702 R200_STATECHANGE( rmesa
, pix
[slot
] );
703 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXCBLEND
] = color_combine
;
704 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXABLEND
] = alpha_combine
;
705 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXCBLEND2
] = color_scale
;
706 rmesa
->hw
.pix
[slot
].cmd
[PIX_PP_TXABLEND2
] = alpha_scale
;
712 void r200SetTexBuffer2(__DRIcontext
*pDRICtx
, GLint target
, GLint texture_format
,
713 __DRIdrawable
*dPriv
)
715 struct gl_texture_object
*texObj
;
716 struct gl_texture_image
*texImage
;
717 struct radeon_renderbuffer
*rb
;
718 radeon_texture_image
*rImage
;
719 radeonContextPtr radeon
;
720 struct radeon_framebuffer
*rfb
;
723 mesa_format texFormat
;
725 radeon
= pDRICtx
->driverPrivate
;
727 rfb
= dPriv
->driverPrivate
;
728 texObj
= _mesa_get_current_tex_object(&radeon
->glCtx
, target
);
729 texImage
= _mesa_get_tex_image(&radeon
->glCtx
, texObj
, target
, 0);
731 rImage
= get_radeon_texture_image(texImage
);
732 t
= radeon_tex_obj(texObj
);
737 radeon_update_renderbuffers(pDRICtx
, dPriv
, GL_TRUE
);
738 rb
= rfb
->color_rb
[0];
739 if (rb
->bo
== NULL
) {
740 /* Failed to BO for the buffer */
744 _mesa_lock_texture(&radeon
->glCtx
, texObj
);
746 radeon_bo_unref(t
->bo
);
750 radeon_bo_unref(rImage
->bo
);
754 radeon_miptree_unreference(&t
->mt
);
755 radeon_miptree_unreference(&rImage
->mt
);
758 radeon_bo_ref(rImage
->bo
);
760 radeon_bo_ref(t
->bo
);
762 t
->image_override
= GL_TRUE
;
763 t
->override_offset
= 0;
764 t
->pp_txpitch
&= (1 << 13) -1;
765 pitch_val
= rb
->pitch
;
768 if (texture_format
== __DRI_TEXTURE_FORMAT_RGB
) {
769 texFormat
= MESA_FORMAT_BGR_UNORM8
;
770 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_BGR_UNORM8
].format
;
773 texFormat
= MESA_FORMAT_B8G8R8A8_UNORM
;
774 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_B8G8R8A8_UNORM
].format
;
776 t
->pp_txfilter
|= tx_table_le
[MESA_FORMAT_B8G8R8A8_UNORM
].filter
;
780 texFormat
= MESA_FORMAT_BGR_UNORM8
;
781 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_BGR_UNORM8
].format
;
782 t
->pp_txfilter
|= tx_table_le
[MESA_FORMAT_BGR_UNORM8
].filter
;
785 texFormat
= MESA_FORMAT_B5G6R5_UNORM
;
786 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_B5G6R5_UNORM
].format
;
787 t
->pp_txfilter
|= tx_table_le
[MESA_FORMAT_B5G6R5_UNORM
].filter
;
791 _mesa_init_teximage_fields(&radeon
->glCtx
, texImage
,
792 rb
->base
.Base
.Width
, rb
->base
.Base
.Height
,
795 rImage
->base
.RowStride
= rb
->pitch
/ rb
->cpp
;
798 t
->pp_txsize
= ((rb
->base
.Base
.Width
- 1) << RADEON_TEX_USIZE_SHIFT
)
799 | ((rb
->base
.Base
.Height
- 1) << RADEON_TEX_VSIZE_SHIFT
);
801 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
802 t
->pp_txformat
|= R200_TXFORMAT_NON_POWER2
;
803 t
->pp_txpitch
= pitch_val
;
806 t
->pp_txformat
&= ~(R200_TXFORMAT_WIDTH_MASK
|
807 R200_TXFORMAT_HEIGHT_MASK
|
808 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
809 R200_TXFORMAT_F5_WIDTH_MASK
|
810 R200_TXFORMAT_F5_HEIGHT_MASK
);
811 t
->pp_txformat
|= ((texImage
->WidthLog2
<< R200_TXFORMAT_WIDTH_SHIFT
) |
812 (texImage
->HeightLog2
<< R200_TXFORMAT_HEIGHT_SHIFT
));
815 t
->validated
= GL_TRUE
;
816 _mesa_unlock_texture(&radeon
->glCtx
, texObj
);
821 void r200SetTexBuffer(__DRIcontext
*pDRICtx
, GLint target
, __DRIdrawable
*dPriv
)
823 r200SetTexBuffer2(pDRICtx
, target
, __DRI_TEXTURE_FORMAT_RGBA
, dPriv
);
830 static GLboolean
r200UpdateAllTexEnv( struct gl_context
*ctx
)
832 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
833 GLint i
, j
, currslot
;
834 GLint maxunitused
= -1;
835 GLboolean texregfree
[6] = {GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
};
836 GLubyte stageref
[7] = {0, 0, 0, 0, 0, 0, 0};
837 GLint nextunit
[R200_MAX_TEXTURE_UNITS
] = {0, 0, 0, 0, 0, 0};
838 GLint currentnext
= -1;
841 /* find highest used unit */
842 for ( j
= 0; j
< R200_MAX_TEXTURE_UNITS
; j
++) {
843 if (ctx
->Texture
.Unit
[j
]._ReallyEnabled
) {
847 stageref
[maxunitused
+ 1] = REF_COLOR
| REF_ALPHA
;
849 for ( j
= maxunitused
; j
>= 0; j
-- ) {
850 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[j
];
852 rmesa
->state
.texture
.unit
[j
].outputreg
= -1;
854 if (stageref
[j
+ 1]) {
856 /* use the lowest available reg. That gets us automatically reg0 for the last stage.
857 need this even for disabled units, as it may get referenced due to the replace
859 for ( i
= 0 ; i
< R200_MAX_TEXTURE_UNITS
; i
++ ) {
861 rmesa
->state
.texture
.unit
[j
].outputreg
= i
;
865 if (rmesa
->state
.texture
.unit
[j
].outputreg
== -1) {
866 /* no more free regs we can use. Need a fallback :-( */
870 nextunit
[j
] = currentnext
;
872 if (!texUnit
->_ReallyEnabled
) {
873 /* the not enabled stages are referenced "indirectly",
874 must not cut off the lower stages */
875 stageref
[j
] = REF_COLOR
| REF_ALPHA
;
880 const GLuint numColorArgs
= texUnit
->_CurrentCombine
->_NumArgsRGB
;
881 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
882 const GLboolean isdot3rgba
= (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
) ||
883 (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
);
886 /* check if we need the color part, special case for dot3_rgba
887 as if only the alpha part is referenced later on it still is using the color part */
888 if ((stageref
[j
+ 1] & REF_COLOR
) || isdot3rgba
) {
889 for ( i
= 0 ; i
< numColorArgs
; i
++ ) {
890 const GLuint srcRGBi
= texUnit
->_CurrentCombine
->SourceRGB
[i
];
891 const GLuint op
= texUnit
->_CurrentCombine
->OperandRGB
[i
];
894 /* op 0/1 are referencing color, op 2/3 alpha */
895 stageref
[j
] |= (op
>> 1) + 1;
898 texregfree
[j
] = GL_FALSE
;
906 texregfree
[srcRGBi
- GL_TEXTURE0
] = GL_FALSE
;
908 default: /* don't care about other sources here */
914 /* alpha args are ignored for dot3_rgba */
915 if ((stageref
[j
+ 1] & REF_ALPHA
) && !isdot3rgba
) {
917 for ( i
= 0 ; i
< numAlphaArgs
; i
++ ) {
918 const GLuint srcAi
= texUnit
->_CurrentCombine
->SourceA
[i
];
921 stageref
[j
] |= REF_ALPHA
;
924 texregfree
[j
] = GL_FALSE
;
932 texregfree
[srcAi
- GL_TEXTURE0
] = GL_FALSE
;
934 default: /* don't care about other sources here */
942 /* don't enable texture sampling for units if the result is not used */
943 for (i
= 0; i
< R200_MAX_TEXTURE_UNITS
; i
++) {
944 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
&& !texregfree
[i
])
945 rmesa
->state
.texture
.unit
[i
].unitneeded
= ctx
->Texture
.Unit
[i
]._ReallyEnabled
;
946 else rmesa
->state
.texture
.unit
[i
].unitneeded
= 0;
951 rmesa
->state
.envneeded
= 1;
954 while ((i
<= maxunitused
) && (i
>= 0)) {
955 /* only output instruction if the results are referenced */
956 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
&& stageref
[i
+1]) {
957 GLuint replaceunit
= i
;
958 /* try to optimize GL_REPLACE away (only one level deep though) */
959 if ( (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ModeRGB
== GL_REPLACE
) &&
960 (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ModeA
== GL_REPLACE
) &&
961 (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ScaleShiftRGB
== 0) &&
962 (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ScaleShiftA
== 0) &&
963 (nextunit
[i
] > 0) ) {
964 /* yippie! can optimize it away! */
969 /* need env instruction slot */
970 rmesa
->state
.envneeded
|= 1 << currslot
;
971 ok
= r200UpdateTextureEnv( ctx
, i
, currslot
, replaceunit
);
972 if (!ok
) return GL_FALSE
;
979 /* need one stage at least */
980 rmesa
->state
.texture
.unit
[0].outputreg
= 0;
981 ok
= r200UpdateTextureEnv( ctx
, 0, 0, 0 );
984 R200_STATECHANGE( rmesa
, ctx
);
985 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~(R200_TEX_BLEND_ENABLE_MASK
| R200_MULTI_PASS_ENABLE
);
986 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= rmesa
->state
.envneeded
<< R200_TEX_BLEND_0_ENABLE_SHIFT
;
995 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
996 R200_MIN_FILTER_MASK | \
997 R200_MAG_FILTER_MASK | \
998 R200_MAX_ANISO_MASK | \
1000 R200_YUV_TEMPERATURE_MASK | \
1001 R200_CLAMP_S_MASK | \
1002 R200_CLAMP_T_MASK | \
1003 R200_BORDER_MODE_D3D )
1005 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
1006 R200_TXFORMAT_HEIGHT_MASK | \
1007 R200_TXFORMAT_FORMAT_MASK | \
1008 R200_TXFORMAT_F5_WIDTH_MASK | \
1009 R200_TXFORMAT_F5_HEIGHT_MASK | \
1010 R200_TXFORMAT_ALPHA_IN_MAP | \
1011 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
1012 R200_TXFORMAT_NON_POWER2)
1014 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
1015 R200_TEXCOORD_MASK | \
1016 R200_MIN_MIP_LEVEL_MASK | \
1017 R200_CLAMP_Q_MASK | \
1018 R200_VOLUME_FILTER_MASK)
1021 static void disable_tex_obj_state( r200ContextPtr rmesa
,
1025 R200_STATECHANGE( rmesa
, vtx
);
1026 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &= ~(7 << (unit
* 3));
1028 R200_STATECHANGE( rmesa
, ctx
);
1029 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~(R200_TEX_0_ENABLE
<< unit
);
1030 if (rmesa
->radeon
.TclFallback
& (R200_TCL_FALLBACK_TEXGEN_0
<<unit
)) {
1031 TCL_FALLBACK( &rmesa
->radeon
.glCtx
, (R200_TCL_FALLBACK_TEXGEN_0
<<unit
), GL_FALSE
);
1034 /* Actually want to keep all units less than max active texture
1035 * enabled, right? Fix this for >2 texunits.
1039 GLuint tmp
= rmesa
->TexGenEnabled
;
1041 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1042 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<<unit
);
1043 rmesa
->TexGenNeedNormals
[unit
] = GL_FALSE
;
1044 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1046 if (tmp
!= rmesa
->TexGenEnabled
) {
1047 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1048 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1052 static void import_tex_obj_state( r200ContextPtr rmesa
,
1054 radeonTexObjPtr texobj
)
1056 /* do not use RADEON_DB_STATE to avoid stale texture caches */
1057 GLuint
*cmd
= &rmesa
->hw
.tex
[unit
].cmd
[TEX_CMD_0
];
1059 R200_STATECHANGE( rmesa
, tex
[unit
] );
1061 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
1062 cmd
[TEX_PP_TXFILTER
] |= texobj
->pp_txfilter
& TEXOBJ_TXFILTER_MASK
;
1063 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1064 cmd
[TEX_PP_TXFORMAT
] |= texobj
->pp_txformat
& TEXOBJ_TXFORMAT_MASK
;
1065 cmd
[TEX_PP_TXFORMAT_X
] &= ~TEXOBJ_TXFORMAT_X_MASK
;
1066 cmd
[TEX_PP_TXFORMAT_X
] |= texobj
->pp_txformat_x
& TEXOBJ_TXFORMAT_X_MASK
;
1067 cmd
[TEX_PP_TXSIZE
] = texobj
->pp_txsize
; /* NPOT only! */
1068 cmd
[TEX_PP_TXPITCH
] = texobj
->pp_txpitch
; /* NPOT only! */
1069 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
1071 if (texobj
->base
.Target
== GL_TEXTURE_CUBE_MAP
) {
1072 GLuint
*cube_cmd
= &rmesa
->hw
.cube
[unit
].cmd
[CUBE_CMD_0
];
1074 R200_STATECHANGE( rmesa
, cube
[unit
] );
1075 cube_cmd
[CUBE_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
1076 /* that value is submitted twice. could change cube atom
1077 to not include that command when new drm is used */
1078 cmd
[TEX_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
1083 static void set_texgen_matrix( r200ContextPtr rmesa
,
1085 const GLfloat
*s_plane
,
1086 const GLfloat
*t_plane
,
1087 const GLfloat
*r_plane
,
1088 const GLfloat
*q_plane
)
1112 _math_matrix_loadf( &(rmesa
->TexGenMatrix
[unit
]), m
);
1113 _math_matrix_analyse( &(rmesa
->TexGenMatrix
[unit
]) );
1114 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<<unit
;
1118 static GLuint
r200_need_dis_texgen(const GLbitfield texGenEnabled
,
1119 const GLfloat
*planeS
,
1120 const GLfloat
*planeT
,
1121 const GLfloat
*planeR
,
1122 const GLfloat
*planeQ
)
1124 GLuint needtgenable
= 0;
1126 if (!(texGenEnabled
& S_BIT
)) {
1127 if (((texGenEnabled
& T_BIT
) && planeT
[0] != 0.0) ||
1128 ((texGenEnabled
& R_BIT
) && planeR
[0] != 0.0) ||
1129 ((texGenEnabled
& Q_BIT
) && planeQ
[0] != 0.0)) {
1130 needtgenable
|= S_BIT
;
1133 if (!(texGenEnabled
& T_BIT
)) {
1134 if (((texGenEnabled
& S_BIT
) && planeS
[1] != 0.0) ||
1135 ((texGenEnabled
& R_BIT
) && planeR
[1] != 0.0) ||
1136 ((texGenEnabled
& Q_BIT
) && planeQ
[1] != 0.0)) {
1137 needtgenable
|= T_BIT
;
1140 if (!(texGenEnabled
& R_BIT
)) {
1141 if (((texGenEnabled
& S_BIT
) && planeS
[2] != 0.0) ||
1142 ((texGenEnabled
& T_BIT
) && planeT
[2] != 0.0) ||
1143 ((texGenEnabled
& Q_BIT
) && planeQ
[2] != 0.0)) {
1144 needtgenable
|= R_BIT
;
1147 if (!(texGenEnabled
& Q_BIT
)) {
1148 if (((texGenEnabled
& S_BIT
) && planeS
[3] != 0.0) ||
1149 ((texGenEnabled
& T_BIT
) && planeT
[3] != 0.0) ||
1150 ((texGenEnabled
& R_BIT
) && planeR
[3] != 0.0)) {
1151 needtgenable
|= Q_BIT
;
1155 return needtgenable
;
1160 * Returns GL_FALSE if fallback required.
1162 static GLboolean
r200_validate_texgen( struct gl_context
*ctx
, GLuint unit
)
1164 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1165 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1166 GLuint inputshift
= R200_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1169 GLboolean mixed_fallback
= GL_FALSE
;
1170 static const GLfloat I
[16] = {
1175 static const GLfloat reflect
[16] = {
1181 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1182 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1183 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<<unit
);
1184 rmesa
->TexGenNeedNormals
[unit
] = GL_FALSE
;
1185 tgi
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] & ~(R200_TEXGEN_INPUT_MASK
<<
1187 tgcm
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_2
] & ~(R200_TEXGEN_COMP_MASK
<<
1191 fprintf(stderr
, "%s unit %d\n", __FUNCTION__
, unit
);
1193 if (texUnit
->TexGenEnabled
& S_BIT
) {
1194 mode
= texUnit
->GenS
.Mode
;
1196 tgcm
|= R200_TEXGEN_COMP_S
<< (unit
* 4);
1199 if (texUnit
->TexGenEnabled
& T_BIT
) {
1200 if (texUnit
->GenT
.Mode
!= mode
)
1201 mixed_fallback
= GL_TRUE
;
1203 tgcm
|= R200_TEXGEN_COMP_T
<< (unit
* 4);
1205 if (texUnit
->TexGenEnabled
& R_BIT
) {
1206 if (texUnit
->GenR
.Mode
!= mode
)
1207 mixed_fallback
= GL_TRUE
;
1209 tgcm
|= R200_TEXGEN_COMP_R
<< (unit
* 4);
1212 if (texUnit
->TexGenEnabled
& Q_BIT
) {
1213 if (texUnit
->GenQ
.Mode
!= mode
)
1214 mixed_fallback
= GL_TRUE
;
1216 tgcm
|= R200_TEXGEN_COMP_Q
<< (unit
* 4);
1219 if (mixed_fallback
) {
1220 if (R200_DEBUG
& RADEON_FALLBACKS
)
1221 fprintf(stderr
, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
1222 texUnit
->TexGenEnabled
, texUnit
->GenS
.Mode
, texUnit
->GenT
.Mode
,
1223 texUnit
->GenR
.Mode
, texUnit
->GenQ
.Mode
);
1227 /* we CANNOT do mixed mode if the texgen mode requires a plane where the input
1228 is not enabled for texgen, since the planes are concatenated into texmat,
1229 and thus the input will come from texcoord rather than tex gen equation!
1230 Either fallback or just hope that those texcoords aren't really needed...
1231 Assuming the former will cause lots of unnecessary fallbacks, the latter will
1232 generate bogus results sometimes - it's pretty much impossible to really know
1233 when a fallback is needed, depends on texmat and what sort of texture is bound
1234 etc, - for now fallback if we're missing either S or T bits, there's a high
1235 probability we need the texcoords in that case.
1236 That's a lot of work for some obscure texgen mixed mode fixup - why oh why
1237 doesn't the chip just directly accept the plane parameters :-(. */
1239 case GL_OBJECT_LINEAR
: {
1240 GLuint needtgenable
= r200_need_dis_texgen( texUnit
->TexGenEnabled
,
1241 texUnit
->GenS
.ObjectPlane
,
1242 texUnit
->GenT
.ObjectPlane
,
1243 texUnit
->GenR
.ObjectPlane
,
1244 texUnit
->GenQ
.ObjectPlane
);
1245 if (needtgenable
& (S_BIT
| T_BIT
)) {
1246 if (R200_DEBUG
& RADEON_FALLBACKS
)
1247 fprintf(stderr
, "fallback mixed texgen / obj plane, 0x%x\n",
1248 texUnit
->TexGenEnabled
);
1251 if (needtgenable
& (R_BIT
)) {
1252 tgcm
&= ~(R200_TEXGEN_COMP_R
<< (unit
* 4));
1254 if (needtgenable
& (Q_BIT
)) {
1255 tgcm
&= ~(R200_TEXGEN_COMP_Q
<< (unit
* 4));
1258 tgi
|= R200_TEXGEN_INPUT_OBJ
<< inputshift
;
1259 set_texgen_matrix( rmesa
, unit
,
1260 (texUnit
->TexGenEnabled
& S_BIT
) ? texUnit
->GenS
.ObjectPlane
: I
,
1261 (texUnit
->TexGenEnabled
& T_BIT
) ? texUnit
->GenT
.ObjectPlane
: I
+ 4,
1262 (texUnit
->TexGenEnabled
& R_BIT
) ? texUnit
->GenR
.ObjectPlane
: I
+ 8,
1263 (texUnit
->TexGenEnabled
& Q_BIT
) ? texUnit
->GenQ
.ObjectPlane
: I
+ 12);
1267 case GL_EYE_LINEAR
: {
1268 GLuint needtgenable
= r200_need_dis_texgen( texUnit
->TexGenEnabled
,
1269 texUnit
->GenS
.EyePlane
,
1270 texUnit
->GenT
.EyePlane
,
1271 texUnit
->GenR
.EyePlane
,
1272 texUnit
->GenQ
.EyePlane
);
1273 if (needtgenable
& (S_BIT
| T_BIT
)) {
1274 if (R200_DEBUG
& RADEON_FALLBACKS
)
1275 fprintf(stderr
, "fallback mixed texgen / eye plane, 0x%x\n",
1276 texUnit
->TexGenEnabled
);
1279 if (needtgenable
& (R_BIT
)) {
1280 tgcm
&= ~(R200_TEXGEN_COMP_R
<< (unit
* 4));
1282 if (needtgenable
& (Q_BIT
)) {
1283 tgcm
&= ~(R200_TEXGEN_COMP_Q
<< (unit
* 4));
1285 tgi
|= R200_TEXGEN_INPUT_EYE
<< inputshift
;
1286 set_texgen_matrix( rmesa
, unit
,
1287 (texUnit
->TexGenEnabled
& S_BIT
) ? texUnit
->GenS
.EyePlane
: I
,
1288 (texUnit
->TexGenEnabled
& T_BIT
) ? texUnit
->GenT
.EyePlane
: I
+ 4,
1289 (texUnit
->TexGenEnabled
& R_BIT
) ? texUnit
->GenR
.EyePlane
: I
+ 8,
1290 (texUnit
->TexGenEnabled
& Q_BIT
) ? texUnit
->GenQ
.EyePlane
: I
+ 12);
1294 case GL_REFLECTION_MAP_NV
:
1295 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1296 tgi
|= R200_TEXGEN_INPUT_EYE_REFLECT
<< inputshift
;
1297 /* pretty weird, must only negate when lighting is enabled? */
1298 if (ctx
->Light
.Enabled
)
1299 set_texgen_matrix( rmesa
, unit
,
1300 (texUnit
->TexGenEnabled
& S_BIT
) ? reflect
: I
,
1301 (texUnit
->TexGenEnabled
& T_BIT
) ? reflect
+ 4 : I
+ 4,
1302 (texUnit
->TexGenEnabled
& R_BIT
) ? reflect
+ 8 : I
+ 8,
1306 case GL_NORMAL_MAP_NV
:
1307 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1308 tgi
|= R200_TEXGEN_INPUT_EYE_NORMAL
<<inputshift
;
1312 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1313 tgi
|= R200_TEXGEN_INPUT_SPHERE
<<inputshift
;
1317 /* All texgen units were disabled, so just pass coords through. */
1318 tgi
|= unit
<< inputshift
;
1322 /* Unsupported mode, fallback:
1324 if (R200_DEBUG
& RADEON_FALLBACKS
)
1325 fprintf(stderr
, "fallback unsupported texgen, %d\n",
1326 texUnit
->GenS
.Mode
);
1330 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
1331 rmesa
->TexGenCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
1333 if (tgi
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] ||
1334 tgcm
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_2
])
1336 R200_STATECHANGE(rmesa
, tcg
);
1337 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] = tgi
;
1338 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_2
] = tgcm
;
1344 void set_re_cntl_d3d( struct gl_context
*ctx
, int unit
, GLboolean use_d3d
)
1346 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1350 re_cntl
= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] & ~(R200_VTX_STQ0_D3D
<< (2 * unit
));
1352 re_cntl
|= R200_VTX_STQ0_D3D
<< (2 * unit
);
1354 if ( re_cntl
!= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] ) {
1355 R200_STATECHANGE( rmesa
, set
);
1356 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] = re_cntl
;
1361 * Compute the cached hardware register values for the given texture object.
1363 * \param rmesa Context pointer
1364 * \param t the r300 texture object
1366 static void setup_hardware_state(r200ContextPtr rmesa
, radeonTexObj
*t
)
1368 const struct gl_texture_image
*firstImage
= t
->base
.Image
[0][t
->minLod
];
1369 GLint log2Width
, log2Height
, log2Depth
, texelBytes
;
1370 uint extra_size
= 0;
1376 log2Width
= firstImage
->WidthLog2
;
1377 log2Height
= firstImage
->HeightLog2
;
1378 log2Depth
= firstImage
->DepthLog2
;
1379 texelBytes
= _mesa_get_format_bytes(firstImage
->TexFormat
);
1381 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
1382 "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
1383 __func__
, rmesa
, t
, log2Width
, log2Height
,
1384 log2Depth
, texelBytes
, firstImage
->TexFormat
);
1386 if (!t
->image_override
) {
1387 if (VALID_FORMAT(firstImage
->TexFormat
)) {
1388 const struct tx_table
*table
= _mesa_little_endian() ? tx_table_le
:
1391 t
->pp_txformat
&= ~(R200_TXFORMAT_FORMAT_MASK
|
1392 R200_TXFORMAT_ALPHA_IN_MAP
);
1393 t
->pp_txfilter
&= ~R200_YUV_TO_RGB
;
1395 t
->pp_txformat
|= table
[ firstImage
->TexFormat
].format
;
1396 t
->pp_txfilter
|= table
[ firstImage
->TexFormat
].filter
;
1400 _mesa_problem(NULL
, "unexpected texture format in %s",
1406 t
->pp_txfilter
&= ~R200_MAX_MIP_LEVEL_MASK
;
1407 t
->pp_txfilter
|= ((t
->maxLod
) << R200_MAX_MIP_LEVEL_SHIFT
)
1408 & R200_MAX_MIP_LEVEL_MASK
;
1410 if ( t
->pp_txfilter
&
1411 (R200_MIN_FILTER_NEAREST_MIP_NEAREST
1412 | R200_MIN_FILTER_NEAREST_MIP_LINEAR
1413 | R200_MIN_FILTER_LINEAR_MIP_NEAREST
1414 | R200_MIN_FILTER_LINEAR_MIP_LINEAR
1415 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
1416 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR
))
1417 extra_size
= t
->minLod
;
1419 t
->pp_txformat
&= ~(R200_TXFORMAT_WIDTH_MASK
|
1420 R200_TXFORMAT_HEIGHT_MASK
|
1421 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
1422 R200_TXFORMAT_F5_WIDTH_MASK
|
1423 R200_TXFORMAT_F5_HEIGHT_MASK
);
1424 t
->pp_txformat
|= (((log2Width
+ extra_size
) << R200_TXFORMAT_WIDTH_SHIFT
) |
1425 ((log2Height
+ extra_size
)<< R200_TXFORMAT_HEIGHT_SHIFT
));
1429 t
->pp_txformat_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
1430 | R200_MIN_MIP_LEVEL_MASK
);
1432 t
->pp_txformat_x
|= (t
->minLod
<< R200_MIN_MIP_LEVEL_SHIFT
)
1433 & R200_MIN_MIP_LEVEL_MASK
;
1435 if (t
->base
.Target
== GL_TEXTURE_3D
) {
1436 t
->pp_txformat_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
1437 t
->pp_txformat_x
|= R200_TEXCOORD_VOLUME
;
1440 else if (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) {
1441 ASSERT(log2Width
== log2Height
);
1442 t
->pp_txformat
|= ((log2Width
<< R200_TXFORMAT_F5_WIDTH_SHIFT
) |
1443 (log2Height
<< R200_TXFORMAT_F5_HEIGHT_SHIFT
) |
1444 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1445 (R200_TXFORMAT_CUBIC_MAP_ENABLE
));
1446 t
->pp_txformat_x
|= R200_TEXCOORD_CUBIC_ENV
;
1447 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
1448 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
1449 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
1450 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
1451 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
1452 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
1453 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
1454 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
1457 /* If we don't in fact send enough texture coordinates, q will be 1,
1458 * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1460 t
->pp_txformat_x
|= R200_TEXCOORD_PROJ
;
1462 /* FIXME: NPOT sizes, Is it correct realy? */
1463 t
->pp_txsize
= (((firstImage
->Width
- 1) << R200_PP_TX_WIDTHMASK_SHIFT
)
1464 | ((firstImage
->Height
- 1) << R200_PP_TX_HEIGHTMASK_SHIFT
));
1466 if ( !t
->image_override
) {
1467 if (_mesa_is_format_compressed(firstImage
->TexFormat
))
1468 t
->pp_txpitch
= (firstImage
->Width
+ 63) & ~(63);
1470 t
->pp_txpitch
= ((firstImage
->Width
* texelBytes
) + 63) & ~(63);
1471 t
->pp_txpitch
-= 32;
1474 if (t
->base
.Target
== GL_TEXTURE_RECTANGLE_NV
) {
1475 t
->pp_txformat
|= R200_TXFORMAT_NON_POWER2
;
1480 static GLboolean
r200_validate_texture(struct gl_context
*ctx
, struct gl_texture_object
*texObj
, int unit
)
1482 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1483 radeonTexObj
*t
= radeon_tex_obj(texObj
);
1485 if (!radeon_validate_texture_miptree(ctx
, _mesa_get_samplerobj(ctx
, unit
), texObj
))
1488 r200_validate_texgen(ctx
, unit
);
1489 /* Configure the hardware registers (more precisely, the cached version
1490 * of the hardware registers). */
1491 setup_hardware_state(rmesa
, t
);
1493 if (texObj
->Target
== GL_TEXTURE_RECTANGLE_NV
||
1494 texObj
->Target
== GL_TEXTURE_2D
||
1495 texObj
->Target
== GL_TEXTURE_1D
)
1496 set_re_cntl_d3d( ctx
, unit
, GL_FALSE
);
1498 set_re_cntl_d3d( ctx
, unit
, GL_TRUE
);
1499 R200_STATECHANGE( rmesa
, ctx
);
1500 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_0_ENABLE
<< unit
;
1502 R200_STATECHANGE( rmesa
, vtx
);
1503 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &= ~(7 << (unit
* 3));
1504 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] |= 4 << (unit
* 3);
1506 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1507 r200TexUpdateParameters(ctx
, unit
);
1508 import_tex_obj_state( rmesa
, unit
, t
);
1510 if (rmesa
->recheck_texgen
[unit
]) {
1511 GLboolean fallback
= !r200_validate_texgen( ctx
, unit
);
1512 TCL_FALLBACK( ctx
, (R200_TCL_FALLBACK_TEXGEN_0
<<unit
), fallback
);
1513 rmesa
->recheck_texgen
[unit
] = 0;
1514 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1517 t
->validated
= GL_TRUE
;
1519 FALLBACK( rmesa
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1521 return !t
->border_fallback
;
1524 static GLboolean
r200UpdateTextureUnit(struct gl_context
*ctx
, int unit
)
1526 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1527 GLuint unitneeded
= rmesa
->state
.texture
.unit
[unit
].unitneeded
;
1530 /* disable the unit */
1531 disable_tex_obj_state(rmesa
, unit
);
1535 if (!r200_validate_texture(ctx
, ctx
->Texture
.Unit
[unit
]._Current
, unit
)) {
1537 "failed to validate texture for unit %d.\n",
1539 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
1543 rmesa
->state
.texture
.unit
[unit
].texobj
= radeon_tex_obj(ctx
->Texture
.Unit
[unit
]._Current
);
1548 void r200UpdateTextureState( struct gl_context
*ctx
)
1550 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1554 /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
1555 rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
1556 we use these to determine if we want to emit the corresponding state
1558 R200_NEWPRIM( rmesa
);
1560 if (ctx
->ATIFragmentShader
._Enabled
) {
1562 for (i
= 0; i
< R200_MAX_TEXTURE_UNITS
; i
++) {
1563 rmesa
->state
.texture
.unit
[i
].unitneeded
= ctx
->Texture
.Unit
[i
]._ReallyEnabled
;
1568 ok
= r200UpdateAllTexEnv( ctx
);
1571 ok
= (r200UpdateTextureUnit( ctx
, 0 ) &&
1572 r200UpdateTextureUnit( ctx
, 1 ) &&
1573 r200UpdateTextureUnit( ctx
, 2 ) &&
1574 r200UpdateTextureUnit( ctx
, 3 ) &&
1575 r200UpdateTextureUnit( ctx
, 4 ) &&
1576 r200UpdateTextureUnit( ctx
, 5 ));
1579 if (ok
&& ctx
->ATIFragmentShader
._Enabled
) {
1580 r200UpdateFragmentShader(ctx
);
1583 FALLBACK( rmesa
, R200_FALLBACK_TEXTURE
, !ok
);
1585 if (rmesa
->radeon
.TclFallback
)
1586 r200ChooseVertexState( ctx
);
1589 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R200
) {
1592 * T0 hang workaround -------------
1593 * not needed for r200 derivatives
1595 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_ENABLE_MASK
) == R200_TEX_0_ENABLE
&&
1596 (rmesa
->hw
.tex
[0].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) > R200_MIN_FILTER_LINEAR
) {
1598 R200_STATECHANGE(rmesa
, ctx
);
1599 R200_STATECHANGE(rmesa
, tex
[1]);
1600 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_1_ENABLE
;
1601 if (!(rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] & R200_PPX_TEX_1_ENABLE
))
1602 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1603 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] |= R200_TXFORMAT_LOOKUP_DISABLE
;
1605 else if (!ctx
->ATIFragmentShader
._Enabled
) {
1606 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
) &&
1607 (rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] & R200_TXFORMAT_LOOKUP_DISABLE
)) {
1608 R200_STATECHANGE(rmesa
, tex
[1]);
1609 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~R200_TXFORMAT_LOOKUP_DISABLE
;
1612 /* do the same workaround for the first pass of a fragment shader.
1613 * completely unknown if necessary / sufficient.
1615 if ((rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] & R200_PPX_TEX_ENABLE_MASK
) == R200_PPX_TEX_0_ENABLE
&&
1616 (rmesa
->hw
.tex
[0].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) > R200_MIN_FILTER_LINEAR
) {
1618 R200_STATECHANGE(rmesa
, cst
);
1619 R200_STATECHANGE(rmesa
, tex
[1]);
1620 rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] |= R200_PPX_TEX_1_ENABLE
;
1621 if (!(rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
))
1622 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1623 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXMULTI_CTL
] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE
;
1626 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1627 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1628 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1629 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1630 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1631 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1632 R200_MIN_FILTER_LINEAR)) {
1633 R200_STATECHANGE(rmesa, ctx);
1634 R200_STATECHANGE(rmesa, tex[i+1]);
1635 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1636 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1637 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1640 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1641 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1642 R200_STATECHANGE(rmesa, tex[i+1]);
1643 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1649 * Texture cache LRU hang workaround -------------
1650 * not needed for r200 derivatives
1651 * hopefully this covers first pass of a shader as well
1654 /* While the cases below attempt to only enable the workaround in the
1655 * specific cases necessary, they were insufficient. See bugzilla #1519,
1656 * #729, #814. Tests with quake3 showed no impact on performance.
1661 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
1662 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1664 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1665 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1667 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1668 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1674 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
1675 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1677 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1678 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1680 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1681 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1687 if (dbg
!= rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
]) {
1688 R200_STATECHANGE( rmesa
, tam
);
1689 rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
] = dbg
;
1690 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg
);