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_unit
*texUnit
;
716 struct gl_texture_object
*texObj
;
717 struct gl_texture_image
*texImage
;
718 struct radeon_renderbuffer
*rb
;
719 radeon_texture_image
*rImage
;
720 radeonContextPtr radeon
;
721 struct radeon_framebuffer
*rfb
;
724 mesa_format texFormat
;
726 radeon
= pDRICtx
->driverPrivate
;
728 rfb
= dPriv
->driverPrivate
;
729 texUnit
= &radeon
->glCtx
.Texture
.Unit
[radeon
->glCtx
.Texture
.CurrentUnit
];
730 texObj
= _mesa_select_tex_object(&radeon
->glCtx
, texUnit
, target
);
731 texImage
= _mesa_get_tex_image(&radeon
->glCtx
, texObj
, target
, 0);
733 rImage
= get_radeon_texture_image(texImage
);
734 t
= radeon_tex_obj(texObj
);
739 radeon_update_renderbuffers(pDRICtx
, dPriv
, GL_TRUE
);
740 rb
= rfb
->color_rb
[0];
741 if (rb
->bo
== NULL
) {
742 /* Failed to BO for the buffer */
746 _mesa_lock_texture(&radeon
->glCtx
, texObj
);
748 radeon_bo_unref(t
->bo
);
752 radeon_bo_unref(rImage
->bo
);
756 radeon_miptree_unreference(&t
->mt
);
757 radeon_miptree_unreference(&rImage
->mt
);
760 radeon_bo_ref(rImage
->bo
);
762 radeon_bo_ref(t
->bo
);
764 t
->image_override
= GL_TRUE
;
765 t
->override_offset
= 0;
766 t
->pp_txpitch
&= (1 << 13) -1;
767 pitch_val
= rb
->pitch
;
770 if (texture_format
== __DRI_TEXTURE_FORMAT_RGB
) {
771 texFormat
= MESA_FORMAT_BGR_UNORM8
;
772 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_BGR_UNORM8
].format
;
775 texFormat
= MESA_FORMAT_B8G8R8A8_UNORM
;
776 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_B8G8R8A8_UNORM
].format
;
778 t
->pp_txfilter
|= tx_table_le
[MESA_FORMAT_B8G8R8A8_UNORM
].filter
;
782 texFormat
= MESA_FORMAT_BGR_UNORM8
;
783 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_BGR_UNORM8
].format
;
784 t
->pp_txfilter
|= tx_table_le
[MESA_FORMAT_BGR_UNORM8
].filter
;
787 texFormat
= MESA_FORMAT_B5G6R5_UNORM
;
788 t
->pp_txformat
= tx_table_le
[MESA_FORMAT_B5G6R5_UNORM
].format
;
789 t
->pp_txfilter
|= tx_table_le
[MESA_FORMAT_B5G6R5_UNORM
].filter
;
793 _mesa_init_teximage_fields(&radeon
->glCtx
, texImage
,
794 rb
->base
.Base
.Width
, rb
->base
.Base
.Height
,
797 rImage
->base
.RowStride
= rb
->pitch
/ rb
->cpp
;
800 t
->pp_txsize
= ((rb
->base
.Base
.Width
- 1) << RADEON_TEX_USIZE_SHIFT
)
801 | ((rb
->base
.Base
.Height
- 1) << RADEON_TEX_VSIZE_SHIFT
);
803 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
804 t
->pp_txformat
|= R200_TXFORMAT_NON_POWER2
;
805 t
->pp_txpitch
= pitch_val
;
808 t
->pp_txformat
&= ~(R200_TXFORMAT_WIDTH_MASK
|
809 R200_TXFORMAT_HEIGHT_MASK
|
810 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
811 R200_TXFORMAT_F5_WIDTH_MASK
|
812 R200_TXFORMAT_F5_HEIGHT_MASK
);
813 t
->pp_txformat
|= ((texImage
->WidthLog2
<< R200_TXFORMAT_WIDTH_SHIFT
) |
814 (texImage
->HeightLog2
<< R200_TXFORMAT_HEIGHT_SHIFT
));
817 t
->validated
= GL_TRUE
;
818 _mesa_unlock_texture(&radeon
->glCtx
, texObj
);
823 void r200SetTexBuffer(__DRIcontext
*pDRICtx
, GLint target
, __DRIdrawable
*dPriv
)
825 r200SetTexBuffer2(pDRICtx
, target
, __DRI_TEXTURE_FORMAT_RGBA
, dPriv
);
832 static GLboolean
r200UpdateAllTexEnv( struct gl_context
*ctx
)
834 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
835 GLint i
, j
, currslot
;
836 GLint maxunitused
= -1;
837 GLboolean texregfree
[6] = {GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
};
838 GLubyte stageref
[7] = {0, 0, 0, 0, 0, 0, 0};
839 GLint nextunit
[R200_MAX_TEXTURE_UNITS
] = {0, 0, 0, 0, 0, 0};
840 GLint currentnext
= -1;
843 /* find highest used unit */
844 for ( j
= 0; j
< R200_MAX_TEXTURE_UNITS
; j
++) {
845 if (ctx
->Texture
.Unit
[j
]._ReallyEnabled
) {
849 stageref
[maxunitused
+ 1] = REF_COLOR
| REF_ALPHA
;
851 for ( j
= maxunitused
; j
>= 0; j
-- ) {
852 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[j
];
854 rmesa
->state
.texture
.unit
[j
].outputreg
= -1;
856 if (stageref
[j
+ 1]) {
858 /* use the lowest available reg. That gets us automatically reg0 for the last stage.
859 need this even for disabled units, as it may get referenced due to the replace
861 for ( i
= 0 ; i
< R200_MAX_TEXTURE_UNITS
; i
++ ) {
863 rmesa
->state
.texture
.unit
[j
].outputreg
= i
;
867 if (rmesa
->state
.texture
.unit
[j
].outputreg
== -1) {
868 /* no more free regs we can use. Need a fallback :-( */
872 nextunit
[j
] = currentnext
;
874 if (!texUnit
->_ReallyEnabled
) {
875 /* the not enabled stages are referenced "indirectly",
876 must not cut off the lower stages */
877 stageref
[j
] = REF_COLOR
| REF_ALPHA
;
882 const GLuint numColorArgs
= texUnit
->_CurrentCombine
->_NumArgsRGB
;
883 const GLuint numAlphaArgs
= texUnit
->_CurrentCombine
->_NumArgsA
;
884 const GLboolean isdot3rgba
= (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA
) ||
885 (texUnit
->_CurrentCombine
->ModeRGB
== GL_DOT3_RGBA_EXT
);
888 /* check if we need the color part, special case for dot3_rgba
889 as if only the alpha part is referenced later on it still is using the color part */
890 if ((stageref
[j
+ 1] & REF_COLOR
) || isdot3rgba
) {
891 for ( i
= 0 ; i
< numColorArgs
; i
++ ) {
892 const GLuint srcRGBi
= texUnit
->_CurrentCombine
->SourceRGB
[i
];
893 const GLuint op
= texUnit
->_CurrentCombine
->OperandRGB
[i
];
896 /* op 0/1 are referencing color, op 2/3 alpha */
897 stageref
[j
] |= (op
>> 1) + 1;
900 texregfree
[j
] = GL_FALSE
;
908 texregfree
[srcRGBi
- GL_TEXTURE0
] = GL_FALSE
;
910 default: /* don't care about other sources here */
916 /* alpha args are ignored for dot3_rgba */
917 if ((stageref
[j
+ 1] & REF_ALPHA
) && !isdot3rgba
) {
919 for ( i
= 0 ; i
< numAlphaArgs
; i
++ ) {
920 const GLuint srcAi
= texUnit
->_CurrentCombine
->SourceA
[i
];
923 stageref
[j
] |= REF_ALPHA
;
926 texregfree
[j
] = GL_FALSE
;
934 texregfree
[srcAi
- GL_TEXTURE0
] = GL_FALSE
;
936 default: /* don't care about other sources here */
944 /* don't enable texture sampling for units if the result is not used */
945 for (i
= 0; i
< R200_MAX_TEXTURE_UNITS
; i
++) {
946 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
&& !texregfree
[i
])
947 rmesa
->state
.texture
.unit
[i
].unitneeded
= ctx
->Texture
.Unit
[i
]._ReallyEnabled
;
948 else rmesa
->state
.texture
.unit
[i
].unitneeded
= 0;
953 rmesa
->state
.envneeded
= 1;
956 while ((i
<= maxunitused
) && (i
>= 0)) {
957 /* only output instruction if the results are referenced */
958 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
&& stageref
[i
+1]) {
959 GLuint replaceunit
= i
;
960 /* try to optimize GL_REPLACE away (only one level deep though) */
961 if ( (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ModeRGB
== GL_REPLACE
) &&
962 (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ModeA
== GL_REPLACE
) &&
963 (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ScaleShiftRGB
== 0) &&
964 (ctx
->Texture
.Unit
[i
]._CurrentCombine
->ScaleShiftA
== 0) &&
965 (nextunit
[i
] > 0) ) {
966 /* yippie! can optimize it away! */
971 /* need env instruction slot */
972 rmesa
->state
.envneeded
|= 1 << currslot
;
973 ok
= r200UpdateTextureEnv( ctx
, i
, currslot
, replaceunit
);
974 if (!ok
) return GL_FALSE
;
981 /* need one stage at least */
982 rmesa
->state
.texture
.unit
[0].outputreg
= 0;
983 ok
= r200UpdateTextureEnv( ctx
, 0, 0, 0 );
986 R200_STATECHANGE( rmesa
, ctx
);
987 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~(R200_TEX_BLEND_ENABLE_MASK
| R200_MULTI_PASS_ENABLE
);
988 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= rmesa
->state
.envneeded
<< R200_TEX_BLEND_0_ENABLE_SHIFT
;
997 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
998 R200_MIN_FILTER_MASK | \
999 R200_MAG_FILTER_MASK | \
1000 R200_MAX_ANISO_MASK | \
1002 R200_YUV_TEMPERATURE_MASK | \
1003 R200_CLAMP_S_MASK | \
1004 R200_CLAMP_T_MASK | \
1005 R200_BORDER_MODE_D3D )
1007 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
1008 R200_TXFORMAT_HEIGHT_MASK | \
1009 R200_TXFORMAT_FORMAT_MASK | \
1010 R200_TXFORMAT_F5_WIDTH_MASK | \
1011 R200_TXFORMAT_F5_HEIGHT_MASK | \
1012 R200_TXFORMAT_ALPHA_IN_MAP | \
1013 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
1014 R200_TXFORMAT_NON_POWER2)
1016 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
1017 R200_TEXCOORD_MASK | \
1018 R200_MIN_MIP_LEVEL_MASK | \
1019 R200_CLAMP_Q_MASK | \
1020 R200_VOLUME_FILTER_MASK)
1023 static void disable_tex_obj_state( r200ContextPtr rmesa
,
1027 R200_STATECHANGE( rmesa
, vtx
);
1028 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &= ~(7 << (unit
* 3));
1030 R200_STATECHANGE( rmesa
, ctx
);
1031 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] &= ~(R200_TEX_0_ENABLE
<< unit
);
1032 if (rmesa
->radeon
.TclFallback
& (R200_TCL_FALLBACK_TEXGEN_0
<<unit
)) {
1033 TCL_FALLBACK( &rmesa
->radeon
.glCtx
, (R200_TCL_FALLBACK_TEXGEN_0
<<unit
), GL_FALSE
);
1036 /* Actually want to keep all units less than max active texture
1037 * enabled, right? Fix this for >2 texunits.
1041 GLuint tmp
= rmesa
->TexGenEnabled
;
1043 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1044 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<<unit
);
1045 rmesa
->TexGenNeedNormals
[unit
] = GL_FALSE
;
1046 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1048 if (tmp
!= rmesa
->TexGenEnabled
) {
1049 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1050 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1054 static void import_tex_obj_state( r200ContextPtr rmesa
,
1056 radeonTexObjPtr texobj
)
1058 /* do not use RADEON_DB_STATE to avoid stale texture caches */
1059 GLuint
*cmd
= &rmesa
->hw
.tex
[unit
].cmd
[TEX_CMD_0
];
1061 R200_STATECHANGE( rmesa
, tex
[unit
] );
1063 cmd
[TEX_PP_TXFILTER
] &= ~TEXOBJ_TXFILTER_MASK
;
1064 cmd
[TEX_PP_TXFILTER
] |= texobj
->pp_txfilter
& TEXOBJ_TXFILTER_MASK
;
1065 cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1066 cmd
[TEX_PP_TXFORMAT
] |= texobj
->pp_txformat
& TEXOBJ_TXFORMAT_MASK
;
1067 cmd
[TEX_PP_TXFORMAT_X
] &= ~TEXOBJ_TXFORMAT_X_MASK
;
1068 cmd
[TEX_PP_TXFORMAT_X
] |= texobj
->pp_txformat_x
& TEXOBJ_TXFORMAT_X_MASK
;
1069 cmd
[TEX_PP_TXSIZE
] = texobj
->pp_txsize
; /* NPOT only! */
1070 cmd
[TEX_PP_TXPITCH
] = texobj
->pp_txpitch
; /* NPOT only! */
1071 cmd
[TEX_PP_BORDER_COLOR
] = texobj
->pp_border_color
;
1073 if (texobj
->base
.Target
== GL_TEXTURE_CUBE_MAP
) {
1074 GLuint
*cube_cmd
= &rmesa
->hw
.cube
[unit
].cmd
[CUBE_CMD_0
];
1076 R200_STATECHANGE( rmesa
, cube
[unit
] );
1077 cube_cmd
[CUBE_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
1078 /* that value is submitted twice. could change cube atom
1079 to not include that command when new drm is used */
1080 cmd
[TEX_PP_CUBIC_FACES
] = texobj
->pp_cubic_faces
;
1085 static void set_texgen_matrix( r200ContextPtr rmesa
,
1087 const GLfloat
*s_plane
,
1088 const GLfloat
*t_plane
,
1089 const GLfloat
*r_plane
,
1090 const GLfloat
*q_plane
)
1114 _math_matrix_loadf( &(rmesa
->TexGenMatrix
[unit
]), m
);
1115 _math_matrix_analyse( &(rmesa
->TexGenMatrix
[unit
]) );
1116 rmesa
->TexGenEnabled
|= R200_TEXMAT_0_ENABLE
<<unit
;
1120 static GLuint
r200_need_dis_texgen(const GLbitfield texGenEnabled
,
1121 const GLfloat
*planeS
,
1122 const GLfloat
*planeT
,
1123 const GLfloat
*planeR
,
1124 const GLfloat
*planeQ
)
1126 GLuint needtgenable
= 0;
1128 if (!(texGenEnabled
& S_BIT
)) {
1129 if (((texGenEnabled
& T_BIT
) && planeT
[0] != 0.0) ||
1130 ((texGenEnabled
& R_BIT
) && planeR
[0] != 0.0) ||
1131 ((texGenEnabled
& Q_BIT
) && planeQ
[0] != 0.0)) {
1132 needtgenable
|= S_BIT
;
1135 if (!(texGenEnabled
& T_BIT
)) {
1136 if (((texGenEnabled
& S_BIT
) && planeS
[1] != 0.0) ||
1137 ((texGenEnabled
& R_BIT
) && planeR
[1] != 0.0) ||
1138 ((texGenEnabled
& Q_BIT
) && planeQ
[1] != 0.0)) {
1139 needtgenable
|= T_BIT
;
1142 if (!(texGenEnabled
& R_BIT
)) {
1143 if (((texGenEnabled
& S_BIT
) && planeS
[2] != 0.0) ||
1144 ((texGenEnabled
& T_BIT
) && planeT
[2] != 0.0) ||
1145 ((texGenEnabled
& Q_BIT
) && planeQ
[2] != 0.0)) {
1146 needtgenable
|= R_BIT
;
1149 if (!(texGenEnabled
& Q_BIT
)) {
1150 if (((texGenEnabled
& S_BIT
) && planeS
[3] != 0.0) ||
1151 ((texGenEnabled
& T_BIT
) && planeT
[3] != 0.0) ||
1152 ((texGenEnabled
& R_BIT
) && planeR
[3] != 0.0)) {
1153 needtgenable
|= Q_BIT
;
1157 return needtgenable
;
1162 * Returns GL_FALSE if fallback required.
1164 static GLboolean
r200_validate_texgen( struct gl_context
*ctx
, GLuint unit
)
1166 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1167 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1168 GLuint inputshift
= R200_TEXGEN_0_INPUT_SHIFT
+ unit
*4;
1171 GLboolean mixed_fallback
= GL_FALSE
;
1172 static const GLfloat I
[16] = {
1177 static const GLfloat reflect
[16] = {
1183 rmesa
->TexGenCompSel
&= ~(R200_OUTPUT_TEX_0
<< unit
);
1184 rmesa
->TexGenEnabled
&= ~(R200_TEXGEN_TEXMAT_0_ENABLE
<<unit
);
1185 rmesa
->TexGenEnabled
&= ~(R200_TEXMAT_0_ENABLE
<<unit
);
1186 rmesa
->TexGenNeedNormals
[unit
] = GL_FALSE
;
1187 tgi
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] & ~(R200_TEXGEN_INPUT_MASK
<<
1189 tgcm
= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_2
] & ~(R200_TEXGEN_COMP_MASK
<<
1193 fprintf(stderr
, "%s unit %d\n", __FUNCTION__
, unit
);
1195 if (texUnit
->TexGenEnabled
& S_BIT
) {
1196 mode
= texUnit
->GenS
.Mode
;
1198 tgcm
|= R200_TEXGEN_COMP_S
<< (unit
* 4);
1201 if (texUnit
->TexGenEnabled
& T_BIT
) {
1202 if (texUnit
->GenT
.Mode
!= mode
)
1203 mixed_fallback
= GL_TRUE
;
1205 tgcm
|= R200_TEXGEN_COMP_T
<< (unit
* 4);
1207 if (texUnit
->TexGenEnabled
& R_BIT
) {
1208 if (texUnit
->GenR
.Mode
!= mode
)
1209 mixed_fallback
= GL_TRUE
;
1211 tgcm
|= R200_TEXGEN_COMP_R
<< (unit
* 4);
1214 if (texUnit
->TexGenEnabled
& Q_BIT
) {
1215 if (texUnit
->GenQ
.Mode
!= mode
)
1216 mixed_fallback
= GL_TRUE
;
1218 tgcm
|= R200_TEXGEN_COMP_Q
<< (unit
* 4);
1221 if (mixed_fallback
) {
1222 if (R200_DEBUG
& RADEON_FALLBACKS
)
1223 fprintf(stderr
, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
1224 texUnit
->TexGenEnabled
, texUnit
->GenS
.Mode
, texUnit
->GenT
.Mode
,
1225 texUnit
->GenR
.Mode
, texUnit
->GenQ
.Mode
);
1229 /* we CANNOT do mixed mode if the texgen mode requires a plane where the input
1230 is not enabled for texgen, since the planes are concatenated into texmat,
1231 and thus the input will come from texcoord rather than tex gen equation!
1232 Either fallback or just hope that those texcoords aren't really needed...
1233 Assuming the former will cause lots of unnecessary fallbacks, the latter will
1234 generate bogus results sometimes - it's pretty much impossible to really know
1235 when a fallback is needed, depends on texmat and what sort of texture is bound
1236 etc, - for now fallback if we're missing either S or T bits, there's a high
1237 probability we need the texcoords in that case.
1238 That's a lot of work for some obscure texgen mixed mode fixup - why oh why
1239 doesn't the chip just directly accept the plane parameters :-(. */
1241 case GL_OBJECT_LINEAR
: {
1242 GLuint needtgenable
= r200_need_dis_texgen( texUnit
->TexGenEnabled
,
1243 texUnit
->GenS
.ObjectPlane
,
1244 texUnit
->GenT
.ObjectPlane
,
1245 texUnit
->GenR
.ObjectPlane
,
1246 texUnit
->GenQ
.ObjectPlane
);
1247 if (needtgenable
& (S_BIT
| T_BIT
)) {
1248 if (R200_DEBUG
& RADEON_FALLBACKS
)
1249 fprintf(stderr
, "fallback mixed texgen / obj plane, 0x%x\n",
1250 texUnit
->TexGenEnabled
);
1253 if (needtgenable
& (R_BIT
)) {
1254 tgcm
&= ~(R200_TEXGEN_COMP_R
<< (unit
* 4));
1256 if (needtgenable
& (Q_BIT
)) {
1257 tgcm
&= ~(R200_TEXGEN_COMP_Q
<< (unit
* 4));
1260 tgi
|= R200_TEXGEN_INPUT_OBJ
<< inputshift
;
1261 set_texgen_matrix( rmesa
, unit
,
1262 (texUnit
->TexGenEnabled
& S_BIT
) ? texUnit
->GenS
.ObjectPlane
: I
,
1263 (texUnit
->TexGenEnabled
& T_BIT
) ? texUnit
->GenT
.ObjectPlane
: I
+ 4,
1264 (texUnit
->TexGenEnabled
& R_BIT
) ? texUnit
->GenR
.ObjectPlane
: I
+ 8,
1265 (texUnit
->TexGenEnabled
& Q_BIT
) ? texUnit
->GenQ
.ObjectPlane
: I
+ 12);
1269 case GL_EYE_LINEAR
: {
1270 GLuint needtgenable
= r200_need_dis_texgen( texUnit
->TexGenEnabled
,
1271 texUnit
->GenS
.EyePlane
,
1272 texUnit
->GenT
.EyePlane
,
1273 texUnit
->GenR
.EyePlane
,
1274 texUnit
->GenQ
.EyePlane
);
1275 if (needtgenable
& (S_BIT
| T_BIT
)) {
1276 if (R200_DEBUG
& RADEON_FALLBACKS
)
1277 fprintf(stderr
, "fallback mixed texgen / eye plane, 0x%x\n",
1278 texUnit
->TexGenEnabled
);
1281 if (needtgenable
& (R_BIT
)) {
1282 tgcm
&= ~(R200_TEXGEN_COMP_R
<< (unit
* 4));
1284 if (needtgenable
& (Q_BIT
)) {
1285 tgcm
&= ~(R200_TEXGEN_COMP_Q
<< (unit
* 4));
1287 tgi
|= R200_TEXGEN_INPUT_EYE
<< inputshift
;
1288 set_texgen_matrix( rmesa
, unit
,
1289 (texUnit
->TexGenEnabled
& S_BIT
) ? texUnit
->GenS
.EyePlane
: I
,
1290 (texUnit
->TexGenEnabled
& T_BIT
) ? texUnit
->GenT
.EyePlane
: I
+ 4,
1291 (texUnit
->TexGenEnabled
& R_BIT
) ? texUnit
->GenR
.EyePlane
: I
+ 8,
1292 (texUnit
->TexGenEnabled
& Q_BIT
) ? texUnit
->GenQ
.EyePlane
: I
+ 12);
1296 case GL_REFLECTION_MAP_NV
:
1297 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1298 tgi
|= R200_TEXGEN_INPUT_EYE_REFLECT
<< inputshift
;
1299 /* pretty weird, must only negate when lighting is enabled? */
1300 if (ctx
->Light
.Enabled
)
1301 set_texgen_matrix( rmesa
, unit
,
1302 (texUnit
->TexGenEnabled
& S_BIT
) ? reflect
: I
,
1303 (texUnit
->TexGenEnabled
& T_BIT
) ? reflect
+ 4 : I
+ 4,
1304 (texUnit
->TexGenEnabled
& R_BIT
) ? reflect
+ 8 : I
+ 8,
1308 case GL_NORMAL_MAP_NV
:
1309 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1310 tgi
|= R200_TEXGEN_INPUT_EYE_NORMAL
<<inputshift
;
1314 rmesa
->TexGenNeedNormals
[unit
] = GL_TRUE
;
1315 tgi
|= R200_TEXGEN_INPUT_SPHERE
<<inputshift
;
1319 /* All texgen units were disabled, so just pass coords through. */
1320 tgi
|= unit
<< inputshift
;
1324 /* Unsupported mode, fallback:
1326 if (R200_DEBUG
& RADEON_FALLBACKS
)
1327 fprintf(stderr
, "fallback unsupported texgen, %d\n",
1328 texUnit
->GenS
.Mode
);
1332 rmesa
->TexGenEnabled
|= R200_TEXGEN_TEXMAT_0_ENABLE
<< unit
;
1333 rmesa
->TexGenCompSel
|= R200_OUTPUT_TEX_0
<< unit
;
1335 if (tgi
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] ||
1336 tgcm
!= rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_2
])
1338 R200_STATECHANGE(rmesa
, tcg
);
1339 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_1
] = tgi
;
1340 rmesa
->hw
.tcg
.cmd
[TCG_TEX_PROC_CTL_2
] = tgcm
;
1346 void set_re_cntl_d3d( struct gl_context
*ctx
, int unit
, GLboolean use_d3d
)
1348 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1352 re_cntl
= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] & ~(R200_VTX_STQ0_D3D
<< (2 * unit
));
1354 re_cntl
|= R200_VTX_STQ0_D3D
<< (2 * unit
);
1356 if ( re_cntl
!= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] ) {
1357 R200_STATECHANGE( rmesa
, set
);
1358 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] = re_cntl
;
1363 * Compute the cached hardware register values for the given texture object.
1365 * \param rmesa Context pointer
1366 * \param t the r300 texture object
1368 static void setup_hardware_state(r200ContextPtr rmesa
, radeonTexObj
*t
)
1370 const struct gl_texture_image
*firstImage
= t
->base
.Image
[0][t
->minLod
];
1371 GLint log2Width
, log2Height
, log2Depth
, texelBytes
;
1372 uint extra_size
= 0;
1378 log2Width
= firstImage
->WidthLog2
;
1379 log2Height
= firstImage
->HeightLog2
;
1380 log2Depth
= firstImage
->DepthLog2
;
1381 texelBytes
= _mesa_get_format_bytes(firstImage
->TexFormat
);
1383 radeon_print(RADEON_TEXTURE
, RADEON_TRACE
,
1384 "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
1385 __func__
, rmesa
, t
, log2Width
, log2Height
,
1386 log2Depth
, texelBytes
, firstImage
->TexFormat
);
1388 if (!t
->image_override
) {
1389 if (VALID_FORMAT(firstImage
->TexFormat
)) {
1390 const struct tx_table
*table
= _mesa_little_endian() ? tx_table_le
:
1393 t
->pp_txformat
&= ~(R200_TXFORMAT_FORMAT_MASK
|
1394 R200_TXFORMAT_ALPHA_IN_MAP
);
1395 t
->pp_txfilter
&= ~R200_YUV_TO_RGB
;
1397 t
->pp_txformat
|= table
[ firstImage
->TexFormat
].format
;
1398 t
->pp_txfilter
|= table
[ firstImage
->TexFormat
].filter
;
1402 _mesa_problem(NULL
, "unexpected texture format in %s",
1408 t
->pp_txfilter
&= ~R200_MAX_MIP_LEVEL_MASK
;
1409 t
->pp_txfilter
|= ((t
->maxLod
) << R200_MAX_MIP_LEVEL_SHIFT
)
1410 & R200_MAX_MIP_LEVEL_MASK
;
1412 if ( t
->pp_txfilter
&
1413 (R200_MIN_FILTER_NEAREST_MIP_NEAREST
1414 | R200_MIN_FILTER_NEAREST_MIP_LINEAR
1415 | R200_MIN_FILTER_LINEAR_MIP_NEAREST
1416 | R200_MIN_FILTER_LINEAR_MIP_LINEAR
1417 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
1418 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR
))
1419 extra_size
= t
->minLod
;
1421 t
->pp_txformat
&= ~(R200_TXFORMAT_WIDTH_MASK
|
1422 R200_TXFORMAT_HEIGHT_MASK
|
1423 R200_TXFORMAT_CUBIC_MAP_ENABLE
|
1424 R200_TXFORMAT_F5_WIDTH_MASK
|
1425 R200_TXFORMAT_F5_HEIGHT_MASK
);
1426 t
->pp_txformat
|= (((log2Width
+ extra_size
) << R200_TXFORMAT_WIDTH_SHIFT
) |
1427 ((log2Height
+ extra_size
)<< R200_TXFORMAT_HEIGHT_SHIFT
));
1431 t
->pp_txformat_x
&= ~(R200_DEPTH_LOG2_MASK
| R200_TEXCOORD_MASK
1432 | R200_MIN_MIP_LEVEL_MASK
);
1434 t
->pp_txformat_x
|= (t
->minLod
<< R200_MIN_MIP_LEVEL_SHIFT
)
1435 & R200_MIN_MIP_LEVEL_MASK
;
1437 if (t
->base
.Target
== GL_TEXTURE_3D
) {
1438 t
->pp_txformat_x
|= (log2Depth
<< R200_DEPTH_LOG2_SHIFT
);
1439 t
->pp_txformat_x
|= R200_TEXCOORD_VOLUME
;
1442 else if (t
->base
.Target
== GL_TEXTURE_CUBE_MAP
) {
1443 ASSERT(log2Width
== log2Height
);
1444 t
->pp_txformat
|= ((log2Width
<< R200_TXFORMAT_F5_WIDTH_SHIFT
) |
1445 (log2Height
<< R200_TXFORMAT_F5_HEIGHT_SHIFT
) |
1446 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1447 (R200_TXFORMAT_CUBIC_MAP_ENABLE
));
1448 t
->pp_txformat_x
|= R200_TEXCOORD_CUBIC_ENV
;
1449 t
->pp_cubic_faces
= ((log2Width
<< R200_FACE_WIDTH_1_SHIFT
) |
1450 (log2Height
<< R200_FACE_HEIGHT_1_SHIFT
) |
1451 (log2Width
<< R200_FACE_WIDTH_2_SHIFT
) |
1452 (log2Height
<< R200_FACE_HEIGHT_2_SHIFT
) |
1453 (log2Width
<< R200_FACE_WIDTH_3_SHIFT
) |
1454 (log2Height
<< R200_FACE_HEIGHT_3_SHIFT
) |
1455 (log2Width
<< R200_FACE_WIDTH_4_SHIFT
) |
1456 (log2Height
<< R200_FACE_HEIGHT_4_SHIFT
));
1459 /* If we don't in fact send enough texture coordinates, q will be 1,
1460 * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1462 t
->pp_txformat_x
|= R200_TEXCOORD_PROJ
;
1464 /* FIXME: NPOT sizes, Is it correct realy? */
1465 t
->pp_txsize
= (((firstImage
->Width
- 1) << R200_PP_TX_WIDTHMASK_SHIFT
)
1466 | ((firstImage
->Height
- 1) << R200_PP_TX_HEIGHTMASK_SHIFT
));
1468 if ( !t
->image_override
) {
1469 if (_mesa_is_format_compressed(firstImage
->TexFormat
))
1470 t
->pp_txpitch
= (firstImage
->Width
+ 63) & ~(63);
1472 t
->pp_txpitch
= ((firstImage
->Width
* texelBytes
) + 63) & ~(63);
1473 t
->pp_txpitch
-= 32;
1476 if (t
->base
.Target
== GL_TEXTURE_RECTANGLE_NV
) {
1477 t
->pp_txformat
|= R200_TXFORMAT_NON_POWER2
;
1482 static GLboolean
r200_validate_texture(struct gl_context
*ctx
, struct gl_texture_object
*texObj
, int unit
)
1484 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1485 radeonTexObj
*t
= radeon_tex_obj(texObj
);
1487 if (!radeon_validate_texture_miptree(ctx
, _mesa_get_samplerobj(ctx
, unit
), texObj
))
1490 r200_validate_texgen(ctx
, unit
);
1491 /* Configure the hardware registers (more precisely, the cached version
1492 * of the hardware registers). */
1493 setup_hardware_state(rmesa
, t
);
1495 if (texObj
->Target
== GL_TEXTURE_RECTANGLE_NV
||
1496 texObj
->Target
== GL_TEXTURE_2D
||
1497 texObj
->Target
== GL_TEXTURE_1D
)
1498 set_re_cntl_d3d( ctx
, unit
, GL_FALSE
);
1500 set_re_cntl_d3d( ctx
, unit
, GL_TRUE
);
1501 R200_STATECHANGE( rmesa
, ctx
);
1502 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_0_ENABLE
<< unit
;
1504 R200_STATECHANGE( rmesa
, vtx
);
1505 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] &= ~(7 << (unit
* 3));
1506 rmesa
->hw
.vtx
.cmd
[VTX_TCL_OUTPUT_VTXFMT_1
] |= 4 << (unit
* 3);
1508 rmesa
->recheck_texgen
[unit
] = GL_TRUE
;
1509 r200TexUpdateParameters(ctx
, unit
);
1510 import_tex_obj_state( rmesa
, unit
, t
);
1512 if (rmesa
->recheck_texgen
[unit
]) {
1513 GLboolean fallback
= !r200_validate_texgen( ctx
, unit
);
1514 TCL_FALLBACK( ctx
, (R200_TCL_FALLBACK_TEXGEN_0
<<unit
), fallback
);
1515 rmesa
->recheck_texgen
[unit
] = 0;
1516 rmesa
->radeon
.NewGLState
|= _NEW_TEXTURE_MATRIX
;
1519 t
->validated
= GL_TRUE
;
1521 FALLBACK( rmesa
, RADEON_FALLBACK_BORDER_MODE
, t
->border_fallback
);
1523 return !t
->border_fallback
;
1526 static GLboolean
r200UpdateTextureUnit(struct gl_context
*ctx
, int unit
)
1528 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1529 GLuint unitneeded
= rmesa
->state
.texture
.unit
[unit
].unitneeded
;
1532 /* disable the unit */
1533 disable_tex_obj_state(rmesa
, unit
);
1537 if (!r200_validate_texture(ctx
, ctx
->Texture
.Unit
[unit
]._Current
, unit
)) {
1539 "failed to validate texture for unit %d.\n",
1541 rmesa
->state
.texture
.unit
[unit
].texobj
= NULL
;
1545 rmesa
->state
.texture
.unit
[unit
].texobj
= radeon_tex_obj(ctx
->Texture
.Unit
[unit
]._Current
);
1550 void r200UpdateTextureState( struct gl_context
*ctx
)
1552 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1556 /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
1557 rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
1558 we use these to determine if we want to emit the corresponding state
1560 R200_NEWPRIM( rmesa
);
1562 if (ctx
->ATIFragmentShader
._Enabled
) {
1564 for (i
= 0; i
< R200_MAX_TEXTURE_UNITS
; i
++) {
1565 rmesa
->state
.texture
.unit
[i
].unitneeded
= ctx
->Texture
.Unit
[i
]._ReallyEnabled
;
1570 ok
= r200UpdateAllTexEnv( ctx
);
1573 ok
= (r200UpdateTextureUnit( ctx
, 0 ) &&
1574 r200UpdateTextureUnit( ctx
, 1 ) &&
1575 r200UpdateTextureUnit( ctx
, 2 ) &&
1576 r200UpdateTextureUnit( ctx
, 3 ) &&
1577 r200UpdateTextureUnit( ctx
, 4 ) &&
1578 r200UpdateTextureUnit( ctx
, 5 ));
1581 if (ok
&& ctx
->ATIFragmentShader
._Enabled
) {
1582 r200UpdateFragmentShader(ctx
);
1585 FALLBACK( rmesa
, R200_FALLBACK_TEXTURE
, !ok
);
1587 if (rmesa
->radeon
.TclFallback
)
1588 r200ChooseVertexState( ctx
);
1591 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R200
) {
1594 * T0 hang workaround -------------
1595 * not needed for r200 derivatives
1597 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_ENABLE_MASK
) == R200_TEX_0_ENABLE
&&
1598 (rmesa
->hw
.tex
[0].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) > R200_MIN_FILTER_LINEAR
) {
1600 R200_STATECHANGE(rmesa
, ctx
);
1601 R200_STATECHANGE(rmesa
, tex
[1]);
1602 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_1_ENABLE
;
1603 if (!(rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] & R200_PPX_TEX_1_ENABLE
))
1604 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1605 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] |= R200_TXFORMAT_LOOKUP_DISABLE
;
1607 else if (!ctx
->ATIFragmentShader
._Enabled
) {
1608 if ((rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
) &&
1609 (rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] & R200_TXFORMAT_LOOKUP_DISABLE
)) {
1610 R200_STATECHANGE(rmesa
, tex
[1]);
1611 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~R200_TXFORMAT_LOOKUP_DISABLE
;
1614 /* do the same workaround for the first pass of a fragment shader.
1615 * completely unknown if necessary / sufficient.
1617 if ((rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] & R200_PPX_TEX_ENABLE_MASK
) == R200_PPX_TEX_0_ENABLE
&&
1618 (rmesa
->hw
.tex
[0].cmd
[TEX_PP_TXFILTER
] & R200_MIN_FILTER_MASK
) > R200_MIN_FILTER_LINEAR
) {
1620 R200_STATECHANGE(rmesa
, cst
);
1621 R200_STATECHANGE(rmesa
, tex
[1]);
1622 rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] |= R200_PPX_TEX_1_ENABLE
;
1623 if (!(rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] & R200_TEX_1_ENABLE
))
1624 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXFORMAT
] &= ~TEXOBJ_TXFORMAT_MASK
;
1625 rmesa
->hw
.tex
[1].cmd
[TEX_PP_TXMULTI_CTL
] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE
;
1628 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1629 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1630 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1631 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1632 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1633 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1634 R200_MIN_FILTER_LINEAR)) {
1635 R200_STATECHANGE(rmesa, ctx);
1636 R200_STATECHANGE(rmesa, tex[i+1]);
1637 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1638 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1639 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1642 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1643 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1644 R200_STATECHANGE(rmesa, tex[i+1]);
1645 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1651 * Texture cache LRU hang workaround -------------
1652 * not needed for r200 derivatives
1653 * hopefully this covers first pass of a shader as well
1656 /* While the cases below attempt to only enable the workaround in the
1657 * specific cases necessary, they were insufficient. See bugzilla #1519,
1658 * #729, #814. Tests with quake3 showed no impact on performance.
1663 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
1664 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1666 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1667 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1669 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1670 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1676 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
1677 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1679 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1680 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1682 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1683 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1689 if (dbg
!= rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
]) {
1690 R200_STATECHANGE( rmesa
, tam
);
1691 rmesa
->hw
.tam
.cmd
[TAM_DEBUG3
] = dbg
;
1692 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg
);