dri/i9*5: correctly calculate the amount of system memory
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texstate.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5
6 All Rights Reserved.
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 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 */
35
36 #include "main/glheader.h"
37 #include "main/imports.h"
38 #include "main/colormac.h"
39 #include "main/context.h"
40 #include "main/macros.h"
41 #include "main/teximage.h"
42 #include "main/texstate.h"
43 #include "main/texobj.h"
44 #include "main/enums.h"
45 #include "main/samplerobj.h"
46
47 #include "radeon_context.h"
48 #include "radeon_mipmap_tree.h"
49 #include "radeon_state.h"
50 #include "radeon_ioctl.h"
51 #include "radeon_swtcl.h"
52 #include "radeon_tex.h"
53 #include "radeon_tcl.h"
54
55
56 #define RADEON_TXFORMAT_A8 RADEON_TXFORMAT_I8
57 #define RADEON_TXFORMAT_L8 RADEON_TXFORMAT_I8
58 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
59 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
60 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
61 #define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1
62 #define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
63 #define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
64 #define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
65
66 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
67 && (tx_table[f].format != 0xffffffff) )
68
69 struct tx_table {
70 GLuint format, filter;
71 };
72
73 /* XXX verify this table against MESA_FORMAT_x values */
74 static const struct tx_table tx_table[] =
75 {
76 [ MESA_FORMAT_NONE ] = { 0xffffffff, 0 },
77 [ MESA_FORMAT_A8B8G8R8_UNORM ] = { RADEON_TXFORMAT_RGBA8888 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
78 [ MESA_FORMAT_R8G8B8A8_UNORM ] = { RADEON_TXFORMAT_RGBA8888 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
79 [ MESA_FORMAT_B8G8R8A8_UNORM ] = { RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
80 [ MESA_FORMAT_A8R8G8B8_UNORM ] = { RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
81 [ MESA_FORMAT_BGR_UNORM8 ] = { RADEON_TXFORMAT_ARGB8888, 0 },
82 [ MESA_FORMAT_B5G6R5_UNORM ] = { RADEON_TXFORMAT_RGB565, 0 },
83 [ MESA_FORMAT_R5G6B5_UNORM ] = { RADEON_TXFORMAT_RGB565, 0 },
84 [ MESA_FORMAT_B4G4R4A4_UNORM ] = { RADEON_TXFORMAT_ARGB4444 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
85 [ MESA_FORMAT_A4R4G4B4_UNORM ] = { RADEON_TXFORMAT_ARGB4444 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
86 [ MESA_FORMAT_B5G5R5A1_UNORM ] = { RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
87 [ MESA_FORMAT_A1R5G5B5_UNORM ] = { RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
88 [ MESA_FORMAT_L8A8_UNORM ] = { RADEON_TXFORMAT_AL88 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
89 [ MESA_FORMAT_A8L8_UNORM ] = { RADEON_TXFORMAT_AL88 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
90 [ MESA_FORMAT_A_UNORM8 ] = { RADEON_TXFORMAT_A8 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
91 [ MESA_FORMAT_L_UNORM8 ] = { RADEON_TXFORMAT_L8, 0 },
92 [ MESA_FORMAT_I_UNORM8 ] = { RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
93 [ MESA_FORMAT_YCBCR ] = { RADEON_TXFORMAT_YCBCR, RADEON_YUV_TO_RGB },
94 [ MESA_FORMAT_YCBCR_REV ] = { RADEON_TXFORMAT_YCBCR_REV, RADEON_YUV_TO_RGB },
95 [ MESA_FORMAT_RGB_FXT1 ] = { 0xffffffff, 0 },
96 [ MESA_FORMAT_RGBA_FXT1 ] = { 0xffffffff, 0 },
97 [ MESA_FORMAT_RGB_DXT1 ] = { RADEON_TXFORMAT_RGB_DXT1, 0 },
98 [ MESA_FORMAT_RGBA_DXT1 ] = { RADEON_TXFORMAT_RGBA_DXT1 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
99 [ MESA_FORMAT_RGBA_DXT3 ] = { RADEON_TXFORMAT_RGBA_DXT3 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
100 [ MESA_FORMAT_RGBA_DXT5 ] = { RADEON_TXFORMAT_RGBA_DXT5 | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 },
101 };
102
103 /* ================================================================
104 * Texture combine functions
105 */
106
107 /* GL_ARB_texture_env_combine support
108 */
109
110 /* The color tables have combine functions for GL_SRC_COLOR,
111 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
112 */
113 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
114 {
115 {
116 RADEON_COLOR_ARG_A_T0_COLOR,
117 RADEON_COLOR_ARG_A_T1_COLOR,
118 RADEON_COLOR_ARG_A_T2_COLOR
119 },
120 {
121 RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
122 RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
123 RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
124 },
125 {
126 RADEON_COLOR_ARG_A_T0_ALPHA,
127 RADEON_COLOR_ARG_A_T1_ALPHA,
128 RADEON_COLOR_ARG_A_T2_ALPHA
129 },
130 {
131 RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
132 RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
133 RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
134 },
135 };
136
137 static GLuint radeon_tfactor_color[] =
138 {
139 RADEON_COLOR_ARG_A_TFACTOR_COLOR,
140 RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
141 RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
142 RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
143 };
144
145 static GLuint radeon_primary_color[] =
146 {
147 RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
148 RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
149 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
150 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
151 };
152
153 static GLuint radeon_previous_color[] =
154 {
155 RADEON_COLOR_ARG_A_CURRENT_COLOR,
156 RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
157 RADEON_COLOR_ARG_A_CURRENT_ALPHA,
158 RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
159 };
160
161 /* GL_ZERO table - indices 0-3
162 * GL_ONE table - indices 1-4
163 */
164 static GLuint radeon_zero_color[] =
165 {
166 RADEON_COLOR_ARG_A_ZERO,
167 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
168 RADEON_COLOR_ARG_A_ZERO,
169 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
170 RADEON_COLOR_ARG_A_ZERO
171 };
172
173
174 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
175 */
176 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
177 {
178 {
179 RADEON_ALPHA_ARG_A_T0_ALPHA,
180 RADEON_ALPHA_ARG_A_T1_ALPHA,
181 RADEON_ALPHA_ARG_A_T2_ALPHA
182 },
183 {
184 RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
185 RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
186 RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
187 },
188 };
189
190 static GLuint radeon_tfactor_alpha[] =
191 {
192 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
193 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
194 };
195
196 static GLuint radeon_primary_alpha[] =
197 {
198 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
199 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
200 };
201
202 static GLuint radeon_previous_alpha[] =
203 {
204 RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
205 RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
206 };
207
208 /* GL_ZERO table - indices 0-1
209 * GL_ONE table - indices 1-2
210 */
211 static GLuint radeon_zero_alpha[] =
212 {
213 RADEON_ALPHA_ARG_A_ZERO,
214 RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
215 RADEON_ALPHA_ARG_A_ZERO
216 };
217
218
219 /* Extract the arg from slot A, shift it into the correct argument slot
220 * and set the corresponding complement bit.
221 */
222 #define RADEON_COLOR_ARG( n, arg ) \
223 do { \
224 color_combine |= \
225 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
226 << RADEON_COLOR_ARG_##arg##_SHIFT); \
227 color_combine |= \
228 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
229 << RADEON_COMP_ARG_##arg##_SHIFT); \
230 } while (0)
231
232 #define RADEON_ALPHA_ARG( n, arg ) \
233 do { \
234 alpha_combine |= \
235 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
236 << RADEON_ALPHA_ARG_##arg##_SHIFT); \
237 alpha_combine |= \
238 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
239 << RADEON_COMP_ARG_##arg##_SHIFT); \
240 } while (0)
241
242
243 /* ================================================================
244 * Texture unit state management
245 */
246
247 static GLboolean radeonUpdateTextureEnv( struct gl_context *ctx, int unit )
248 {
249 r100ContextPtr rmesa = R100_CONTEXT(ctx);
250 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
251 GLuint color_combine, alpha_combine;
252 const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
253 | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
254 | RADEON_SCALE_1X | RADEON_CLAMP_TX;
255 const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
256 | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
257 | RADEON_SCALE_1X | RADEON_CLAMP_TX;
258
259
260 /* texUnit->_Current can be NULL if and only if the texture unit is
261 * not actually enabled.
262 */
263 assert( (texUnit->_ReallyEnabled == 0)
264 || (texUnit->_Current != NULL) );
265
266 if ( RADEON_DEBUG & RADEON_TEXTURE ) {
267 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
268 }
269
270 /* Set the texture environment state. Isn't this nice and clean?
271 * The chip will automagically set the texture alpha to 0xff when
272 * the texture format does not include an alpha component. This
273 * reduces the amount of special-casing we have to do, alpha-only
274 * textures being a notable exception. Doesn't work for luminance
275 * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
276 */
277 /* Don't cache these results.
278 */
279 rmesa->state.texture.unit[unit].format = 0;
280 rmesa->state.texture.unit[unit].envMode = 0;
281
282 if ( !texUnit->_ReallyEnabled ) {
283 color_combine = color_combine0;
284 alpha_combine = alpha_combine0;
285 }
286 else {
287 GLuint color_arg[3], alpha_arg[3];
288 GLuint i;
289 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
290 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
291 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
292 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
293
294
295 /* Step 1:
296 * Extract the color and alpha combine function arguments.
297 */
298 for ( i = 0 ; i < numColorArgs ; i++ ) {
299 const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
300 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
301 assert(op >= 0);
302 assert(op <= 3);
303 switch ( srcRGBi ) {
304 case GL_TEXTURE:
305 if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA)
306 color_arg[i] = radeon_zero_color[op];
307 else
308 color_arg[i] = radeon_texture_color[op][unit];
309 break;
310 case GL_CONSTANT:
311 color_arg[i] = radeon_tfactor_color[op];
312 break;
313 case GL_PRIMARY_COLOR:
314 color_arg[i] = radeon_primary_color[op];
315 break;
316 case GL_PREVIOUS:
317 color_arg[i] = radeon_previous_color[op];
318 break;
319 case GL_ZERO:
320 color_arg[i] = radeon_zero_color[op];
321 break;
322 case GL_ONE:
323 color_arg[i] = radeon_zero_color[op+1];
324 break;
325 case GL_TEXTURE0:
326 case GL_TEXTURE1:
327 case GL_TEXTURE2: {
328 GLuint txunit = srcRGBi - GL_TEXTURE0;
329 if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA)
330 color_arg[i] = radeon_zero_color[op];
331 else
332 /* implement ogl 1.4/1.5 core spec here, not specification of
333 * GL_ARB_texture_env_crossbar (which would require disabling blending
334 * instead of undefined results when referencing not enabled texunit) */
335 color_arg[i] = radeon_texture_color[op][txunit];
336 }
337 break;
338 default:
339 return GL_FALSE;
340 }
341 }
342
343 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
344 const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
345 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
346 assert(op >= 0);
347 assert(op <= 1);
348 switch ( srcAi ) {
349 case GL_TEXTURE:
350 if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
351 alpha_arg[i] = radeon_zero_alpha[op+1];
352 else
353 alpha_arg[i] = radeon_texture_alpha[op][unit];
354 break;
355 case GL_CONSTANT:
356 alpha_arg[i] = radeon_tfactor_alpha[op];
357 break;
358 case GL_PRIMARY_COLOR:
359 alpha_arg[i] = radeon_primary_alpha[op];
360 break;
361 case GL_PREVIOUS:
362 alpha_arg[i] = radeon_previous_alpha[op];
363 break;
364 case GL_ZERO:
365 alpha_arg[i] = radeon_zero_alpha[op];
366 break;
367 case GL_ONE:
368 alpha_arg[i] = radeon_zero_alpha[op+1];
369 break;
370 case GL_TEXTURE0:
371 case GL_TEXTURE1:
372 case GL_TEXTURE2: {
373 GLuint txunit = srcAi - GL_TEXTURE0;
374 if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
375 alpha_arg[i] = radeon_zero_alpha[op+1];
376 else
377 alpha_arg[i] = radeon_texture_alpha[op][txunit];
378 }
379 break;
380 default:
381 return GL_FALSE;
382 }
383 }
384
385 /* Step 2:
386 * Build up the color and alpha combine functions.
387 */
388 switch ( texUnit->_CurrentCombine->ModeRGB ) {
389 case GL_REPLACE:
390 color_combine = (RADEON_COLOR_ARG_A_ZERO |
391 RADEON_COLOR_ARG_B_ZERO |
392 RADEON_BLEND_CTL_ADD |
393 RADEON_CLAMP_TX);
394 RADEON_COLOR_ARG( 0, C );
395 break;
396 case GL_MODULATE:
397 color_combine = (RADEON_COLOR_ARG_C_ZERO |
398 RADEON_BLEND_CTL_ADD |
399 RADEON_CLAMP_TX);
400 RADEON_COLOR_ARG( 0, A );
401 RADEON_COLOR_ARG( 1, B );
402 break;
403 case GL_ADD:
404 color_combine = (RADEON_COLOR_ARG_B_ZERO |
405 RADEON_COMP_ARG_B |
406 RADEON_BLEND_CTL_ADD |
407 RADEON_CLAMP_TX);
408 RADEON_COLOR_ARG( 0, A );
409 RADEON_COLOR_ARG( 1, C );
410 break;
411 case GL_ADD_SIGNED:
412 color_combine = (RADEON_COLOR_ARG_B_ZERO |
413 RADEON_COMP_ARG_B |
414 RADEON_BLEND_CTL_ADDSIGNED |
415 RADEON_CLAMP_TX);
416 RADEON_COLOR_ARG( 0, A );
417 RADEON_COLOR_ARG( 1, C );
418 break;
419 case GL_SUBTRACT:
420 color_combine = (RADEON_COLOR_ARG_B_ZERO |
421 RADEON_COMP_ARG_B |
422 RADEON_BLEND_CTL_SUBTRACT |
423 RADEON_CLAMP_TX);
424 RADEON_COLOR_ARG( 0, A );
425 RADEON_COLOR_ARG( 1, C );
426 break;
427 case GL_INTERPOLATE:
428 color_combine = (RADEON_BLEND_CTL_BLEND |
429 RADEON_CLAMP_TX);
430 RADEON_COLOR_ARG( 0, B );
431 RADEON_COLOR_ARG( 1, A );
432 RADEON_COLOR_ARG( 2, C );
433 break;
434
435 case GL_DOT3_RGB_EXT:
436 case GL_DOT3_RGBA_EXT:
437 /* The EXT version of the DOT3 extension does not support the
438 * scale factor, but the ARB version (and the version in OpenGL
439 * 1.3) does.
440 */
441 RGBshift = 0;
442 /* FALLTHROUGH */
443
444 case GL_DOT3_RGB:
445 case GL_DOT3_RGBA:
446 /* The R100 / RV200 only support a 1X multiplier in hardware
447 * w/the ARB version.
448 */
449 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
450 return GL_FALSE;
451 }
452
453 RGBshift += 2;
454 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
455 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
456 /* is it necessary to set this or will it be ignored anyway? */
457 Ashift = RGBshift;
458 }
459
460 color_combine = (RADEON_COLOR_ARG_C_ZERO |
461 RADEON_BLEND_CTL_DOT3 |
462 RADEON_CLAMP_TX);
463 RADEON_COLOR_ARG( 0, A );
464 RADEON_COLOR_ARG( 1, B );
465 break;
466
467 case GL_MODULATE_ADD_ATI:
468 color_combine = (RADEON_BLEND_CTL_ADD |
469 RADEON_CLAMP_TX);
470 RADEON_COLOR_ARG( 0, A );
471 RADEON_COLOR_ARG( 1, C );
472 RADEON_COLOR_ARG( 2, B );
473 break;
474 case GL_MODULATE_SIGNED_ADD_ATI:
475 color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
476 RADEON_CLAMP_TX);
477 RADEON_COLOR_ARG( 0, A );
478 RADEON_COLOR_ARG( 1, C );
479 RADEON_COLOR_ARG( 2, B );
480 break;
481 case GL_MODULATE_SUBTRACT_ATI:
482 color_combine = (RADEON_BLEND_CTL_SUBTRACT |
483 RADEON_CLAMP_TX);
484 RADEON_COLOR_ARG( 0, A );
485 RADEON_COLOR_ARG( 1, C );
486 RADEON_COLOR_ARG( 2, B );
487 break;
488 default:
489 return GL_FALSE;
490 }
491
492 switch ( texUnit->_CurrentCombine->ModeA ) {
493 case GL_REPLACE:
494 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
495 RADEON_ALPHA_ARG_B_ZERO |
496 RADEON_BLEND_CTL_ADD |
497 RADEON_CLAMP_TX);
498 RADEON_ALPHA_ARG( 0, C );
499 break;
500 case GL_MODULATE:
501 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
502 RADEON_BLEND_CTL_ADD |
503 RADEON_CLAMP_TX);
504 RADEON_ALPHA_ARG( 0, A );
505 RADEON_ALPHA_ARG( 1, B );
506 break;
507 case GL_ADD:
508 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
509 RADEON_COMP_ARG_B |
510 RADEON_BLEND_CTL_ADD |
511 RADEON_CLAMP_TX);
512 RADEON_ALPHA_ARG( 0, A );
513 RADEON_ALPHA_ARG( 1, C );
514 break;
515 case GL_ADD_SIGNED:
516 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
517 RADEON_COMP_ARG_B |
518 RADEON_BLEND_CTL_ADDSIGNED |
519 RADEON_CLAMP_TX);
520 RADEON_ALPHA_ARG( 0, A );
521 RADEON_ALPHA_ARG( 1, C );
522 break;
523 case GL_SUBTRACT:
524 alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
525 RADEON_COMP_ARG_B |
526 RADEON_BLEND_CTL_SUBTRACT |
527 RADEON_CLAMP_TX);
528 RADEON_ALPHA_ARG( 0, A );
529 RADEON_ALPHA_ARG( 1, C );
530 break;
531 case GL_INTERPOLATE:
532 alpha_combine = (RADEON_BLEND_CTL_BLEND |
533 RADEON_CLAMP_TX);
534 RADEON_ALPHA_ARG( 0, B );
535 RADEON_ALPHA_ARG( 1, A );
536 RADEON_ALPHA_ARG( 2, C );
537 break;
538
539 case GL_MODULATE_ADD_ATI:
540 alpha_combine = (RADEON_BLEND_CTL_ADD |
541 RADEON_CLAMP_TX);
542 RADEON_ALPHA_ARG( 0, A );
543 RADEON_ALPHA_ARG( 1, C );
544 RADEON_ALPHA_ARG( 2, B );
545 break;
546 case GL_MODULATE_SIGNED_ADD_ATI:
547 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
548 RADEON_CLAMP_TX);
549 RADEON_ALPHA_ARG( 0, A );
550 RADEON_ALPHA_ARG( 1, C );
551 RADEON_ALPHA_ARG( 2, B );
552 break;
553 case GL_MODULATE_SUBTRACT_ATI:
554 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
555 RADEON_CLAMP_TX);
556 RADEON_ALPHA_ARG( 0, A );
557 RADEON_ALPHA_ARG( 1, C );
558 RADEON_ALPHA_ARG( 2, B );
559 break;
560 default:
561 return GL_FALSE;
562 }
563
564 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
565 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
566 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
567 }
568
569 /* Step 3:
570 * Apply the scale factor.
571 */
572 color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
573 alpha_combine |= (Ashift << RADEON_SCALE_SHIFT);
574
575 /* All done!
576 */
577 }
578
579 if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
580 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
581 RADEON_STATECHANGE( rmesa, tex[unit] );
582 rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
583 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
584 }
585
586 return GL_TRUE;
587 }
588
589 void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
590 __DRIdrawable *dPriv)
591 {
592 struct gl_texture_object *texObj;
593 struct gl_texture_image *texImage;
594 struct radeon_renderbuffer *rb;
595 radeon_texture_image *rImage;
596 radeonContextPtr radeon;
597 struct radeon_framebuffer *rfb;
598 radeonTexObjPtr t;
599 uint32_t pitch_val;
600 mesa_format texFormat;
601
602 radeon = pDRICtx->driverPrivate;
603
604 rfb = dPriv->driverPrivate;
605 texObj = _mesa_get_current_tex_object(&radeon->glCtx, target);
606 texImage = _mesa_get_tex_image(&radeon->glCtx, texObj, target, 0);
607
608 rImage = get_radeon_texture_image(texImage);
609 t = radeon_tex_obj(texObj);
610 if (t == NULL) {
611 return;
612 }
613
614 radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
615 rb = rfb->color_rb[0];
616 if (rb->bo == NULL) {
617 /* Failed to BO for the buffer */
618 return;
619 }
620
621 _mesa_lock_texture(&radeon->glCtx, texObj);
622 if (t->bo) {
623 radeon_bo_unref(t->bo);
624 t->bo = NULL;
625 }
626 if (rImage->bo) {
627 radeon_bo_unref(rImage->bo);
628 rImage->bo = NULL;
629 }
630
631 radeon_miptree_unreference(&t->mt);
632 radeon_miptree_unreference(&rImage->mt);
633
634 rImage->bo = rb->bo;
635 radeon_bo_ref(rImage->bo);
636 t->bo = rb->bo;
637 radeon_bo_ref(t->bo);
638 t->tile_bits = 0;
639 t->image_override = GL_TRUE;
640 t->override_offset = 0;
641 switch (rb->cpp) {
642 case 4:
643 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
644 t->pp_txformat = tx_table[MESA_FORMAT_BGR_UNORM8].format;
645 texFormat = MESA_FORMAT_BGR_UNORM8;
646 }
647 else {
648 t->pp_txformat = tx_table[MESA_FORMAT_B8G8R8A8_UNORM].format;
649 texFormat = MESA_FORMAT_B8G8R8A8_UNORM;
650 }
651 t->pp_txfilter |= tx_table[MESA_FORMAT_B8G8R8A8_UNORM].filter;
652 break;
653 case 3:
654 default:
655 texFormat = MESA_FORMAT_BGR_UNORM8;
656 t->pp_txformat = tx_table[MESA_FORMAT_BGR_UNORM8].format;
657 t->pp_txfilter |= tx_table[MESA_FORMAT_BGR_UNORM8].filter;
658 break;
659 case 2:
660 texFormat = MESA_FORMAT_B5G6R5_UNORM;
661 t->pp_txformat = tx_table[MESA_FORMAT_B5G6R5_UNORM].format;
662 t->pp_txfilter |= tx_table[MESA_FORMAT_B5G6R5_UNORM].filter;
663 break;
664 }
665
666 _mesa_init_teximage_fields(&radeon->glCtx, texImage,
667 rb->base.Base.Width, rb->base.Base.Height,
668 1, 0,
669 rb->cpp, texFormat);
670 rImage->base.RowStride = rb->pitch / rb->cpp;
671
672 t->pp_txpitch &= (1 << 13) -1;
673 pitch_val = rb->pitch;
674
675 t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
676 | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
677 if (target == GL_TEXTURE_RECTANGLE_NV) {
678 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
679 t->pp_txpitch = pitch_val;
680 t->pp_txpitch -= 32;
681 } else {
682 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
683 RADEON_TXFORMAT_HEIGHT_MASK |
684 RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
685 RADEON_TXFORMAT_F5_WIDTH_MASK |
686 RADEON_TXFORMAT_F5_HEIGHT_MASK);
687 t->pp_txformat |= ((texImage->WidthLog2 << RADEON_TXFORMAT_WIDTH_SHIFT) |
688 (texImage->HeightLog2 << RADEON_TXFORMAT_HEIGHT_SHIFT));
689 }
690 t->validated = GL_TRUE;
691 _mesa_unlock_texture(&radeon->glCtx, texObj);
692 return;
693 }
694
695
696 void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
697 {
698 radeonSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
699 }
700
701
702 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
703 RADEON_MIN_FILTER_MASK | \
704 RADEON_MAG_FILTER_MASK | \
705 RADEON_MAX_ANISO_MASK | \
706 RADEON_YUV_TO_RGB | \
707 RADEON_YUV_TEMPERATURE_MASK | \
708 RADEON_CLAMP_S_MASK | \
709 RADEON_CLAMP_T_MASK | \
710 RADEON_BORDER_MODE_D3D )
711
712 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
713 RADEON_TXFORMAT_HEIGHT_MASK | \
714 RADEON_TXFORMAT_FORMAT_MASK | \
715 RADEON_TXFORMAT_F5_WIDTH_MASK | \
716 RADEON_TXFORMAT_F5_HEIGHT_MASK | \
717 RADEON_TXFORMAT_ALPHA_IN_MAP | \
718 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \
719 RADEON_TXFORMAT_NON_POWER2)
720
721
722 static void disable_tex_obj_state( r100ContextPtr rmesa,
723 int unit )
724 {
725 RADEON_STATECHANGE( rmesa, tex[unit] );
726
727 RADEON_STATECHANGE( rmesa, tcl );
728 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |
729 RADEON_Q_BIT(unit));
730
731 if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
732 TCL_FALLBACK( &rmesa->radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
733 rmesa->recheck_texgen[unit] = GL_TRUE;
734 }
735
736 if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
737 /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
738 cubic_map bit on unit 2 when the unit is disabled, otherwise every
739 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
740 units, better be safe than sorry though).*/
741 RADEON_STATECHANGE( rmesa, tex[unit] );
742 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
743 }
744
745 {
746 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
747 GLuint tmp = rmesa->TexGenEnabled;
748
749 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
750 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
751 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
752 rmesa->TexGenNeedNormals[unit] = 0;
753 rmesa->TexGenEnabled |=
754 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
755
756 if (tmp != rmesa->TexGenEnabled) {
757 rmesa->recheck_texgen[unit] = GL_TRUE;
758 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
759 }
760 }
761 }
762
763 static void import_tex_obj_state( r100ContextPtr rmesa,
764 int unit,
765 radeonTexObjPtr texobj )
766 {
767 /* do not use RADEON_DB_STATE to avoid stale texture caches */
768 uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
769 GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
770
771 RADEON_STATECHANGE( rmesa, tex[unit] );
772
773 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
774 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
775 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
776 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
777 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
778
779 if (texobj->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
780 uint32_t *txr_cmd = &rmesa->hw.txr[unit].cmd[TXR_CMD_0];
781 txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
782 txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
783 RADEON_STATECHANGE( rmesa, txr[unit] );
784 }
785
786 if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
787 se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
788 }
789 else {
790 se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
791
792 if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
793 uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
794
795 RADEON_STATECHANGE( rmesa, cube[unit] );
796 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
797 /* state filled out in the cube_emit */
798 }
799 }
800
801 if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {
802 RADEON_STATECHANGE( rmesa, set );
803 rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
804 }
805
806 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
807 }
808
809
810 static void set_texgen_matrix( r100ContextPtr rmesa,
811 GLuint unit,
812 const GLfloat *s_plane,
813 const GLfloat *t_plane,
814 const GLfloat *r_plane,
815 const GLfloat *q_plane )
816 {
817 rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
818 rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
819 rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
820 rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
821
822 rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
823 rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
824 rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
825 rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
826
827 rmesa->TexGenMatrix[unit].m[2] = r_plane[0];
828 rmesa->TexGenMatrix[unit].m[6] = r_plane[1];
829 rmesa->TexGenMatrix[unit].m[10] = r_plane[2];
830 rmesa->TexGenMatrix[unit].m[14] = r_plane[3];
831
832 rmesa->TexGenMatrix[unit].m[3] = q_plane[0];
833 rmesa->TexGenMatrix[unit].m[7] = q_plane[1];
834 rmesa->TexGenMatrix[unit].m[11] = q_plane[2];
835 rmesa->TexGenMatrix[unit].m[15] = q_plane[3];
836
837 rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;
838 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
839 }
840
841 /* Returns GL_FALSE if fallback required.
842 */
843 static GLboolean radeon_validate_texgen( struct gl_context *ctx, GLuint unit )
844 {
845 r100ContextPtr rmesa = R100_CONTEXT(ctx);
846 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
847 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
848 GLuint tmp = rmesa->TexGenEnabled;
849 static const GLfloat reflect[16] = {
850 -1, 0, 0, 0,
851 0, -1, 0, 0,
852 0, 0, -1, 0,
853 0, 0, 0, 1 };
854
855 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);
856 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);
857 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);
858 rmesa->TexGenNeedNormals[unit] = 0;
859
860 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {
861 /* Disabled, no fallback:
862 */
863 rmesa->TexGenEnabled |=
864 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
865 return GL_TRUE;
866 }
867 /* the r100 cannot do texgen for some coords and not for others
868 * we do not detect such cases (certainly can't do it here) and just
869 * ASSUME that when S and T are texgen enabled we do not need other
870 * non-texgen enabled coords, no matter if the R and Q bits are texgen
871 * enabled. Still check for mixed mode texgen for all coords.
872 */
873 else if ( (texUnit->TexGenEnabled & S_BIT) &&
874 (texUnit->TexGenEnabled & T_BIT) &&
875 (texUnit->GenS.Mode == texUnit->GenT.Mode) ) {
876 if ( ((texUnit->TexGenEnabled & R_BIT) &&
877 (texUnit->GenS.Mode != texUnit->GenR.Mode)) ||
878 ((texUnit->TexGenEnabled & Q_BIT) &&
879 (texUnit->GenS.Mode != texUnit->GenQ.Mode)) ) {
880 /* Mixed modes, fallback:
881 */
882 if (RADEON_DEBUG & RADEON_FALLBACKS)
883 fprintf(stderr, "fallback mixed texgen\n");
884 return GL_FALSE;
885 }
886 rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
887 }
888 else {
889 /* some texgen mode not including both S and T bits */
890 if (RADEON_DEBUG & RADEON_FALLBACKS)
891 fprintf(stderr, "fallback mixed texgen/nontexgen\n");
892 return GL_FALSE;
893 }
894
895 if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {
896 /* need this here for vtxfmt presumably. Argh we need to set
897 this from way too many places, would be much easier if we could leave
898 tcl q coord always enabled as on r200) */
899 RADEON_STATECHANGE( rmesa, tcl );
900 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);
901 }
902
903 switch (texUnit->GenS.Mode) {
904 case GL_OBJECT_LINEAR:
905 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
906 set_texgen_matrix( rmesa, unit,
907 texUnit->GenS.ObjectPlane,
908 texUnit->GenT.ObjectPlane,
909 texUnit->GenR.ObjectPlane,
910 texUnit->GenQ.ObjectPlane);
911 break;
912
913 case GL_EYE_LINEAR:
914 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
915 set_texgen_matrix( rmesa, unit,
916 texUnit->GenS.EyePlane,
917 texUnit->GenT.EyePlane,
918 texUnit->GenR.EyePlane,
919 texUnit->GenQ.EyePlane);
920 break;
921
922 case GL_REFLECTION_MAP_NV:
923 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
924 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;
925 /* TODO: unknown if this is needed/correct */
926 set_texgen_matrix( rmesa, unit, reflect, reflect + 4,
927 reflect + 8, reflect + 12 );
928 break;
929
930 case GL_NORMAL_MAP_NV:
931 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
932 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;
933 break;
934
935 case GL_SPHERE_MAP:
936 /* the mode which everyone uses :-( */
937 default:
938 /* Unsupported mode, fallback:
939 */
940 if (RADEON_DEBUG & RADEON_FALLBACKS)
941 fprintf(stderr, "fallback GL_SPHERE_MAP\n");
942 return GL_FALSE;
943 }
944
945 if (tmp != rmesa->TexGenEnabled) {
946 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
947 }
948
949 return GL_TRUE;
950 }
951
952 /**
953 * Compute the cached hardware register values for the given texture object.
954 *
955 * \param rmesa Context pointer
956 * \param t the r300 texture object
957 */
958 static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit)
959 {
960 const struct gl_texture_image *firstImage;
961 GLint log2Width, log2Height, texelBytes;
962
963 if ( t->bo ) {
964 return GL_TRUE;
965 }
966
967 firstImage = t->base.Image[0][t->minLod];
968
969 log2Width = firstImage->WidthLog2;
970 log2Height = firstImage->HeightLog2;
971 texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
972
973 if (!t->image_override) {
974 if (VALID_FORMAT(firstImage->TexFormat)) {
975 const struct tx_table *table = tx_table;
976
977 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
978 RADEON_TXFORMAT_ALPHA_IN_MAP);
979 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
980
981 t->pp_txformat |= table[ firstImage->TexFormat ].format;
982 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
983 } else {
984 _mesa_problem(NULL, "unexpected texture format in %s",
985 __FUNCTION__);
986 return GL_FALSE;
987 }
988 }
989
990 t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
991 t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT;
992
993 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
994 RADEON_TXFORMAT_HEIGHT_MASK |
995 RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
996 RADEON_TXFORMAT_F5_WIDTH_MASK |
997 RADEON_TXFORMAT_F5_HEIGHT_MASK);
998 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
999 (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
1000
1001 t->tile_bits = 0;
1002
1003 if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
1004 ASSERT(log2Width == log2Height);
1005 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
1006 (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
1007 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1008 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
1009 t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
1010 (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
1011 (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
1012 (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
1013 (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
1014 (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
1015 (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
1016 (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
1017 }
1018
1019 t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT)
1020 | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT));
1021
1022 if ( !t->image_override ) {
1023 if (_mesa_is_format_compressed(firstImage->TexFormat))
1024 t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1025 else
1026 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1027 t->pp_txpitch -= 32;
1028 }
1029
1030 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1031 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
1032 }
1033
1034 return GL_TRUE;
1035 }
1036
1037 static GLboolean radeon_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
1038 {
1039 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1040 radeonTexObj *t = radeon_tex_obj(texObj);
1041 int ret;
1042
1043 if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
1044 return GL_FALSE;
1045
1046 ret = setup_hardware_state(rmesa, t, unit);
1047 if (ret == GL_FALSE)
1048 return GL_FALSE;
1049
1050 /* yuv conversion only works in first unit */
1051 if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))
1052 return GL_FALSE;
1053
1054 RADEON_STATECHANGE( rmesa, ctx );
1055 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
1056 (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
1057 RADEON_STATECHANGE( rmesa, tcl );
1058 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
1059
1060 rmesa->recheck_texgen[unit] = GL_TRUE;
1061
1062 radeonTexUpdateParameters(ctx, unit);
1063 import_tex_obj_state( rmesa, unit, t );
1064
1065 if (rmesa->recheck_texgen[unit]) {
1066 GLboolean fallback = !radeon_validate_texgen( ctx, unit );
1067 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1068 rmesa->recheck_texgen[unit] = 0;
1069 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1070 }
1071
1072 if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
1073 return GL_FALSE;
1074 }
1075 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1076
1077 t->validated = GL_TRUE;
1078 return !t->border_fallback;
1079 }
1080
1081 static GLboolean radeonUpdateTextureUnit( struct gl_context *ctx, int unit )
1082 {
1083 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1084
1085 if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) {
1086 disable_tex_obj_state(rmesa, unit);
1087 rmesa->state.texture.unit[unit].texobj = NULL;
1088 return GL_FALSE;
1089 }
1090
1091 if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
1092 /* disable the unit */
1093 disable_tex_obj_state(rmesa, unit);
1094 rmesa->state.texture.unit[unit].texobj = NULL;
1095 return GL_TRUE;
1096 }
1097
1098 if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1099 _mesa_warning(ctx,
1100 "failed to validate texture for unit %d.\n",
1101 unit);
1102 rmesa->state.texture.unit[unit].texobj = NULL;
1103 return GL_FALSE;
1104 }
1105 rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1106 return GL_TRUE;
1107 }
1108
1109 void radeonUpdateTextureState( struct gl_context *ctx )
1110 {
1111 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1112 GLboolean ok;
1113
1114 /* set the ctx all textures off */
1115 RADEON_STATECHANGE( rmesa, ctx );
1116 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK));
1117
1118 ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
1119 radeonUpdateTextureUnit( ctx, 1 ) &&
1120 radeonUpdateTextureUnit( ctx, 2 ));
1121
1122 FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
1123
1124 if (rmesa->radeon.TclFallback)
1125 radeonChooseVertexState( ctx );
1126 }