r200: use _mesa_get_current_tex_object() in r200SetTexBuffer2()
[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 /* 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_object *texObj;
716 struct gl_texture_image *texImage;
717 struct radeon_renderbuffer *rb;
718 radeon_texture_image *rImage;
719 radeonContextPtr radeon;
720 struct radeon_framebuffer *rfb;
721 radeonTexObjPtr t;
722 uint32_t pitch_val;
723 mesa_format texFormat;
724
725 radeon = pDRICtx->driverPrivate;
726
727 rfb = dPriv->driverPrivate;
728 texObj = _mesa_get_current_tex_object(&radeon->glCtx, target);
729 texImage = _mesa_get_tex_image(&radeon->glCtx, texObj, target, 0);
730
731 rImage = get_radeon_texture_image(texImage);
732 t = radeon_tex_obj(texObj);
733 if (t == NULL) {
734 return;
735 }
736
737 radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
738 rb = rfb->color_rb[0];
739 if (rb->bo == NULL) {
740 /* Failed to BO for the buffer */
741 return;
742 }
743
744 _mesa_lock_texture(&radeon->glCtx, texObj);
745 if (t->bo) {
746 radeon_bo_unref(t->bo);
747 t->bo = NULL;
748 }
749 if (rImage->bo) {
750 radeon_bo_unref(rImage->bo);
751 rImage->bo = NULL;
752 }
753
754 radeon_miptree_unreference(&t->mt);
755 radeon_miptree_unreference(&rImage->mt);
756
757 rImage->bo = rb->bo;
758 radeon_bo_ref(rImage->bo);
759 t->bo = rb->bo;
760 radeon_bo_ref(t->bo);
761 t->tile_bits = 0;
762 t->image_override = GL_TRUE;
763 t->override_offset = 0;
764 t->pp_txpitch &= (1 << 13) -1;
765 pitch_val = rb->pitch;
766 switch (rb->cpp) {
767 case 4:
768 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
769 texFormat = MESA_FORMAT_BGR_UNORM8;
770 t->pp_txformat = tx_table_le[MESA_FORMAT_BGR_UNORM8].format;
771 }
772 else {
773 texFormat = MESA_FORMAT_B8G8R8A8_UNORM;
774 t->pp_txformat = tx_table_le[MESA_FORMAT_B8G8R8A8_UNORM].format;
775 }
776 t->pp_txfilter |= tx_table_le[MESA_FORMAT_B8G8R8A8_UNORM].filter;
777 break;
778 case 3:
779 default:
780 texFormat = MESA_FORMAT_BGR_UNORM8;
781 t->pp_txformat = tx_table_le[MESA_FORMAT_BGR_UNORM8].format;
782 t->pp_txfilter |= tx_table_le[MESA_FORMAT_BGR_UNORM8].filter;
783 break;
784 case 2:
785 texFormat = MESA_FORMAT_B5G6R5_UNORM;
786 t->pp_txformat = tx_table_le[MESA_FORMAT_B5G6R5_UNORM].format;
787 t->pp_txfilter |= tx_table_le[MESA_FORMAT_B5G6R5_UNORM].filter;
788 break;
789 }
790
791 _mesa_init_teximage_fields(&radeon->glCtx, texImage,
792 rb->base.Base.Width, rb->base.Base.Height,
793 1, 0,
794 rb->cpp, texFormat);
795 rImage->base.RowStride = rb->pitch / rb->cpp;
796
797
798 t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
799 | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
800
801 if (target == GL_TEXTURE_RECTANGLE_NV) {
802 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
803 t->pp_txpitch = pitch_val;
804 t->pp_txpitch -= 32;
805 } else {
806 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
807 R200_TXFORMAT_HEIGHT_MASK |
808 R200_TXFORMAT_CUBIC_MAP_ENABLE |
809 R200_TXFORMAT_F5_WIDTH_MASK |
810 R200_TXFORMAT_F5_HEIGHT_MASK);
811 t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
812 (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
813 }
814
815 t->validated = GL_TRUE;
816 _mesa_unlock_texture(&radeon->glCtx, texObj);
817 return;
818 }
819
820
821 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
822 {
823 r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
824 }
825
826
827 #define REF_COLOR 1
828 #define REF_ALPHA 2
829
830 static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
831 {
832 r200ContextPtr rmesa = R200_CONTEXT(ctx);
833 GLint i, j, currslot;
834 GLint maxunitused = -1;
835 GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
836 GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0};
837 GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0};
838 GLint currentnext = -1;
839 GLboolean ok;
840
841 /* find highest used unit */
842 for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
843 if (ctx->Texture.Unit[j]._ReallyEnabled) {
844 maxunitused = j;
845 }
846 }
847 stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA;
848
849 for ( j = maxunitused; j >= 0; j-- ) {
850 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[j];
851
852 rmesa->state.texture.unit[j].outputreg = -1;
853
854 if (stageref[j + 1]) {
855
856 /* use the lowest available reg. That gets us automatically reg0 for the last stage.
857 need this even for disabled units, as it may get referenced due to the replace
858 optimization */
859 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) {
860 if (texregfree[i]) {
861 rmesa->state.texture.unit[j].outputreg = i;
862 break;
863 }
864 }
865 if (rmesa->state.texture.unit[j].outputreg == -1) {
866 /* no more free regs we can use. Need a fallback :-( */
867 return GL_FALSE;
868 }
869
870 nextunit[j] = currentnext;
871
872 if (!texUnit->_ReallyEnabled) {
873 /* the not enabled stages are referenced "indirectly",
874 must not cut off the lower stages */
875 stageref[j] = REF_COLOR | REF_ALPHA;
876 continue;
877 }
878 currentnext = j;
879
880 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
881 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
882 const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ||
883 (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT);
884
885
886 /* check if we need the color part, special case for dot3_rgba
887 as if only the alpha part is referenced later on it still is using the color part */
888 if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) {
889 for ( i = 0 ; i < numColorArgs ; i++ ) {
890 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
891 const GLuint op = texUnit->_CurrentCombine->OperandRGB[i];
892 switch ( srcRGBi ) {
893 case GL_PREVIOUS:
894 /* op 0/1 are referencing color, op 2/3 alpha */
895 stageref[j] |= (op >> 1) + 1;
896 break;
897 case GL_TEXTURE:
898 texregfree[j] = GL_FALSE;
899 break;
900 case GL_TEXTURE0:
901 case GL_TEXTURE1:
902 case GL_TEXTURE2:
903 case GL_TEXTURE3:
904 case GL_TEXTURE4:
905 case GL_TEXTURE5:
906 texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE;
907 break;
908 default: /* don't care about other sources here */
909 break;
910 }
911 }
912 }
913
914 /* alpha args are ignored for dot3_rgba */
915 if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) {
916
917 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
918 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
919 switch ( srcAi ) {
920 case GL_PREVIOUS:
921 stageref[j] |= REF_ALPHA;
922 break;
923 case GL_TEXTURE:
924 texregfree[j] = GL_FALSE;
925 break;
926 case GL_TEXTURE0:
927 case GL_TEXTURE1:
928 case GL_TEXTURE2:
929 case GL_TEXTURE3:
930 case GL_TEXTURE4:
931 case GL_TEXTURE5:
932 texregfree[srcAi - GL_TEXTURE0] = GL_FALSE;
933 break;
934 default: /* don't care about other sources here */
935 break;
936 }
937 }
938 }
939 }
940 }
941
942 /* don't enable texture sampling for units if the result is not used */
943 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
944 if (ctx->Texture.Unit[i]._ReallyEnabled && !texregfree[i])
945 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
946 else rmesa->state.texture.unit[i].unitneeded = 0;
947 }
948
949 ok = GL_TRUE;
950 currslot = 0;
951 rmesa->state.envneeded = 1;
952
953 i = 0;
954 while ((i <= maxunitused) && (i >= 0)) {
955 /* only output instruction if the results are referenced */
956 if (ctx->Texture.Unit[i]._ReallyEnabled && stageref[i+1]) {
957 GLuint replaceunit = i;
958 /* try to optimize GL_REPLACE away (only one level deep though) */
959 if ( (ctx->Texture.Unit[i]._CurrentCombine->ModeRGB == GL_REPLACE) &&
960 (ctx->Texture.Unit[i]._CurrentCombine->ModeA == GL_REPLACE) &&
961 (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftRGB == 0) &&
962 (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftA == 0) &&
963 (nextunit[i] > 0) ) {
964 /* yippie! can optimize it away! */
965 replaceunit = i;
966 i = nextunit[i];
967 }
968
969 /* need env instruction slot */
970 rmesa->state.envneeded |= 1 << currslot;
971 ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit );
972 if (!ok) return GL_FALSE;
973 currslot++;
974 }
975 i = i + 1;
976 }
977
978 if (currslot == 0) {
979 /* need one stage at least */
980 rmesa->state.texture.unit[0].outputreg = 0;
981 ok = r200UpdateTextureEnv( ctx, 0, 0, 0 );
982 }
983
984 R200_STATECHANGE( rmesa, ctx );
985 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE);
986 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT;
987
988 return ok;
989 }
990
991 #undef REF_COLOR
992 #undef REF_ALPHA
993
994
995 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \
996 R200_MIN_FILTER_MASK | \
997 R200_MAG_FILTER_MASK | \
998 R200_MAX_ANISO_MASK | \
999 R200_YUV_TO_RGB | \
1000 R200_YUV_TEMPERATURE_MASK | \
1001 R200_CLAMP_S_MASK | \
1002 R200_CLAMP_T_MASK | \
1003 R200_BORDER_MODE_D3D )
1004
1005 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \
1006 R200_TXFORMAT_HEIGHT_MASK | \
1007 R200_TXFORMAT_FORMAT_MASK | \
1008 R200_TXFORMAT_F5_WIDTH_MASK | \
1009 R200_TXFORMAT_F5_HEIGHT_MASK | \
1010 R200_TXFORMAT_ALPHA_IN_MAP | \
1011 R200_TXFORMAT_CUBIC_MAP_ENABLE | \
1012 R200_TXFORMAT_NON_POWER2)
1013
1014 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \
1015 R200_TEXCOORD_MASK | \
1016 R200_MIN_MIP_LEVEL_MASK | \
1017 R200_CLAMP_Q_MASK | \
1018 R200_VOLUME_FILTER_MASK)
1019
1020
1021 static void disable_tex_obj_state( r200ContextPtr rmesa,
1022 int unit )
1023 {
1024
1025 R200_STATECHANGE( rmesa, vtx );
1026 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1027
1028 R200_STATECHANGE( rmesa, ctx );
1029 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
1030 if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
1031 TCL_FALLBACK( &rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
1032 }
1033
1034 /* Actually want to keep all units less than max active texture
1035 * enabled, right? Fix this for >2 texunits.
1036 */
1037
1038 {
1039 GLuint tmp = rmesa->TexGenEnabled;
1040
1041 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1042 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1043 rmesa->TexGenNeedNormals[unit] = GL_FALSE;
1044 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1045
1046 if (tmp != rmesa->TexGenEnabled) {
1047 rmesa->recheck_texgen[unit] = GL_TRUE;
1048 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1049 }
1050 }
1051 }
1052 static void import_tex_obj_state( r200ContextPtr rmesa,
1053 int unit,
1054 radeonTexObjPtr texobj )
1055 {
1056 /* do not use RADEON_DB_STATE to avoid stale texture caches */
1057 GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
1058
1059 R200_STATECHANGE( rmesa, tex[unit] );
1060
1061 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
1062 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
1063 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1064 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
1065 cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
1066 cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK;
1067 cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
1068 cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
1069 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
1070
1071 if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
1072 GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
1073
1074 R200_STATECHANGE( rmesa, cube[unit] );
1075 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1076 /* that value is submitted twice. could change cube atom
1077 to not include that command when new drm is used */
1078 cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1079 }
1080
1081 }
1082
1083 static void set_texgen_matrix( r200ContextPtr rmesa,
1084 GLuint unit,
1085 const GLfloat *s_plane,
1086 const GLfloat *t_plane,
1087 const GLfloat *r_plane,
1088 const GLfloat *q_plane )
1089 {
1090 GLfloat m[16];
1091
1092 m[0] = s_plane[0];
1093 m[4] = s_plane[1];
1094 m[8] = s_plane[2];
1095 m[12] = s_plane[3];
1096
1097 m[1] = t_plane[0];
1098 m[5] = t_plane[1];
1099 m[9] = t_plane[2];
1100 m[13] = t_plane[3];
1101
1102 m[2] = r_plane[0];
1103 m[6] = r_plane[1];
1104 m[10] = r_plane[2];
1105 m[14] = r_plane[3];
1106
1107 m[3] = q_plane[0];
1108 m[7] = q_plane[1];
1109 m[11] = q_plane[2];
1110 m[15] = q_plane[3];
1111
1112 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1113 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1114 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1115 }
1116
1117
1118 static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
1119 const GLfloat *planeS,
1120 const GLfloat *planeT,
1121 const GLfloat *planeR,
1122 const GLfloat *planeQ)
1123 {
1124 GLuint needtgenable = 0;
1125
1126 if (!(texGenEnabled & S_BIT)) {
1127 if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) ||
1128 ((texGenEnabled & R_BIT) && planeR[0] != 0.0) ||
1129 ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) {
1130 needtgenable |= S_BIT;
1131 }
1132 }
1133 if (!(texGenEnabled & T_BIT)) {
1134 if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) ||
1135 ((texGenEnabled & R_BIT) && planeR[1] != 0.0) ||
1136 ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) {
1137 needtgenable |= T_BIT;
1138 }
1139 }
1140 if (!(texGenEnabled & R_BIT)) {
1141 if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) ||
1142 ((texGenEnabled & T_BIT) && planeT[2] != 0.0) ||
1143 ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) {
1144 needtgenable |= R_BIT;
1145 }
1146 }
1147 if (!(texGenEnabled & Q_BIT)) {
1148 if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) ||
1149 ((texGenEnabled & T_BIT) && planeT[3] != 0.0) ||
1150 ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) {
1151 needtgenable |= Q_BIT;
1152 }
1153 }
1154
1155 return needtgenable;
1156 }
1157
1158
1159 /*
1160 * Returns GL_FALSE if fallback required.
1161 */
1162 static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
1163 {
1164 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1165 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1166 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
1167 GLuint tgi, tgcm;
1168 GLuint mode = 0;
1169 GLboolean mixed_fallback = GL_FALSE;
1170 static const GLfloat I[16] = {
1171 1, 0, 0, 0,
1172 0, 1, 0, 0,
1173 0, 0, 1, 0,
1174 0, 0, 0, 1 };
1175 static const GLfloat reflect[16] = {
1176 -1, 0, 0, 0,
1177 0, -1, 0, 0,
1178 0, 0, -1, 0,
1179 0, 0, 0, 1 };
1180
1181 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1182 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1183 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1184 rmesa->TexGenNeedNormals[unit] = GL_FALSE;
1185 tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK <<
1186 inputshift);
1187 tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
1188 (unit * 4));
1189
1190 if (0)
1191 fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
1192
1193 if (texUnit->TexGenEnabled & S_BIT) {
1194 mode = texUnit->GenS.Mode;
1195 } else {
1196 tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
1197 }
1198
1199 if (texUnit->TexGenEnabled & T_BIT) {
1200 if (texUnit->GenT.Mode != mode)
1201 mixed_fallback = GL_TRUE;
1202 } else {
1203 tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
1204 }
1205 if (texUnit->TexGenEnabled & R_BIT) {
1206 if (texUnit->GenR.Mode != mode)
1207 mixed_fallback = GL_TRUE;
1208 } else {
1209 tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
1210 }
1211
1212 if (texUnit->TexGenEnabled & Q_BIT) {
1213 if (texUnit->GenQ.Mode != mode)
1214 mixed_fallback = GL_TRUE;
1215 } else {
1216 tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
1217 }
1218
1219 if (mixed_fallback) {
1220 if (R200_DEBUG & RADEON_FALLBACKS)
1221 fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
1222 texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode,
1223 texUnit->GenR.Mode, texUnit->GenQ.Mode);
1224 return GL_FALSE;
1225 }
1226
1227 /* we CANNOT do mixed mode if the texgen mode requires a plane where the input
1228 is not enabled for texgen, since the planes are concatenated into texmat,
1229 and thus the input will come from texcoord rather than tex gen equation!
1230 Either fallback or just hope that those texcoords aren't really needed...
1231 Assuming the former will cause lots of unnecessary fallbacks, the latter will
1232 generate bogus results sometimes - it's pretty much impossible to really know
1233 when a fallback is needed, depends on texmat and what sort of texture is bound
1234 etc, - for now fallback if we're missing either S or T bits, there's a high
1235 probability we need the texcoords in that case.
1236 That's a lot of work for some obscure texgen mixed mode fixup - why oh why
1237 doesn't the chip just directly accept the plane parameters :-(. */
1238 switch (mode) {
1239 case GL_OBJECT_LINEAR: {
1240 GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
1241 texUnit->GenS.ObjectPlane,
1242 texUnit->GenT.ObjectPlane,
1243 texUnit->GenR.ObjectPlane,
1244 texUnit->GenQ.ObjectPlane );
1245 if (needtgenable & (S_BIT | T_BIT)) {
1246 if (R200_DEBUG & RADEON_FALLBACKS)
1247 fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
1248 texUnit->TexGenEnabled);
1249 return GL_FALSE;
1250 }
1251 if (needtgenable & (R_BIT)) {
1252 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1253 }
1254 if (needtgenable & (Q_BIT)) {
1255 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1256 }
1257
1258 tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
1259 set_texgen_matrix( rmesa, unit,
1260 (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.ObjectPlane : I,
1261 (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.ObjectPlane : I + 4,
1262 (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.ObjectPlane : I + 8,
1263 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.ObjectPlane : I + 12);
1264 }
1265 break;
1266
1267 case GL_EYE_LINEAR: {
1268 GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
1269 texUnit->GenS.EyePlane,
1270 texUnit->GenT.EyePlane,
1271 texUnit->GenR.EyePlane,
1272 texUnit->GenQ.EyePlane );
1273 if (needtgenable & (S_BIT | T_BIT)) {
1274 if (R200_DEBUG & RADEON_FALLBACKS)
1275 fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
1276 texUnit->TexGenEnabled);
1277 return GL_FALSE;
1278 }
1279 if (needtgenable & (R_BIT)) {
1280 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1281 }
1282 if (needtgenable & (Q_BIT)) {
1283 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1284 }
1285 tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
1286 set_texgen_matrix( rmesa, unit,
1287 (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.EyePlane : I,
1288 (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.EyePlane : I + 4,
1289 (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.EyePlane : I + 8,
1290 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.EyePlane : I + 12);
1291 }
1292 break;
1293
1294 case GL_REFLECTION_MAP_NV:
1295 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1296 tgi |= R200_TEXGEN_INPUT_EYE_REFLECT << inputshift;
1297 /* pretty weird, must only negate when lighting is enabled? */
1298 if (ctx->Light.Enabled)
1299 set_texgen_matrix( rmesa, unit,
1300 (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
1301 (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
1302 (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
1303 I + 12);
1304 break;
1305
1306 case GL_NORMAL_MAP_NV:
1307 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1308 tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
1309 break;
1310
1311 case GL_SPHERE_MAP:
1312 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1313 tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
1314 break;
1315
1316 case 0:
1317 /* All texgen units were disabled, so just pass coords through. */
1318 tgi |= unit << inputshift;
1319 break;
1320
1321 default:
1322 /* Unsupported mode, fallback:
1323 */
1324 if (R200_DEBUG & RADEON_FALLBACKS)
1325 fprintf(stderr, "fallback unsupported texgen, %d\n",
1326 texUnit->GenS.Mode);
1327 return GL_FALSE;
1328 }
1329
1330 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1331 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
1332
1333 if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] ||
1334 tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
1335 {
1336 R200_STATECHANGE(rmesa, tcg);
1337 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi;
1338 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm;
1339 }
1340
1341 return GL_TRUE;
1342 }
1343
1344 void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
1345 {
1346 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1347
1348 GLuint re_cntl;
1349
1350 re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
1351 if (use_d3d)
1352 re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
1353
1354 if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
1355 R200_STATECHANGE( rmesa, set );
1356 rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
1357 }
1358 }
1359
1360 /**
1361 * Compute the cached hardware register values for the given texture object.
1362 *
1363 * \param rmesa Context pointer
1364 * \param t the r300 texture object
1365 */
1366 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
1367 {
1368 const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
1369 GLint log2Width, log2Height, log2Depth, texelBytes;
1370 uint extra_size = 0;
1371
1372 if ( t->bo ) {
1373 return;
1374 }
1375
1376 log2Width = firstImage->WidthLog2;
1377 log2Height = firstImage->HeightLog2;
1378 log2Depth = firstImage->DepthLog2;
1379 texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
1380
1381 radeon_print(RADEON_TEXTURE, RADEON_TRACE,
1382 "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
1383 __func__, rmesa, t, log2Width, log2Height,
1384 log2Depth, texelBytes, firstImage->TexFormat);
1385
1386 if (!t->image_override) {
1387 if (VALID_FORMAT(firstImage->TexFormat)) {
1388 const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
1389 tx_table_be;
1390
1391 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
1392 R200_TXFORMAT_ALPHA_IN_MAP);
1393 t->pp_txfilter &= ~R200_YUV_TO_RGB;
1394
1395 t->pp_txformat |= table[ firstImage->TexFormat ].format;
1396 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
1397
1398
1399 } else {
1400 _mesa_problem(NULL, "unexpected texture format in %s",
1401 __FUNCTION__);
1402 return;
1403 }
1404 }
1405
1406 t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
1407 t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
1408 & R200_MAX_MIP_LEVEL_MASK;
1409
1410 if ( t->pp_txfilter &
1411 (R200_MIN_FILTER_NEAREST_MIP_NEAREST
1412 | R200_MIN_FILTER_NEAREST_MIP_LINEAR
1413 | R200_MIN_FILTER_LINEAR_MIP_NEAREST
1414 | R200_MIN_FILTER_LINEAR_MIP_LINEAR
1415 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
1416 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
1417 extra_size = t->minLod;
1418
1419 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
1420 R200_TXFORMAT_HEIGHT_MASK |
1421 R200_TXFORMAT_CUBIC_MAP_ENABLE |
1422 R200_TXFORMAT_F5_WIDTH_MASK |
1423 R200_TXFORMAT_F5_HEIGHT_MASK);
1424 t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
1425 ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
1426
1427 t->tile_bits = 0;
1428
1429 t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
1430 | R200_MIN_MIP_LEVEL_MASK);
1431
1432 t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
1433 & R200_MIN_MIP_LEVEL_MASK;
1434
1435 if (t->base.Target == GL_TEXTURE_3D) {
1436 t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
1437 t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
1438
1439 }
1440 else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
1441 ASSERT(log2Width == log2Height);
1442 t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
1443 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
1444 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1445 (R200_TXFORMAT_CUBIC_MAP_ENABLE));
1446 t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
1447 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
1448 (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
1449 (log2Width << R200_FACE_WIDTH_2_SHIFT) |
1450 (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
1451 (log2Width << R200_FACE_WIDTH_3_SHIFT) |
1452 (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
1453 (log2Width << R200_FACE_WIDTH_4_SHIFT) |
1454 (log2Height << R200_FACE_HEIGHT_4_SHIFT));
1455 }
1456 else {
1457 /* If we don't in fact send enough texture coordinates, q will be 1,
1458 * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1459 */
1460 t->pp_txformat_x |= R200_TEXCOORD_PROJ;
1461 }
1462 /* FIXME: NPOT sizes, Is it correct realy? */
1463 t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
1464 | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
1465
1466 if ( !t->image_override ) {
1467 if (_mesa_is_format_compressed(firstImage->TexFormat))
1468 t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1469 else
1470 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1471 t->pp_txpitch -= 32;
1472 }
1473
1474 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1475 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
1476 }
1477
1478 }
1479
1480 static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
1481 {
1482 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1483 radeonTexObj *t = radeon_tex_obj(texObj);
1484
1485 if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
1486 return GL_FALSE;
1487
1488 r200_validate_texgen(ctx, unit);
1489 /* Configure the hardware registers (more precisely, the cached version
1490 * of the hardware registers). */
1491 setup_hardware_state(rmesa, t);
1492
1493 if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
1494 texObj->Target == GL_TEXTURE_2D ||
1495 texObj->Target == GL_TEXTURE_1D)
1496 set_re_cntl_d3d( ctx, unit, GL_FALSE );
1497 else
1498 set_re_cntl_d3d( ctx, unit, GL_TRUE );
1499 R200_STATECHANGE( rmesa, ctx );
1500 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
1501
1502 R200_STATECHANGE( rmesa, vtx );
1503 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1504 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1505
1506 rmesa->recheck_texgen[unit] = GL_TRUE;
1507 r200TexUpdateParameters(ctx, unit);
1508 import_tex_obj_state( rmesa, unit, t );
1509
1510 if (rmesa->recheck_texgen[unit]) {
1511 GLboolean fallback = !r200_validate_texgen( ctx, unit );
1512 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1513 rmesa->recheck_texgen[unit] = 0;
1514 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1515 }
1516
1517 t->validated = GL_TRUE;
1518
1519 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1520
1521 return !t->border_fallback;
1522 }
1523
1524 static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
1525 {
1526 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1527 GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
1528
1529 if (!unitneeded) {
1530 /* disable the unit */
1531 disable_tex_obj_state(rmesa, unit);
1532 return GL_TRUE;
1533 }
1534
1535 if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1536 _mesa_warning(ctx,
1537 "failed to validate texture for unit %d.\n",
1538 unit);
1539 rmesa->state.texture.unit[unit].texobj = NULL;
1540 return GL_FALSE;
1541 }
1542
1543 rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1544 return GL_TRUE;
1545 }
1546
1547
1548 void r200UpdateTextureState( struct gl_context *ctx )
1549 {
1550 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1551 GLboolean ok;
1552 GLuint dbg;
1553
1554 /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
1555 rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
1556 we use these to determine if we want to emit the corresponding state
1557 atoms. */
1558 R200_NEWPRIM( rmesa );
1559
1560 if (ctx->ATIFragmentShader._Enabled) {
1561 GLuint i;
1562 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1563 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
1564 }
1565 ok = GL_TRUE;
1566 }
1567 else {
1568 ok = r200UpdateAllTexEnv( ctx );
1569 }
1570 if (ok) {
1571 ok = (r200UpdateTextureUnit( ctx, 0 ) &&
1572 r200UpdateTextureUnit( ctx, 1 ) &&
1573 r200UpdateTextureUnit( ctx, 2 ) &&
1574 r200UpdateTextureUnit( ctx, 3 ) &&
1575 r200UpdateTextureUnit( ctx, 4 ) &&
1576 r200UpdateTextureUnit( ctx, 5 ));
1577 }
1578
1579 if (ok && ctx->ATIFragmentShader._Enabled) {
1580 r200UpdateFragmentShader(ctx);
1581 }
1582
1583 FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
1584
1585 if (rmesa->radeon.TclFallback)
1586 r200ChooseVertexState( ctx );
1587
1588
1589 if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
1590
1591 /*
1592 * T0 hang workaround -------------
1593 * not needed for r200 derivatives
1594 */
1595 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&
1596 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1597
1598 R200_STATECHANGE(rmesa, ctx);
1599 R200_STATECHANGE(rmesa, tex[1]);
1600 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1601 if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
1602 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1603 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
1604 }
1605 else if (!ctx->ATIFragmentShader._Enabled) {
1606 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
1607 (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {
1608 R200_STATECHANGE(rmesa, tex[1]);
1609 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE;
1610 }
1611 }
1612 /* do the same workaround for the first pass of a fragment shader.
1613 * completely unknown if necessary / sufficient.
1614 */
1615 if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE &&
1616 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1617
1618 R200_STATECHANGE(rmesa, cst);
1619 R200_STATECHANGE(rmesa, tex[1]);
1620 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE;
1621 if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE))
1622 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1623 rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
1624 }
1625
1626 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1627 looks like that's not the case, if 8500/9100 owners don't complain remove this...
1628 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1629 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1630 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1631 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1632 R200_MIN_FILTER_LINEAR)) {
1633 R200_STATECHANGE(rmesa, ctx);
1634 R200_STATECHANGE(rmesa, tex[i+1]);
1635 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1636 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1637 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1638 }
1639 else {
1640 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1641 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1642 R200_STATECHANGE(rmesa, tex[i+1]);
1643 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1644 }
1645 }
1646 } */
1647
1648 /*
1649 * Texture cache LRU hang workaround -------------
1650 * not needed for r200 derivatives
1651 * hopefully this covers first pass of a shader as well
1652 */
1653
1654 /* While the cases below attempt to only enable the workaround in the
1655 * specific cases necessary, they were insufficient. See bugzilla #1519,
1656 * #729, #814. Tests with quake3 showed no impact on performance.
1657 */
1658 dbg = 0x6;
1659
1660 /*
1661 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
1662 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1663 0x04) == 0)) ||
1664 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1665 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1666 0x04) == 0)) ||
1667 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1668 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1669 0x04) == 0)))
1670 {
1671 dbg |= 0x02;
1672 }
1673
1674 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
1675 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1676 0x04) == 0)) ||
1677 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1678 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1679 0x04) == 0)) ||
1680 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1681 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1682 0x04) == 0)))
1683 {
1684 dbg |= 0x04;
1685 }*/
1686
1687 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1688 R200_STATECHANGE( rmesa, tam );
1689 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1690 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);
1691 }
1692 }
1693 }