~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r200/r200_tex.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

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