s/Tungsten Graphics/VMware/
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texstate.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Keith Whitwell <keithw@vmware.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/context.h"
38 #include "main/macros.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
41 #include "main/enums.h"
42
43 #include "radeon_common.h"
44 #include "radeon_mipmap_tree.h"
45 #include "r200_context.h"
46 #include "r200_state.h"
47 #include "r200_ioctl.h"
48 #include "r200_swtcl.h"
49 #include "r200_tex.h"
50 #include "r200_tcl.h"
51
52
53 #define R200_TXFORMAT_A8 R200_TXFORMAT_I8
54 #define R200_TXFORMAT_L8 R200_TXFORMAT_I8
55 #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88
56 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422
57 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
58 #define R200_TXFORMAT_RGB_DXT1 R200_TXFORMAT_DXT1
59 #define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
60 #define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
61 #define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
62
63 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
64 && (tx_table_be[f].format != 0xffffffff) )
65
66 struct tx_table {
67 GLuint format, filter;
68 };
69
70 static const struct tx_table tx_table_be[] =
71 {
72 [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
73 [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_RGBA8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
74 [ MESA_FORMAT_ARGB8888 ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
75 [ MESA_FORMAT_ARGB8888_REV ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
76 [ MESA_FORMAT_RGB888 ] = { 0xffffffff, 0 },
77 [ MESA_FORMAT_RGB565 ] = { R200_TXFORMAT_RGB565, 0 },
78 [ MESA_FORMAT_RGB565_REV ] = { R200_TXFORMAT_RGB565, 0 },
79 [ MESA_FORMAT_ARGB4444 ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
80 [ MESA_FORMAT_ARGB4444_REV ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
81 [ MESA_FORMAT_ARGB1555 ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
82 [ MESA_FORMAT_ARGB1555_REV ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
83 [ MESA_FORMAT_AL88 ] = { R200_TXFORMAT_AL88 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
84 [ MESA_FORMAT_AL88_REV ] = { R200_TXFORMAT_AL88 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
85 [ MESA_FORMAT_A8 ] = { R200_TXFORMAT_A8 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
86 [ MESA_FORMAT_L8 ] = { R200_TXFORMAT_L8, 0 },
87 [ MESA_FORMAT_I8 ] = { 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 },
96 };
97
98 static const struct tx_table tx_table_le[] =
99 {
100 [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_RGBA8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
101 [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
102 [ MESA_FORMAT_ARGB8888 ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
103 [ MESA_FORMAT_ARGB8888_REV ] = { R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
104 [ MESA_FORMAT_RGB888 ] = { R200_TXFORMAT_ARGB8888, 0 },
105 [ MESA_FORMAT_RGB565 ] = { R200_TXFORMAT_RGB565, 0 },
106 [ MESA_FORMAT_RGB565_REV ] = { R200_TXFORMAT_RGB565, 0 },
107 [ MESA_FORMAT_ARGB4444 ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
108 [ MESA_FORMAT_ARGB4444_REV ] = { R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
109 [ MESA_FORMAT_ARGB1555 ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
110 [ MESA_FORMAT_ARGB1555_REV ] = { R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
111 [ MESA_FORMAT_AL88 ] = { R200_TXFORMAT_AL88 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
112 [ MESA_FORMAT_AL88_REV ] = { R200_TXFORMAT_AL88 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
113 [ MESA_FORMAT_A8 ] = { R200_TXFORMAT_A8 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
114 [ MESA_FORMAT_L8 ] = { R200_TXFORMAT_L8, 0 },
115 [ MESA_FORMAT_I8 ] = { 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 },
124 };
125
126 /* ================================================================
127 * Texture combine functions
128 */
129
130 /* GL_ARB_texture_env_combine support
131 */
132
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.
135 */
136 static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] =
137 {
138 {
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
145 },
146 {
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
153 },
154 {
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
161 },
162 {
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
169 },
170 };
171
172 static GLuint r200_tfactor_color[] =
173 {
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
178 };
179
180 static GLuint r200_tfactor1_color[] =
181 {
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
186 };
187
188 static GLuint r200_primary_color[] =
189 {
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
194 };
195
196 /* GL_ZERO table - indices 0-3
197 * GL_ONE table - indices 1-4
198 */
199 static GLuint r200_zero_color[] =
200 {
201 R200_TXC_ARG_A_ZERO,
202 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
203 R200_TXC_ARG_A_ZERO,
204 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
205 R200_TXC_ARG_A_ZERO
206 };
207
208 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
209 */
210 static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] =
211 {
212 {
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
219 },
220 {
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
227 },
228 };
229
230 static GLuint r200_tfactor_alpha[] =
231 {
232 R200_TXA_ARG_A_TFACTOR_ALPHA,
233 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
234 };
235
236 static GLuint r200_tfactor1_alpha[] =
237 {
238 R200_TXA_ARG_A_TFACTOR1_ALPHA,
239 R200_TXA_ARG_A_TFACTOR1_ALPHA | R200_TXA_COMP_ARG_A
240 };
241
242 static GLuint r200_primary_alpha[] =
243 {
244 R200_TXA_ARG_A_DIFFUSE_ALPHA,
245 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
246 };
247
248 /* GL_ZERO table - indices 0-1
249 * GL_ONE table - indices 1-2
250 */
251 static GLuint r200_zero_alpha[] =
252 {
253 R200_TXA_ARG_A_ZERO,
254 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
255 R200_TXA_ARG_A_ZERO,
256 };
257
258
259 /* Extract the arg from slot A, shift it into the correct argument slot
260 * and set the corresponding complement bit.
261 */
262 #define R200_COLOR_ARG( n, arg ) \
263 do { \
264 color_combine |= \
265 ((color_arg[n] & R200_TXC_ARG_A_MASK) \
266 << R200_TXC_ARG_##arg##_SHIFT); \
267 color_combine |= \
268 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \
269 << R200_TXC_COMP_ARG_##arg##_SHIFT); \
270 } while (0)
271
272 #define R200_ALPHA_ARG( n, arg ) \
273 do { \
274 alpha_combine |= \
275 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \
276 << R200_TXA_ARG_##arg##_SHIFT); \
277 alpha_combine |= \
278 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \
279 << R200_TXA_COMP_ARG_##arg##_SHIFT); \
280 } while (0)
281
282
283 /* ================================================================
284 * Texture unit state management
285 */
286
287 static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs )
288 {
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);
298
299 /* texUnit->_Current can be NULL if and only if the texture unit is
300 * not actually enabled.
301 */
302 assert( (texUnit->_ReallyEnabled == 0)
303 || (texUnit->_Current != NULL) );
304
305 if ( R200_DEBUG & RADEON_TEXTURE ) {
306 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
307 }
308
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.
314 */
315
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);
322
323 if ( !texUnit->_ReallyEnabled ) {
324 assert( unit == 0);
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;
329 }
330 else {
331 GLuint color_arg[3], alpha_arg[3];
332 GLuint i;
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;
337
338
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;
343
344 /* Step 1:
345 * Extract the color and alpha combine function arguments.
346 */
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];
350 assert(op >= 0);
351 assert(op <= 3);
352 switch ( srcRGBi ) {
353 case GL_TEXTURE:
354 color_arg[i] = r200_register_color[op][unit];
355 break;
356 case GL_CONSTANT:
357 color_arg[i] = r200_tfactor_color[op];
358 break;
359 case GL_PRIMARY_COLOR:
360 color_arg[i] = r200_primary_color[op];
361 break;
362 case GL_PREVIOUS:
363 if (replaceargs != unit) {
364 const GLint srcRGBreplace =
365 ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceRGB[0];
366 if (op >= 2) {
367 op = op ^ replaceopa;
368 }
369 else {
370 op = op ^ replaceoprgb;
371 }
372 switch (srcRGBreplace) {
373 case GL_TEXTURE:
374 color_arg[i] = r200_register_color[op][replaceargs];
375 break;
376 case GL_CONSTANT:
377 color_arg[i] = r200_tfactor1_color[op];
378 break;
379 case GL_PRIMARY_COLOR:
380 color_arg[i] = r200_primary_color[op];
381 break;
382 case GL_PREVIOUS:
383 if (slot == 0)
384 color_arg[i] = r200_primary_color[op];
385 else
386 color_arg[i] = r200_register_color[op]
387 [rmesa->state.texture.unit[replaceargs - 1].outputreg];
388 break;
389 case GL_ZERO:
390 color_arg[i] = r200_zero_color[op];
391 break;
392 case GL_ONE:
393 color_arg[i] = r200_zero_color[op+1];
394 break;
395 case GL_TEXTURE0:
396 case GL_TEXTURE1:
397 case GL_TEXTURE2:
398 case GL_TEXTURE3:
399 case GL_TEXTURE4:
400 case GL_TEXTURE5:
401 color_arg[i] = r200_register_color[op][srcRGBreplace - GL_TEXTURE0];
402 break;
403 default:
404 return GL_FALSE;
405 }
406 }
407 else {
408 if (slot == 0)
409 color_arg[i] = r200_primary_color[op];
410 else
411 color_arg[i] = r200_register_color[op]
412 [rmesa->state.texture.unit[unit - 1].outputreg];
413 }
414 break;
415 case GL_ZERO:
416 color_arg[i] = r200_zero_color[op];
417 break;
418 case GL_ONE:
419 color_arg[i] = r200_zero_color[op+1];
420 break;
421 case GL_TEXTURE0:
422 case GL_TEXTURE1:
423 case GL_TEXTURE2:
424 case GL_TEXTURE3:
425 case GL_TEXTURE4:
426 case GL_TEXTURE5:
427 color_arg[i] = r200_register_color[op][srcRGBi - GL_TEXTURE0];
428 break;
429 default:
430 return GL_FALSE;
431 }
432 }
433
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];
437 assert(op >= 0);
438 assert(op <= 1);
439 switch ( srcAi ) {
440 case GL_TEXTURE:
441 alpha_arg[i] = r200_register_alpha[op][unit];
442 break;
443 case GL_CONSTANT:
444 alpha_arg[i] = r200_tfactor_alpha[op];
445 break;
446 case GL_PRIMARY_COLOR:
447 alpha_arg[i] = r200_primary_alpha[op];
448 break;
449 case GL_PREVIOUS:
450 if (replaceargs != unit) {
451 const GLint srcAreplace =
452 ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceA[0];
453 op = op ^ replaceopa;
454 switch (srcAreplace) {
455 case GL_TEXTURE:
456 alpha_arg[i] = r200_register_alpha[op][replaceargs];
457 break;
458 case GL_CONSTANT:
459 alpha_arg[i] = r200_tfactor1_alpha[op];
460 break;
461 case GL_PRIMARY_COLOR:
462 alpha_arg[i] = r200_primary_alpha[op];
463 break;
464 case GL_PREVIOUS:
465 if (slot == 0)
466 alpha_arg[i] = r200_primary_alpha[op];
467 else
468 alpha_arg[i] = r200_register_alpha[op]
469 [rmesa->state.texture.unit[replaceargs - 1].outputreg];
470 break;
471 case GL_ZERO:
472 alpha_arg[i] = r200_zero_alpha[op];
473 break;
474 case GL_ONE:
475 alpha_arg[i] = r200_zero_alpha[op+1];
476 break;
477 case GL_TEXTURE0:
478 case GL_TEXTURE1:
479 case GL_TEXTURE2:
480 case GL_TEXTURE3:
481 case GL_TEXTURE4:
482 case GL_TEXTURE5:
483 alpha_arg[i] = r200_register_alpha[op][srcAreplace - GL_TEXTURE0];
484 break;
485 default:
486 return GL_FALSE;
487 }
488 }
489 else {
490 if (slot == 0)
491 alpha_arg[i] = r200_primary_alpha[op];
492 else
493 alpha_arg[i] = r200_register_alpha[op]
494 [rmesa->state.texture.unit[unit - 1].outputreg];
495 }
496 break;
497 case GL_ZERO:
498 alpha_arg[i] = r200_zero_alpha[op];
499 break;
500 case GL_ONE:
501 alpha_arg[i] = r200_zero_alpha[op+1];
502 break;
503 case GL_TEXTURE0:
504 case GL_TEXTURE1:
505 case GL_TEXTURE2:
506 case GL_TEXTURE3:
507 case GL_TEXTURE4:
508 case GL_TEXTURE5:
509 alpha_arg[i] = r200_register_alpha[op][srcAi - GL_TEXTURE0];
510 break;
511 default:
512 return GL_FALSE;
513 }
514 }
515
516 /* Step 2:
517 * Build up the color and alpha combine functions.
518 */
519 switch ( texUnit->_CurrentCombine->ModeRGB ) {
520 case GL_REPLACE:
521 color_combine = (R200_TXC_ARG_A_ZERO |
522 R200_TXC_ARG_B_ZERO |
523 R200_TXC_OP_MADD);
524 R200_COLOR_ARG( 0, C );
525 break;
526 case GL_MODULATE:
527 color_combine = (R200_TXC_ARG_C_ZERO |
528 R200_TXC_OP_MADD);
529 R200_COLOR_ARG( 0, A );
530 R200_COLOR_ARG( 1, B );
531 break;
532 case GL_ADD:
533 color_combine = (R200_TXC_ARG_B_ZERO |
534 R200_TXC_COMP_ARG_B |
535 R200_TXC_OP_MADD);
536 R200_COLOR_ARG( 0, A );
537 R200_COLOR_ARG( 1, C );
538 break;
539 case GL_ADD_SIGNED:
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 );
546 break;
547 case GL_SUBTRACT:
548 color_combine = (R200_TXC_ARG_B_ZERO |
549 R200_TXC_COMP_ARG_B |
550 R200_TXC_NEG_ARG_C |
551 R200_TXC_OP_MADD);
552 R200_COLOR_ARG( 0, A );
553 R200_COLOR_ARG( 1, C );
554 break;
555 case GL_INTERPOLATE:
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 );
560 break;
561
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
566 * 1.3) does.
567 */
568 RGBshift = 0;
569 /* FALLTHROUGH */
570
571 case GL_DOT3_RGB:
572 case GL_DOT3_RGBA:
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
578 * normally.
579 */
580
581 color_combine = (R200_TXC_ARG_C_ZERO |
582 R200_TXC_OP_DOT3 |
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 );
589 break;
590
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 );
596 break;
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 );
603 break;
604 case GL_MODULATE_SUBTRACT_ATI:
605 color_combine = (R200_TXC_NEG_ARG_C |
606 R200_TXC_OP_MADD);
607 R200_COLOR_ARG( 0, A );
608 R200_COLOR_ARG( 1, C );
609 R200_COLOR_ARG( 2, B );
610 break;
611 default:
612 return GL_FALSE;
613 }
614
615 switch ( texUnit->_CurrentCombine->ModeA ) {
616 case GL_REPLACE:
617 alpha_combine = (R200_TXA_ARG_A_ZERO |
618 R200_TXA_ARG_B_ZERO |
619 R200_TXA_OP_MADD);
620 R200_ALPHA_ARG( 0, C );
621 break;
622 case GL_MODULATE:
623 alpha_combine = (R200_TXA_ARG_C_ZERO |
624 R200_TXA_OP_MADD);
625 R200_ALPHA_ARG( 0, A );
626 R200_ALPHA_ARG( 1, B );
627 break;
628 case GL_ADD:
629 alpha_combine = (R200_TXA_ARG_B_ZERO |
630 R200_TXA_COMP_ARG_B |
631 R200_TXA_OP_MADD);
632 R200_ALPHA_ARG( 0, A );
633 R200_ALPHA_ARG( 1, C );
634 break;
635 case GL_ADD_SIGNED:
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 );
642 break;
643 case GL_SUBTRACT:
644 alpha_combine = (R200_TXA_ARG_B_ZERO |
645 R200_TXA_COMP_ARG_B |
646 R200_TXA_NEG_ARG_C |
647 R200_TXA_OP_MADD);
648 R200_ALPHA_ARG( 0, A );
649 R200_ALPHA_ARG( 1, C );
650 break;
651 case GL_INTERPOLATE:
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 );
656 break;
657
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 );
663 break;
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 );
670 break;
671 case GL_MODULATE_SUBTRACT_ATI:
672 alpha_combine = (R200_TXA_NEG_ARG_C |
673 R200_TXA_OP_MADD);
674 R200_ALPHA_ARG( 0, A );
675 R200_ALPHA_ARG( 1, C );
676 R200_ALPHA_ARG( 2, B );
677 break;
678 default:
679 return GL_FALSE;
680 }
681
682 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
683 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
684 alpha_scale |= R200_TXA_DOT_ALPHA;
685 Ashift = RGBshift;
686 }
687
688 /* Step 3:
689 * Apply the scale factor.
690 */
691 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
692 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT);
693
694 /* All done!
695 */
696 }
697
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;
707 }
708
709 return GL_TRUE;
710 }
711
712 void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
713 __DRIdrawable *dPriv)
714 {
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;
722 radeonTexObjPtr t;
723 uint32_t pitch_val;
724 gl_format texFormat;
725
726 radeon = pDRICtx->driverPrivate;
727
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);
732
733 rImage = get_radeon_texture_image(texImage);
734 t = radeon_tex_obj(texObj);
735 if (t == NULL) {
736 return;
737 }
738
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 */
743 return;
744 }
745
746 _mesa_lock_texture(&radeon->glCtx, texObj);
747 if (t->bo) {
748 radeon_bo_unref(t->bo);
749 t->bo = NULL;
750 }
751 if (rImage->bo) {
752 radeon_bo_unref(rImage->bo);
753 rImage->bo = NULL;
754 }
755
756 radeon_miptree_unreference(&t->mt);
757 radeon_miptree_unreference(&rImage->mt);
758
759 rImage->bo = rb->bo;
760 radeon_bo_ref(rImage->bo);
761 t->bo = rb->bo;
762 radeon_bo_ref(t->bo);
763 t->tile_bits = 0;
764 t->image_override = GL_TRUE;
765 t->override_offset = 0;
766 t->pp_txpitch &= (1 << 13) -1;
767 pitch_val = rb->pitch;
768 switch (rb->cpp) {
769 case 4:
770 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
771 texFormat = MESA_FORMAT_RGB888;
772 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
773 }
774 else {
775 texFormat = MESA_FORMAT_ARGB8888;
776 t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
777 }
778 t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
779 break;
780 case 3:
781 default:
782 texFormat = MESA_FORMAT_RGB888;
783 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
784 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
785 break;
786 case 2:
787 texFormat = MESA_FORMAT_RGB565;
788 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
789 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
790 break;
791 }
792
793 _mesa_init_teximage_fields(&radeon->glCtx, texImage,
794 rb->base.Base.Width, rb->base.Base.Height,
795 1, 0,
796 rb->cpp, texFormat);
797 rImage->base.RowStride = rb->pitch / rb->cpp;
798
799
800 t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
801 | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
802
803 if (target == GL_TEXTURE_RECTANGLE_NV) {
804 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
805 t->pp_txpitch = pitch_val;
806 t->pp_txpitch -= 32;
807 } else {
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));
815 }
816
817 t->validated = GL_TRUE;
818 _mesa_unlock_texture(&radeon->glCtx, texObj);
819 return;
820 }
821
822
823 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
824 {
825 r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
826 }
827
828
829 #define REF_COLOR 1
830 #define REF_ALPHA 2
831
832 static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
833 {
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;
841 GLboolean ok;
842
843 /* find highest used unit */
844 for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
845 if (ctx->Texture.Unit[j]._ReallyEnabled) {
846 maxunitused = j;
847 }
848 }
849 stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA;
850
851 for ( j = maxunitused; j >= 0; j-- ) {
852 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[j];
853
854 rmesa->state.texture.unit[j].outputreg = -1;
855
856 if (stageref[j + 1]) {
857
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
860 optimization */
861 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) {
862 if (texregfree[i]) {
863 rmesa->state.texture.unit[j].outputreg = i;
864 break;
865 }
866 }
867 if (rmesa->state.texture.unit[j].outputreg == -1) {
868 /* no more free regs we can use. Need a fallback :-( */
869 return GL_FALSE;
870 }
871
872 nextunit[j] = currentnext;
873
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;
878 continue;
879 }
880 currentnext = j;
881
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);
886
887
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];
894 switch ( srcRGBi ) {
895 case GL_PREVIOUS:
896 /* op 0/1 are referencing color, op 2/3 alpha */
897 stageref[j] |= (op >> 1) + 1;
898 break;
899 case GL_TEXTURE:
900 texregfree[j] = GL_FALSE;
901 break;
902 case GL_TEXTURE0:
903 case GL_TEXTURE1:
904 case GL_TEXTURE2:
905 case GL_TEXTURE3:
906 case GL_TEXTURE4:
907 case GL_TEXTURE5:
908 texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE;
909 break;
910 default: /* don't care about other sources here */
911 break;
912 }
913 }
914 }
915
916 /* alpha args are ignored for dot3_rgba */
917 if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) {
918
919 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
920 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
921 switch ( srcAi ) {
922 case GL_PREVIOUS:
923 stageref[j] |= REF_ALPHA;
924 break;
925 case GL_TEXTURE:
926 texregfree[j] = GL_FALSE;
927 break;
928 case GL_TEXTURE0:
929 case GL_TEXTURE1:
930 case GL_TEXTURE2:
931 case GL_TEXTURE3:
932 case GL_TEXTURE4:
933 case GL_TEXTURE5:
934 texregfree[srcAi - GL_TEXTURE0] = GL_FALSE;
935 break;
936 default: /* don't care about other sources here */
937 break;
938 }
939 }
940 }
941 }
942 }
943
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;
949 }
950
951 ok = GL_TRUE;
952 currslot = 0;
953 rmesa->state.envneeded = 1;
954
955 i = 0;
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! */
967 replaceunit = i;
968 i = nextunit[i];
969 }
970
971 /* need env instruction slot */
972 rmesa->state.envneeded |= 1 << currslot;
973 ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit );
974 if (!ok) return GL_FALSE;
975 currslot++;
976 }
977 i = i + 1;
978 }
979
980 if (currslot == 0) {
981 /* need one stage at least */
982 rmesa->state.texture.unit[0].outputreg = 0;
983 ok = r200UpdateTextureEnv( ctx, 0, 0, 0 );
984 }
985
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;
989
990 return ok;
991 }
992
993 #undef REF_COLOR
994 #undef REF_ALPHA
995
996
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 | \
1001 R200_YUV_TO_RGB | \
1002 R200_YUV_TEMPERATURE_MASK | \
1003 R200_CLAMP_S_MASK | \
1004 R200_CLAMP_T_MASK | \
1005 R200_BORDER_MODE_D3D )
1006
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)
1015
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)
1021
1022
1023 static void disable_tex_obj_state( r200ContextPtr rmesa,
1024 int unit )
1025 {
1026
1027 R200_STATECHANGE( rmesa, vtx );
1028 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1029
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);
1034 }
1035
1036 /* Actually want to keep all units less than max active texture
1037 * enabled, right? Fix this for >2 texunits.
1038 */
1039
1040 {
1041 GLuint tmp = rmesa->TexGenEnabled;
1042
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);
1047
1048 if (tmp != rmesa->TexGenEnabled) {
1049 rmesa->recheck_texgen[unit] = GL_TRUE;
1050 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1051 }
1052 }
1053 }
1054 static void import_tex_obj_state( r200ContextPtr rmesa,
1055 int unit,
1056 radeonTexObjPtr texobj )
1057 {
1058 /* do not use RADEON_DB_STATE to avoid stale texture caches */
1059 GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
1060
1061 R200_STATECHANGE( rmesa, tex[unit] );
1062
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;
1072
1073 if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
1074 GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
1075
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;
1081 }
1082
1083 }
1084
1085 static void set_texgen_matrix( r200ContextPtr rmesa,
1086 GLuint unit,
1087 const GLfloat *s_plane,
1088 const GLfloat *t_plane,
1089 const GLfloat *r_plane,
1090 const GLfloat *q_plane )
1091 {
1092 GLfloat m[16];
1093
1094 m[0] = s_plane[0];
1095 m[4] = s_plane[1];
1096 m[8] = s_plane[2];
1097 m[12] = s_plane[3];
1098
1099 m[1] = t_plane[0];
1100 m[5] = t_plane[1];
1101 m[9] = t_plane[2];
1102 m[13] = t_plane[3];
1103
1104 m[2] = r_plane[0];
1105 m[6] = r_plane[1];
1106 m[10] = r_plane[2];
1107 m[14] = r_plane[3];
1108
1109 m[3] = q_plane[0];
1110 m[7] = q_plane[1];
1111 m[11] = q_plane[2];
1112 m[15] = q_plane[3];
1113
1114 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1115 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1116 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1117 }
1118
1119
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)
1125 {
1126 GLuint needtgenable = 0;
1127
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;
1133 }
1134 }
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;
1140 }
1141 }
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;
1147 }
1148 }
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;
1154 }
1155 }
1156
1157 return needtgenable;
1158 }
1159
1160
1161 /*
1162 * Returns GL_FALSE if fallback required.
1163 */
1164 static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
1165 {
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;
1169 GLuint tgi, tgcm;
1170 GLuint mode = 0;
1171 GLboolean mixed_fallback = GL_FALSE;
1172 static const GLfloat I[16] = {
1173 1, 0, 0, 0,
1174 0, 1, 0, 0,
1175 0, 0, 1, 0,
1176 0, 0, 0, 1 };
1177 static const GLfloat reflect[16] = {
1178 -1, 0, 0, 0,
1179 0, -1, 0, 0,
1180 0, 0, -1, 0,
1181 0, 0, 0, 1 };
1182
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 <<
1188 inputshift);
1189 tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
1190 (unit * 4));
1191
1192 if (0)
1193 fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
1194
1195 if (texUnit->TexGenEnabled & S_BIT) {
1196 mode = texUnit->GenS.Mode;
1197 } else {
1198 tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
1199 }
1200
1201 if (texUnit->TexGenEnabled & T_BIT) {
1202 if (texUnit->GenT.Mode != mode)
1203 mixed_fallback = GL_TRUE;
1204 } else {
1205 tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
1206 }
1207 if (texUnit->TexGenEnabled & R_BIT) {
1208 if (texUnit->GenR.Mode != mode)
1209 mixed_fallback = GL_TRUE;
1210 } else {
1211 tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
1212 }
1213
1214 if (texUnit->TexGenEnabled & Q_BIT) {
1215 if (texUnit->GenQ.Mode != mode)
1216 mixed_fallback = GL_TRUE;
1217 } else {
1218 tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
1219 }
1220
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);
1226 return GL_FALSE;
1227 }
1228
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 :-(. */
1240 switch (mode) {
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);
1251 return GL_FALSE;
1252 }
1253 if (needtgenable & (R_BIT)) {
1254 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1255 }
1256 if (needtgenable & (Q_BIT)) {
1257 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1258 }
1259
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);
1266 }
1267 break;
1268
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);
1279 return GL_FALSE;
1280 }
1281 if (needtgenable & (R_BIT)) {
1282 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1283 }
1284 if (needtgenable & (Q_BIT)) {
1285 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1286 }
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);
1293 }
1294 break;
1295
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,
1305 I + 12);
1306 break;
1307
1308 case GL_NORMAL_MAP_NV:
1309 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1310 tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
1311 break;
1312
1313 case GL_SPHERE_MAP:
1314 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1315 tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
1316 break;
1317
1318 case 0:
1319 /* All texgen units were disabled, so just pass coords through. */
1320 tgi |= unit << inputshift;
1321 break;
1322
1323 default:
1324 /* Unsupported mode, fallback:
1325 */
1326 if (R200_DEBUG & RADEON_FALLBACKS)
1327 fprintf(stderr, "fallback unsupported texgen, %d\n",
1328 texUnit->GenS.Mode);
1329 return GL_FALSE;
1330 }
1331
1332 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1333 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
1334
1335 if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] ||
1336 tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
1337 {
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;
1341 }
1342
1343 return GL_TRUE;
1344 }
1345
1346 void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
1347 {
1348 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1349
1350 GLuint re_cntl;
1351
1352 re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
1353 if (use_d3d)
1354 re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
1355
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;
1359 }
1360 }
1361
1362 /**
1363 * Compute the cached hardware register values for the given texture object.
1364 *
1365 * \param rmesa Context pointer
1366 * \param t the r300 texture object
1367 */
1368 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
1369 {
1370 const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
1371 GLint log2Width, log2Height, log2Depth, texelBytes;
1372 uint extra_size = 0;
1373
1374 if ( t->bo ) {
1375 return;
1376 }
1377
1378 log2Width = firstImage->WidthLog2;
1379 log2Height = firstImage->HeightLog2;
1380 log2Depth = firstImage->DepthLog2;
1381 texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
1382
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);
1387
1388 if (!t->image_override) {
1389 if (VALID_FORMAT(firstImage->TexFormat)) {
1390 const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
1391 tx_table_be;
1392
1393 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
1394 R200_TXFORMAT_ALPHA_IN_MAP);
1395 t->pp_txfilter &= ~R200_YUV_TO_RGB;
1396
1397 t->pp_txformat |= table[ firstImage->TexFormat ].format;
1398 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
1399
1400
1401 } else {
1402 _mesa_problem(NULL, "unexpected texture format in %s",
1403 __FUNCTION__);
1404 return;
1405 }
1406 }
1407
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;
1411
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;
1420
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));
1428
1429 t->tile_bits = 0;
1430
1431 t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
1432 | R200_MIN_MIP_LEVEL_MASK);
1433
1434 t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
1435 & R200_MIN_MIP_LEVEL_MASK;
1436
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;
1440
1441 }
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));
1457 }
1458 else {
1459 /* If we don't in fact send enough texture coordinates, q will be 1,
1460 * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1461 */
1462 t->pp_txformat_x |= R200_TEXCOORD_PROJ;
1463 }
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));
1467
1468 if ( !t->image_override ) {
1469 if (_mesa_is_format_compressed(firstImage->TexFormat))
1470 t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1471 else
1472 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1473 t->pp_txpitch -= 32;
1474 }
1475
1476 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1477 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
1478 }
1479
1480 }
1481
1482 static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
1483 {
1484 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1485 radeonTexObj *t = radeon_tex_obj(texObj);
1486
1487 if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
1488 return GL_FALSE;
1489
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);
1494
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 );
1499 else
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;
1503
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);
1507
1508 rmesa->recheck_texgen[unit] = GL_TRUE;
1509 r200TexUpdateParameters(ctx, unit);
1510 import_tex_obj_state( rmesa, unit, t );
1511
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;
1517 }
1518
1519 t->validated = GL_TRUE;
1520
1521 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1522
1523 return !t->border_fallback;
1524 }
1525
1526 static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
1527 {
1528 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1529 GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
1530
1531 if (!unitneeded) {
1532 /* disable the unit */
1533 disable_tex_obj_state(rmesa, unit);
1534 return GL_TRUE;
1535 }
1536
1537 if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1538 _mesa_warning(ctx,
1539 "failed to validate texture for unit %d.\n",
1540 unit);
1541 rmesa->state.texture.unit[unit].texobj = NULL;
1542 return GL_FALSE;
1543 }
1544
1545 rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1546 return GL_TRUE;
1547 }
1548
1549
1550 void r200UpdateTextureState( struct gl_context *ctx )
1551 {
1552 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1553 GLboolean ok;
1554 GLuint dbg;
1555
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
1559 atoms. */
1560 R200_NEWPRIM( rmesa );
1561
1562 if (ctx->ATIFragmentShader._Enabled) {
1563 GLuint i;
1564 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1565 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
1566 }
1567 ok = GL_TRUE;
1568 }
1569 else {
1570 ok = r200UpdateAllTexEnv( ctx );
1571 }
1572 if (ok) {
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 ));
1579 }
1580
1581 if (ok && ctx->ATIFragmentShader._Enabled) {
1582 r200UpdateFragmentShader(ctx);
1583 }
1584
1585 FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
1586
1587 if (rmesa->radeon.TclFallback)
1588 r200ChooseVertexState( ctx );
1589
1590
1591 if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
1592
1593 /*
1594 * T0 hang workaround -------------
1595 * not needed for r200 derivatives
1596 */
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) {
1599
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;
1606 }
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;
1612 }
1613 }
1614 /* do the same workaround for the first pass of a fragment shader.
1615 * completely unknown if necessary / sufficient.
1616 */
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) {
1619
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;
1626 }
1627
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;
1640 }
1641 else {
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;
1646 }
1647 }
1648 } */
1649
1650 /*
1651 * Texture cache LRU hang workaround -------------
1652 * not needed for r200 derivatives
1653 * hopefully this covers first pass of a shader as well
1654 */
1655
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.
1659 */
1660 dbg = 0x6;
1661
1662 /*
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)) &
1665 0x04) == 0)) ||
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)) &
1668 0x04) == 0)) ||
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)) &
1671 0x04) == 0)))
1672 {
1673 dbg |= 0x02;
1674 }
1675
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)) &
1678 0x04) == 0)) ||
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)) &
1681 0x04) == 0)) ||
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)) &
1684 0x04) == 0)))
1685 {
1686 dbg |= 0x04;
1687 }*/
1688
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);
1693 }
1694 }
1695 }