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