r200_tex.c revision 692ca82116485a9c6191e5265c5b369d5b4f82f3
1/*
2Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
4The Weather Channel (TM) funded Tungsten Graphics to develop the
5initial release of the Radeon 8500 driver under the XFree86 license.
6This notice must be preserved.
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 * Authors:
31 *   Keith Whitwell <keith@tungstengraphics.com>
32 */
33
34#include "main/glheader.h"
35#include "main/imports.h"
36#include "main/colormac.h"
37#include "main/context.h"
38#include "main/enums.h"
39#include "main/image.h"
40#include "main/simple_list.h"
41#include "main/texformat.h"
42#include "main/texstore.h"
43#include "main/teximage.h"
44#include "main/texobj.h"
45
46#include "texmem.h"
47
48#include "r200_context.h"
49#include "r200_state.h"
50#include "r200_ioctl.h"
51#include "r200_swtcl.h"
52#include "r200_tex.h"
53
54#include "xmlpool.h"
55
56
57
58/**
59 * Set the texture wrap modes.
60 *
61 * \param t Texture object whose wrap modes are to be set
62 * \param swrap Wrap mode for the \a s texture coordinate
63 * \param twrap Wrap mode for the \a t texture coordinate
64 */
65
66static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap )
67{
68   GLboolean  is_clamp = GL_FALSE;
69   GLboolean  is_clamp_to_border = GL_FALSE;
70
71   t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D);
72
73   switch ( swrap ) {
74   case GL_REPEAT:
75      t->pp_txfilter |= R200_CLAMP_S_WRAP;
76      break;
77   case GL_CLAMP:
78      t->pp_txfilter |= R200_CLAMP_S_CLAMP_GL;
79      is_clamp = GL_TRUE;
80      break;
81   case GL_CLAMP_TO_EDGE:
82      t->pp_txfilter |= R200_CLAMP_S_CLAMP_LAST;
83      break;
84   case GL_CLAMP_TO_BORDER:
85      t->pp_txfilter |= R200_CLAMP_S_CLAMP_GL;
86      is_clamp_to_border = GL_TRUE;
87      break;
88   case GL_MIRRORED_REPEAT:
89      t->pp_txfilter |= R200_CLAMP_S_MIRROR;
90      break;
91   case GL_MIRROR_CLAMP_EXT:
92      t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_GL;
93      is_clamp = GL_TRUE;
94      break;
95   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
96      t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_LAST;
97      break;
98   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
99      t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_GL;
100      is_clamp_to_border = GL_TRUE;
101      break;
102   default:
103      _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
104   }
105
106   if (t->base.tObj->Target != GL_TEXTURE_1D) {
107      switch ( twrap ) {
108      case GL_REPEAT:
109         t->pp_txfilter |= R200_CLAMP_T_WRAP;
110         break;
111      case GL_CLAMP:
112         t->pp_txfilter |= R200_CLAMP_T_CLAMP_GL;
113         is_clamp = GL_TRUE;
114         break;
115      case GL_CLAMP_TO_EDGE:
116         t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST;
117         break;
118      case GL_CLAMP_TO_BORDER:
119         t->pp_txfilter |= R200_CLAMP_T_CLAMP_GL;
120         is_clamp_to_border = GL_TRUE;
121         break;
122      case GL_MIRRORED_REPEAT:
123         t->pp_txfilter |= R200_CLAMP_T_MIRROR;
124         break;
125      case GL_MIRROR_CLAMP_EXT:
126         t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_GL;
127         is_clamp = GL_TRUE;
128         break;
129      case GL_MIRROR_CLAMP_TO_EDGE_EXT:
130         t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_LAST;
131         break;
132      case GL_MIRROR_CLAMP_TO_BORDER_EXT:
133         t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_GL;
134         is_clamp_to_border = GL_TRUE;
135         break;
136      default:
137         _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
138      }
139   }
140
141   t->pp_txformat_x &= ~R200_CLAMP_Q_MASK;
142
143   switch ( rwrap ) {
144   case GL_REPEAT:
145      t->pp_txformat_x |= R200_CLAMP_Q_WRAP;
146      break;
147   case GL_CLAMP:
148      t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_GL;
149      is_clamp = GL_TRUE;
150      break;
151   case GL_CLAMP_TO_EDGE:
152      t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_LAST;
153      break;
154   case GL_CLAMP_TO_BORDER:
155      t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_GL;
156      is_clamp_to_border = GL_TRUE;
157      break;
158   case GL_MIRRORED_REPEAT:
159      t->pp_txformat_x |= R200_CLAMP_Q_MIRROR;
160      break;
161   case GL_MIRROR_CLAMP_EXT:
162      t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_GL;
163      is_clamp = GL_TRUE;
164      break;
165   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
166      t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_LAST;
167      break;
168   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
169      t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_GL;
170      is_clamp_to_border = GL_TRUE;
171      break;
172   default:
173      _mesa_problem(NULL, "bad R wrap mode in %s", __FUNCTION__);
174   }
175
176   if ( is_clamp_to_border ) {
177      t->pp_txfilter |= R200_BORDER_MODE_D3D;
178   }
179
180   t->border_fallback = (is_clamp && is_clamp_to_border);
181}
182
183static void r200SetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max )
184{
185   t->pp_txfilter &= ~R200_MAX_ANISO_MASK;
186
187   if ( max <= 1.0 ) {
188      t->pp_txfilter |= R200_MAX_ANISO_1_TO_1;
189   } else if ( max <= 2.0 ) {
190      t->pp_txfilter |= R200_MAX_ANISO_2_TO_1;
191   } else if ( max <= 4.0 ) {
192      t->pp_txfilter |= R200_MAX_ANISO_4_TO_1;
193   } else if ( max <= 8.0 ) {
194      t->pp_txfilter |= R200_MAX_ANISO_8_TO_1;
195   } else {
196      t->pp_txfilter |= R200_MAX_ANISO_16_TO_1;
197   }
198}
199
200/**
201 * Set the texture magnification and minification modes.
202 *
203 * \param t Texture whose filter modes are to be set
204 * \param minf Texture minification mode
205 * \param magf Texture magnification mode
206 */
207
208static void r200SetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf )
209{
210   GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK);
211
212   t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK);
213   t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK;
214
215   if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) {
216      switch ( minf ) {
217      case GL_NEAREST:
218	 t->pp_txfilter |= R200_MIN_FILTER_NEAREST;
219	 break;
220      case GL_LINEAR:
221	 t->pp_txfilter |= R200_MIN_FILTER_LINEAR;
222	 break;
223      case GL_NEAREST_MIPMAP_NEAREST:
224	 t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_NEAREST;
225	 break;
226      case GL_NEAREST_MIPMAP_LINEAR:
227	 t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_NEAREST;
228	 break;
229      case GL_LINEAR_MIPMAP_NEAREST:
230	 t->pp_txfilter |= R200_MIN_FILTER_NEAREST_MIP_LINEAR;
231	 break;
232      case GL_LINEAR_MIPMAP_LINEAR:
233	 t->pp_txfilter |= R200_MIN_FILTER_LINEAR_MIP_LINEAR;
234	 break;
235      }
236   } else {
237      switch ( minf ) {
238      case GL_NEAREST:
239	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST;
240	 break;
241      case GL_LINEAR:
242	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_LINEAR;
243	 break;
244      case GL_NEAREST_MIPMAP_NEAREST:
245      case GL_LINEAR_MIPMAP_NEAREST:
246	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
247	 break;
248      case GL_NEAREST_MIPMAP_LINEAR:
249      case GL_LINEAR_MIPMAP_LINEAR:
250	 t->pp_txfilter |= R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
251	 break;
252      }
253   }
254
255   /* Note we don't have 3D mipmaps so only use the mag filter setting
256    * to set the 3D texture filter mode.
257    */
258   switch ( magf ) {
259   case GL_NEAREST:
260      t->pp_txfilter |= R200_MAG_FILTER_NEAREST;
261      t->pp_txformat_x |= R200_VOLUME_FILTER_NEAREST;
262      break;
263   case GL_LINEAR:
264      t->pp_txfilter |= R200_MAG_FILTER_LINEAR;
265      t->pp_txformat_x |= R200_VOLUME_FILTER_LINEAR;
266      break;
267   }
268}
269
270static void r200SetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] )
271{
272   t->pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
273}
274
275
276/**
277 * Allocate space for and load the mesa images into the texture memory block.
278 * This will happen before drawing with a new texture, or drawing with a
279 * texture after it was swapped out or teximaged again.
280 */
281
282static radeonTexObjPtr r200AllocTexObj( struct gl_texture_object *texObj )
283{
284   radeonTexObjPtr t;
285
286   t = CALLOC_STRUCT( radeon_tex_obj );
287   texObj->DriverData = t;
288   if ( t != NULL ) {
289      if ( R200_DEBUG & DEBUG_TEXTURE ) {
290	 fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, (void *)texObj,
291		  (void *)t );
292      }
293
294      /* Initialize non-image-dependent parts of the state:
295       */
296      t->base.tObj = texObj;
297      t->border_fallback = GL_FALSE;
298
299      make_empty_list( & t->base );
300
301      r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR );
302      r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
303      r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
304      r200SetTexBorderColor( t, texObj->_BorderChan );
305   }
306
307   return t;
308}
309
310/* try to find a format which will only need a memcopy */
311static const struct gl_texture_format *
312r200Choose8888TexFormat( GLenum srcFormat, GLenum srcType )
313{
314   const GLuint ui = 1;
315   const GLubyte littleEndian = *((const GLubyte *) &ui);
316
317   if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
318       (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
319       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
320       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
321      return &_mesa_texformat_rgba8888;
322   }
323   else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
324       (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
325       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
326       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
327      return &_mesa_texformat_rgba8888_rev;
328   }
329   else return _dri_texformat_argb8888;
330}
331
332static const struct gl_texture_format *
333r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
334                           GLenum format, GLenum type )
335{
336   r200ContextPtr rmesa = R200_CONTEXT(ctx);
337   const GLboolean do32bpt =
338       ( rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32 );
339   const GLboolean force16bpt =
340       ( rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 );
341   (void) format;
342
343   switch ( internalFormat ) {
344   case 4:
345   case GL_RGBA:
346   case GL_COMPRESSED_RGBA:
347      switch ( type ) {
348      case GL_UNSIGNED_INT_10_10_10_2:
349      case GL_UNSIGNED_INT_2_10_10_10_REV:
350	 return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_argb1555;
351      case GL_UNSIGNED_SHORT_4_4_4_4:
352      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
353	 return _dri_texformat_argb4444;
354      case GL_UNSIGNED_SHORT_5_5_5_1:
355      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
356	 return _dri_texformat_argb1555;
357      default:
358         return do32bpt ?
359	    r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444;
360      }
361
362   case 3:
363   case GL_RGB:
364   case GL_COMPRESSED_RGB:
365      switch ( type ) {
366      case GL_UNSIGNED_SHORT_4_4_4_4:
367      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
368	 return _dri_texformat_argb4444;
369      case GL_UNSIGNED_SHORT_5_5_5_1:
370      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
371	 return _dri_texformat_argb1555;
372      case GL_UNSIGNED_SHORT_5_6_5:
373      case GL_UNSIGNED_SHORT_5_6_5_REV:
374	 return _dri_texformat_rgb565;
375      default:
376         return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565;
377      }
378
379   case GL_RGBA8:
380   case GL_RGB10_A2:
381   case GL_RGBA12:
382   case GL_RGBA16:
383      return !force16bpt ?
384	  r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444;
385
386   case GL_RGBA4:
387   case GL_RGBA2:
388      return _dri_texformat_argb4444;
389
390   case GL_RGB5_A1:
391      return _dri_texformat_argb1555;
392
393   case GL_RGB8:
394   case GL_RGB10:
395   case GL_RGB12:
396   case GL_RGB16:
397      return !force16bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565;
398
399   case GL_RGB5:
400   case GL_RGB4:
401   case GL_R3_G3_B2:
402      return _dri_texformat_rgb565;
403
404   case GL_ALPHA:
405   case GL_ALPHA4:
406   case GL_ALPHA8:
407   case GL_ALPHA12:
408   case GL_ALPHA16:
409   case GL_COMPRESSED_ALPHA:
410   /* can't use a8 format since interpreting hw I8 as a8 would result
411      in wrong rgb values (same as alpha value instead of 0). */
412      return _dri_texformat_al88;
413
414   case 1:
415   case GL_LUMINANCE:
416   case GL_LUMINANCE4:
417   case GL_LUMINANCE8:
418   case GL_LUMINANCE12:
419   case GL_LUMINANCE16:
420   case GL_COMPRESSED_LUMINANCE:
421      return _dri_texformat_l8;
422
423   case 2:
424   case GL_LUMINANCE_ALPHA:
425   case GL_LUMINANCE4_ALPHA4:
426   case GL_LUMINANCE6_ALPHA2:
427   case GL_LUMINANCE8_ALPHA8:
428   case GL_LUMINANCE12_ALPHA4:
429   case GL_LUMINANCE12_ALPHA12:
430   case GL_LUMINANCE16_ALPHA16:
431   case GL_COMPRESSED_LUMINANCE_ALPHA:
432      return _dri_texformat_al88;
433
434   case GL_INTENSITY:
435   case GL_INTENSITY4:
436   case GL_INTENSITY8:
437   case GL_INTENSITY12:
438   case GL_INTENSITY16:
439   case GL_COMPRESSED_INTENSITY:
440       return _dri_texformat_i8;
441
442   case GL_YCBCR_MESA:
443      if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
444          type == GL_UNSIGNED_BYTE)
445         return &_mesa_texformat_ycbcr;
446      else
447         return &_mesa_texformat_ycbcr_rev;
448
449   case GL_RGB_S3TC:
450   case GL_RGB4_S3TC:
451   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
452      return &_mesa_texformat_rgb_dxt1;
453
454   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
455      return &_mesa_texformat_rgba_dxt1;
456
457   case GL_RGBA_S3TC:
458   case GL_RGBA4_S3TC:
459   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
460      return &_mesa_texformat_rgba_dxt3;
461
462   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
463      return &_mesa_texformat_rgba_dxt5;
464
465   default:
466      _mesa_problem(ctx,
467         "unexpected internalFormat 0x%x in r200ChooseTextureFormat",
468         (int) internalFormat);
469      return NULL;
470   }
471
472   return NULL; /* never get here */
473}
474
475
476static GLboolean
477r200ValidateClientStorage( GLcontext *ctx, GLenum target,
478			   GLint internalFormat,
479			   GLint srcWidth, GLint srcHeight,
480                           GLenum format, GLenum type,  const void *pixels,
481			   const struct gl_pixelstore_attrib *packing,
482			   struct gl_texture_object *texObj,
483			   struct gl_texture_image *texImage)
484
485{
486   r200ContextPtr rmesa = R200_CONTEXT(ctx);
487
488   if ( R200_DEBUG & DEBUG_TEXTURE )
489      fprintf(stderr, "intformat %s format %s type %s\n",
490	      _mesa_lookup_enum_by_nr( internalFormat ),
491	      _mesa_lookup_enum_by_nr( format ),
492	      _mesa_lookup_enum_by_nr( type ));
493
494   if (!ctx->Unpack.ClientStorage)
495      return 0;
496
497   if (ctx->_ImageTransferState ||
498       texImage->IsCompressed ||
499       texObj->GenerateMipmap)
500      return 0;
501
502
503   /* This list is incomplete, may be different on ppc???
504    */
505   switch ( internalFormat ) {
506   case GL_RGBA:
507      if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
508	 texImage->TexFormat = _dri_texformat_argb8888;
509      }
510      else
511	 return 0;
512      break;
513
514   case GL_RGB:
515      if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
516	 texImage->TexFormat = _dri_texformat_rgb565;
517      }
518      else
519	 return 0;
520      break;
521
522   case GL_YCBCR_MESA:
523      if ( format == GL_YCBCR_MESA &&
524	   type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
525	 texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
526      }
527      else if ( format == GL_YCBCR_MESA &&
528		(type == GL_UNSIGNED_SHORT_8_8_APPLE ||
529		 type == GL_UNSIGNED_BYTE)) {
530	 texImage->TexFormat = &_mesa_texformat_ycbcr;
531      }
532      else
533	 return 0;
534      break;
535
536   default:
537      return 0;
538   }
539
540   /* Could deal with these packing issues, but currently don't:
541    */
542   if (packing->SkipPixels ||
543       packing->SkipRows ||
544       packing->SwapBytes ||
545       packing->LsbFirst) {
546      return 0;
547   }
548
549   {
550      GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
551						  format, type);
552
553
554      if ( R200_DEBUG & DEBUG_TEXTURE )
555	 fprintf(stderr, "%s: srcRowStride %d/%x\n",
556		 __FUNCTION__, srcRowStride, srcRowStride);
557
558      /* Could check this later in upload, pitch restrictions could be
559       * relaxed, but would need to store the image pitch somewhere,
560       * as packing details might change before image is uploaded:
561       */
562      if (!r200IsGartMemory( rmesa, pixels, srcHeight * srcRowStride ) ||
563	  (srcRowStride & 63))
564	 return 0;
565
566
567      /* Have validated that _mesa_transfer_teximage would be a straight
568       * memcpy at this point.  NOTE: future calls to TexSubImage will
569       * overwrite the client data.  This is explicitly mentioned in the
570       * extension spec.
571       */
572      texImage->Data = (void *)pixels;
573      texImage->IsClientData = GL_TRUE;
574      texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes;
575
576      return 1;
577   }
578}
579
580
581static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level,
582                              GLint internalFormat,
583                              GLint width, GLint border,
584                              GLenum format, GLenum type, const GLvoid *pixels,
585                              const struct gl_pixelstore_attrib *packing,
586                              struct gl_texture_object *texObj,
587                              struct gl_texture_image *texImage )
588{
589   driTextureObject * t = (driTextureObject *) texObj->DriverData;
590
591   if ( t ) {
592      driSwapOutTextureObject( t );
593   }
594   else {
595      t = (driTextureObject *) r200AllocTexObj( texObj );
596      if (!t) {
597         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
598         return;
599      }
600   }
601
602   /* Note, this will call ChooseTextureFormat */
603   _mesa_store_teximage1d(ctx, target, level, internalFormat,
604                          width, border, format, type, pixels,
605                          &ctx->Unpack, texObj, texImage);
606
607   t->dirty_images[0] |= (1 << level);
608}
609
610
611static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
612                                 GLint xoffset,
613                                 GLsizei width,
614                                 GLenum format, GLenum type,
615                                 const GLvoid *pixels,
616                                 const struct gl_pixelstore_attrib *packing,
617                                 struct gl_texture_object *texObj,
618                                 struct gl_texture_image *texImage )
619{
620   driTextureObject * t = (driTextureObject *) texObj->DriverData;
621
622   assert( t ); /* this _should_ be true */
623   if ( t ) {
624      driSwapOutTextureObject( t );
625   }
626   else {
627      t = (driTextureObject *) r200AllocTexObj( texObj );
628      if (!t) {
629         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
630         return;
631      }
632   }
633
634   _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
635			     format, type, pixels, packing, texObj,
636			     texImage);
637
638   t->dirty_images[0] |= (1 << level);
639}
640
641
642static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level,
643                              GLint internalFormat,
644                              GLint width, GLint height, GLint border,
645                              GLenum format, GLenum type, const GLvoid *pixels,
646                              const struct gl_pixelstore_attrib *packing,
647                              struct gl_texture_object *texObj,
648                              struct gl_texture_image *texImage )
649{
650   driTextureObject * t = (driTextureObject *) texObj->DriverData;
651   GLuint face;
652
653   /* which cube face or ordinary 2D image */
654   switch (target) {
655   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
656   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
657   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
658   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
659   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
660   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
661      face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
662      ASSERT(face < 6);
663      break;
664   default:
665      face = 0;
666   }
667
668   if ( t != NULL ) {
669      driSwapOutTextureObject( t );
670   }
671   else {
672      t = (driTextureObject *) r200AllocTexObj( texObj );
673      if (!t) {
674         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
675         return;
676      }
677   }
678
679   texImage->IsClientData = GL_FALSE;
680
681   if (r200ValidateClientStorage( ctx, target,
682				  internalFormat,
683				  width, height,
684				  format, type, pixels,
685				  packing, texObj, texImage)) {
686      if (R200_DEBUG & DEBUG_TEXTURE)
687	 fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
688   }
689   else {
690      if (R200_DEBUG & DEBUG_TEXTURE)
691	 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
692
693      /* Normal path: copy (to cached memory) and eventually upload
694       * via another copy to GART memory and then a blit...  Could
695       * eliminate one copy by going straight to (permanent) GART.
696       *
697       * Note, this will call r200ChooseTextureFormat.
698       */
699      _mesa_store_teximage2d(ctx, target, level, internalFormat,
700			     width, height, border, format, type, pixels,
701			     &ctx->Unpack, texObj, texImage);
702
703      t->dirty_images[face] |= (1 << level);
704   }
705}
706
707
708static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
709                                 GLint xoffset, GLint yoffset,
710                                 GLsizei width, GLsizei height,
711                                 GLenum format, GLenum type,
712                                 const GLvoid *pixels,
713                                 const struct gl_pixelstore_attrib *packing,
714                                 struct gl_texture_object *texObj,
715                                 struct gl_texture_image *texImage )
716{
717   driTextureObject * t = (driTextureObject *) texObj->DriverData;
718   GLuint face;
719
720   /* which cube face or ordinary 2D image */
721   switch (target) {
722   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
723   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
724   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
725   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
726   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
727   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
728      face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
729      ASSERT(face < 6);
730      break;
731   default:
732      face = 0;
733   }
734
735   assert( t ); /* this _should_ be true */
736   if ( t ) {
737      driSwapOutTextureObject( t );
738   }
739   else {
740      t = (driTextureObject *) r200AllocTexObj( texObj );
741      if (!t) {
742         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
743         return;
744      }
745   }
746
747   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
748			     height, format, type, pixels, packing, texObj,
749			     texImage);
750
751   t->dirty_images[face] |= (1 << level);
752}
753
754
755static void r200CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
756                              GLint internalFormat,
757                              GLint width, GLint height, GLint border,
758                              GLsizei imageSize, const GLvoid *data,
759                              struct gl_texture_object *texObj,
760                              struct gl_texture_image *texImage )
761{
762   driTextureObject * t = (driTextureObject *) texObj->DriverData;
763   GLuint face;
764
765   /* which cube face or ordinary 2D image */
766   switch (target) {
767   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
768   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
769   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
770   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
771   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
772   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
773      face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
774      ASSERT(face < 6);
775      break;
776   default:
777      face = 0;
778   }
779
780   if ( t != NULL ) {
781      driSwapOutTextureObject( t );
782   }
783   else {
784      t = (driTextureObject *) r200AllocTexObj( texObj );
785      if (!t) {
786         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
787         return;
788      }
789   }
790
791   texImage->IsClientData = GL_FALSE;
792/* can't call this, different parameters. Would never evaluate to true anyway currently
793   if (r200ValidateClientStorage( ctx, target,
794				  internalFormat,
795				  width, height,
796				  format, type, pixels,
797				  packing, texObj, texImage)) {
798      if (R200_DEBUG & DEBUG_TEXTURE)
799	 fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
800   }
801   else */{
802      if (R200_DEBUG & DEBUG_TEXTURE)
803	 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
804
805      /* Normal path: copy (to cached memory) and eventually upload
806       * via another copy to GART memory and then a blit...  Could
807       * eliminate one copy by going straight to (permanent) GART.
808       *
809       * Note, this will call r200ChooseTextureFormat.
810       */
811      _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
812                                 height, border, imageSize, data, texObj, texImage);
813
814      t->dirty_images[face] |= (1 << level);
815   }
816}
817
818
819static void r200CompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
820                                 GLint xoffset, GLint yoffset,
821                                 GLsizei width, GLsizei height,
822                                 GLenum format,
823                                 GLsizei imageSize, const GLvoid *data,
824                                 struct gl_texture_object *texObj,
825                                 struct gl_texture_image *texImage )
826{
827   driTextureObject * t = (driTextureObject *) texObj->DriverData;
828   GLuint face;
829
830
831   /* which cube face or ordinary 2D image */
832   switch (target) {
833   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
834   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
835   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
836   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
837   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
838   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
839      face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
840      ASSERT(face < 6);
841      break;
842   default:
843      face = 0;
844   }
845
846   assert( t ); /* this _should_ be true */
847   if ( t ) {
848      driSwapOutTextureObject( t );
849   }
850   else {
851      t = (driTextureObject *) r200AllocTexObj( texObj );
852      if (!t) {
853         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
854         return;
855      }
856   }
857
858   _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
859                            height, format, imageSize, data, texObj, texImage);
860
861   t->dirty_images[face] |= (1 << level);
862}
863
864
865#if ENABLE_HW_3D_TEXTURE
866static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level,
867                            GLint internalFormat,
868                            GLint width, GLint height, GLint depth,
869                            GLint border,
870                            GLenum format, GLenum type, const GLvoid *pixels,
871                            const struct gl_pixelstore_attrib *packing,
872                            struct gl_texture_object *texObj,
873                            struct gl_texture_image *texImage )
874{
875   driTextureObject * t = (driTextureObject *) texObj->DriverData;
876
877   if ( t ) {
878      driSwapOutTextureObject( t );
879   }
880   else {
881      t = (driTextureObject *) r200AllocTexObj( texObj );
882      if (!t) {
883         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
884         return;
885      }
886   }
887
888   texImage->IsClientData = GL_FALSE;
889
890#if 0
891   if (r200ValidateClientStorage( ctx, target,
892				  internalFormat,
893				  width, height,
894				  format, type, pixels,
895				  packing, texObj, texImage)) {
896      if (R200_DEBUG & DEBUG_TEXTURE)
897	 fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
898   }
899   else
900#endif
901   {
902      if (R200_DEBUG & DEBUG_TEXTURE)
903	 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
904
905      /* Normal path: copy (to cached memory) and eventually upload
906       * via another copy to GART memory and then a blit...  Could
907       * eliminate one copy by going straight to (permanent) GART.
908       *
909       * Note, this will call r200ChooseTextureFormat.
910       */
911      _mesa_store_teximage3d(ctx, target, level, internalFormat,
912			     width, height, depth, border,
913                             format, type, pixels,
914			     &ctx->Unpack, texObj, texImage);
915
916      t->dirty_images[0] |= (1 << level);
917   }
918}
919#endif
920
921
922#if ENABLE_HW_3D_TEXTURE
923static void
924r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
925                   GLint xoffset, GLint yoffset, GLint zoffset,
926                   GLsizei width, GLsizei height, GLsizei depth,
927                   GLenum format, GLenum type,
928                   const GLvoid *pixels,
929                   const struct gl_pixelstore_attrib *packing,
930                   struct gl_texture_object *texObj,
931                   struct gl_texture_image *texImage )
932{
933   driTextureObject * t = (driTextureObject *) texObj->DriverData;
934
935/*     fprintf(stderr, "%s\n", __FUNCTION__); */
936
937   assert( t ); /* this _should_ be true */
938   if ( t ) {
939      driSwapOutTextureObject( t );
940   }
941   else {
942      t = (driTextureObject *) r200AllocTexObj( texObj );
943      if (!t) {
944         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
945         return;
946      }
947      texObj->DriverData = t;
948   }
949
950   _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
951                             width, height, depth,
952                             format, type, pixels, packing, texObj, texImage);
953
954   t->dirty_images[0] |= (1 << level);
955}
956#endif
957
958
959
960static void r200TexEnv( GLcontext *ctx, GLenum target,
961			  GLenum pname, const GLfloat *param )
962{
963   r200ContextPtr rmesa = R200_CONTEXT(ctx);
964   GLuint unit = ctx->Texture.CurrentUnit;
965   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
966
967   if ( R200_DEBUG & DEBUG_STATE ) {
968      fprintf( stderr, "%s( %s )\n",
969	       __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) );
970   }
971
972   /* This is incorrect: Need to maintain this data for each of
973    * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
974    * between them according to _ReallyEnabled.
975    */
976   switch ( pname ) {
977   case GL_TEXTURE_ENV_COLOR: {
978      GLubyte c[4];
979      GLuint envColor;
980      UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
981      envColor = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
982      if ( rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] != envColor ) {
983	 R200_STATECHANGE( rmesa, tf );
984	 rmesa->hw.tf.cmd[TF_TFACTOR_0 + unit] = envColor;
985      }
986      break;
987   }
988
989   case GL_TEXTURE_LOD_BIAS_EXT: {
990      GLfloat bias, min;
991      GLuint b;
992      const int fixed_one = 0x8000000;
993
994      /* The R200's LOD bias is a signed 2's complement value with a
995       * range of -16.0 <= bias < 16.0.
996       *
997       * NOTE: Add a small bias to the bias for conform mipsel.c test.
998       */
999      bias = *param + .01;
1000      min = driQueryOptionb (&rmesa->optionCache, "no_neg_lod_bias") ?
1001	  0.0 : -16.0;
1002      bias = CLAMP( bias, min, 16.0 );
1003      b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK;
1004
1005      if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) {
1006	 R200_STATECHANGE( rmesa, tex[unit] );
1007	 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] &= ~R200_LOD_BIAS_MASK;
1008	 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] |= b;
1009      }
1010      break;
1011   }
1012   case GL_COORD_REPLACE_ARB:
1013      if (ctx->Point.PointSprite) {
1014	 R200_STATECHANGE( rmesa, spr );
1015	 if ((GLenum)param[0]) {
1016	    rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_GEN_TEX_0 << unit;
1017	 } else {
1018	    rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~(R200_PS_GEN_TEX_0 << unit);
1019	 }
1020      }
1021      break;
1022   default:
1023      return;
1024   }
1025}
1026
1027
1028/**
1029 * Changes variables and flags for a state update, which will happen at the
1030 * next UpdateTextureState
1031 */
1032
1033static void r200TexParameter( GLcontext *ctx, GLenum target,
1034				struct gl_texture_object *texObj,
1035				GLenum pname, const GLfloat *params )
1036{
1037   radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
1038
1039   if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
1040      fprintf( stderr, "%s( %s )\n", __FUNCTION__,
1041	       _mesa_lookup_enum_by_nr( pname ) );
1042   }
1043
1044   switch ( pname ) {
1045   case GL_TEXTURE_MIN_FILTER:
1046   case GL_TEXTURE_MAG_FILTER:
1047   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1048      r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
1049      r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
1050      break;
1051
1052   case GL_TEXTURE_WRAP_S:
1053   case GL_TEXTURE_WRAP_T:
1054   case GL_TEXTURE_WRAP_R:
1055      r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR );
1056      break;
1057
1058   case GL_TEXTURE_BORDER_COLOR:
1059      r200SetTexBorderColor( t, texObj->_BorderChan );
1060      break;
1061
1062   case GL_TEXTURE_BASE_LEVEL:
1063   case GL_TEXTURE_MAX_LEVEL:
1064   case GL_TEXTURE_MIN_LOD:
1065   case GL_TEXTURE_MAX_LOD:
1066      /* This isn't the most efficient solution but there doesn't appear to
1067       * be a nice alternative.  Since there's no LOD clamping,
1068       * we just have to rely on loading the right subset of mipmap levels
1069       * to simulate a clamped LOD.
1070       */
1071      driSwapOutTextureObject( (driTextureObject *) t );
1072      break;
1073
1074   default:
1075      return;
1076   }
1077
1078   /* Mark this texobj as dirty (one bit per tex unit)
1079    */
1080   t->dirty_state = R200_TEX_ALL;
1081}
1082
1083
1084
1085static void r200BindTexture( GLcontext *ctx, GLenum target,
1086			       struct gl_texture_object *texObj )
1087{
1088   if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
1089      fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, (void *)texObj,
1090	       ctx->Texture.CurrentUnit );
1091   }
1092
1093   if ( (target == GL_TEXTURE_1D)
1094	|| (target == GL_TEXTURE_2D)
1095#if ENABLE_HW_3D_TEXTURE
1096	|| (target == GL_TEXTURE_3D)
1097#endif
1098	|| (target == GL_TEXTURE_CUBE_MAP)
1099	|| (target == GL_TEXTURE_RECTANGLE_NV) ) {
1100      assert( texObj->DriverData != NULL );
1101   }
1102}
1103
1104
1105static void r200DeleteTexture( GLcontext *ctx,
1106				 struct gl_texture_object *texObj )
1107{
1108   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1109   driTextureObject * t = (driTextureObject *) texObj->DriverData;
1110
1111   if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
1112      fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, (void *)texObj,
1113	       _mesa_lookup_enum_by_nr( texObj->Target ) );
1114   }
1115
1116   if ( t != NULL ) {
1117      if ( rmesa ) {
1118         R200_FIREVERTICES( rmesa );
1119      }
1120
1121      driDestroyTextureObject( t );
1122   }
1123   /* Free mipmap images and the texture object itself */
1124   _mesa_delete_texture_object(ctx, texObj);
1125}
1126
1127/* Need:
1128 *  - Same GEN_MODE for all active bits
1129 *  - Same EyePlane/ObjPlane for all active bits when using Eye/Obj
1130 *  - STRQ presumably all supported (matrix means incoming R values
1131 *    can end up in STQ, this has implications for vertex support,
1132 *    presumably ok if maos is used, though?)
1133 *
1134 * Basically impossible to do this on the fly - just collect some
1135 * basic info & do the checks from ValidateState().
1136 */
1137static void r200TexGen( GLcontext *ctx,
1138			  GLenum coord,
1139			  GLenum pname,
1140			  const GLfloat *params )
1141{
1142   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1143   GLuint unit = ctx->Texture.CurrentUnit;
1144   rmesa->recheck_texgen[unit] = GL_TRUE;
1145}
1146
1147
1148/**
1149 * Allocate a new texture object.
1150 * Called via ctx->Driver.NewTextureObject.
1151 * Note: this function will be called during context creation to
1152 * allocate the default texture objects.
1153 * Note: we could use containment here to 'derive' the driver-specific
1154 * texture object from the core mesa gl_texture_object.  Not done at this time.
1155 * Fixup MaxAnisotropy according to user preference.
1156 */
1157static struct gl_texture_object *
1158r200NewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
1159{
1160   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1161   struct gl_texture_object *obj;
1162   obj = _mesa_new_texture_object(ctx, name, target);
1163   if (!obj)
1164      return NULL;
1165   obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
1166   r200AllocTexObj( obj );
1167   return obj;
1168}
1169
1170
1171void r200InitTextureFuncs( struct dd_function_table *functions )
1172{
1173   /* Note: we only plug in the functions we implement in the driver
1174    * since _mesa_init_driver_functions() was already called.
1175    */
1176   functions->ChooseTextureFormat	= r200ChooseTextureFormat;
1177   functions->TexImage1D		= r200TexImage1D;
1178   functions->TexImage2D		= r200TexImage2D;
1179#if ENABLE_HW_3D_TEXTURE
1180   functions->TexImage3D		= r200TexImage3D;
1181#else
1182   functions->TexImage3D		= _mesa_store_teximage3d;
1183#endif
1184   functions->TexSubImage1D		= r200TexSubImage1D;
1185   functions->TexSubImage2D		= r200TexSubImage2D;
1186#if ENABLE_HW_3D_TEXTURE
1187   functions->TexSubImage3D		= r200TexSubImage3D;
1188#else
1189   functions->TexSubImage3D		= _mesa_store_texsubimage3d;
1190#endif
1191   functions->NewTextureObject		= r200NewTextureObject;
1192   functions->BindTexture		= r200BindTexture;
1193   functions->DeleteTexture		= r200DeleteTexture;
1194   functions->IsTextureResident		= driIsTextureResident;
1195
1196   functions->TexEnv			= r200TexEnv;
1197   functions->TexParameter		= r200TexParameter;
1198   functions->TexGen			= r200TexGen;
1199
1200   functions->CompressedTexImage2D	= r200CompressedTexImage2D;
1201   functions->CompressedTexSubImage2D	= r200CompressedTexSubImage2D;
1202
1203   driInitTextureFormats();
1204
1205#if 000
1206   /* moved or obsolete code */
1207   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1208   driInitTextureObjects( ctx, & rmesa->swapped,
1209			  DRI_TEXMGR_DO_TEXTURE_1D
1210			  | DRI_TEXMGR_DO_TEXTURE_2D );
1211
1212   /* Hack: r200NewTextureObject is not yet installed when the
1213    * default textures are created. Therefore set MaxAnisotropy of the
1214    * default 2D texture now. */
1215   ctx->Shared->Default2D->MaxAnisotropy = driQueryOptionf (&rmesa->optionCache,
1216							    "def_max_anisotropy");
1217#endif
1218}
1219