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