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