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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r300/r300_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
/*
 
2
Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 
3
 
 
4
The Weather Channel (TM) funded Tungsten Graphics to develop the
 
5
initial release of the Radeon 8500 driver under the XFree86 license.
 
6
This notice must be preserved.
 
7
 
 
8
Permission is hereby granted, free of charge, to any person obtaining
 
9
a copy of this software and associated documentation files (the
 
10
"Software"), to deal in the Software without restriction, including
 
11
without limitation the rights to use, copy, modify, merge, publish,
 
12
distribute, sublicense, and/or sell copies of the Software, and to
 
13
permit persons to whom the Software is furnished to do so, subject to
 
14
the following conditions:
 
15
 
 
16
The above copyright notice and this permission notice (including the
 
17
next paragraph) shall be included in all copies or substantial
 
18
portions of the Software.
 
19
 
 
20
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
23
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 
24
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
*/
 
28
 
 
29
/**
 
30
 * \file
 
31
 *
 
32
 * \author 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 "r300_context.h"
 
49
#include "r300_state.h"
 
50
#include "r300_ioctl.h"
 
51
#include "r300_tex.h"
 
52
 
 
53
#include "xmlpool.h"
 
54
 
 
55
/**
 
56
 * Set the texture wrap modes.
 
57
 *
 
58
 * \param t Texture object whose wrap modes are to be set
 
59
 * \param swrap Wrap mode for the \a s texture coordinate
 
60
 * \param twrap Wrap mode for the \a t texture coordinate
 
61
 */
 
62
 
 
63
static void r300SetTexWrap(r300TexObjPtr t, GLenum swrap, GLenum twrap,
 
64
                           GLenum rwrap)
 
65
{
 
66
        unsigned long hw_swrap = 0, hw_twrap = 0, hw_qwrap = 0;
 
67
 
 
68
        t->filter &=
 
69
            ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_Q_MASK);
 
70
 
 
71
        switch (swrap) {
 
72
        case GL_REPEAT:
 
73
                hw_swrap |= R300_TX_REPEAT;
 
74
                break;
 
75
        case GL_CLAMP:
 
76
                hw_swrap |= R300_TX_CLAMP;
 
77
                break;
 
78
        case GL_CLAMP_TO_EDGE:
 
79
                hw_swrap |= R300_TX_CLAMP_TO_EDGE;
 
80
                break;
 
81
        case GL_CLAMP_TO_BORDER:
 
82
                hw_swrap |= R300_TX_CLAMP_TO_BORDER;
 
83
                break;
 
84
        case GL_MIRRORED_REPEAT:
 
85
                hw_swrap |= R300_TX_REPEAT | R300_TX_MIRRORED;
 
86
                break;
 
87
        case GL_MIRROR_CLAMP_EXT:
 
88
                hw_swrap |= R300_TX_CLAMP | R300_TX_MIRRORED;
 
89
                break;
 
90
        case GL_MIRROR_CLAMP_TO_EDGE_EXT:
 
91
                hw_swrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
 
92
                break;
 
93
        case GL_MIRROR_CLAMP_TO_BORDER_EXT:
 
94
                hw_swrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
 
95
                break;
 
96
        default:
 
97
                _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
 
98
        }
 
99
 
 
100
        switch (twrap) {
 
101
        case GL_REPEAT:
 
102
                hw_twrap |= R300_TX_REPEAT;
 
103
                break;
 
104
        case GL_CLAMP:
 
105
                hw_twrap |= R300_TX_CLAMP;
 
106
                break;
 
107
        case GL_CLAMP_TO_EDGE:
 
108
                hw_twrap |= R300_TX_CLAMP_TO_EDGE;
 
109
                break;
 
110
        case GL_CLAMP_TO_BORDER:
 
111
                hw_twrap |= R300_TX_CLAMP_TO_BORDER;
 
112
                break;
 
113
        case GL_MIRRORED_REPEAT:
 
114
                hw_twrap |= R300_TX_REPEAT | R300_TX_MIRRORED;
 
115
                break;
 
116
        case GL_MIRROR_CLAMP_EXT:
 
117
                hw_twrap |= R300_TX_CLAMP | R300_TX_MIRRORED;
 
118
                break;
 
119
        case GL_MIRROR_CLAMP_TO_EDGE_EXT:
 
120
                hw_twrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
 
121
                break;
 
122
        case GL_MIRROR_CLAMP_TO_BORDER_EXT:
 
123
                hw_twrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
 
124
                break;
 
125
        default:
 
126
                _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
 
127
        }
 
128
 
 
129
        switch (rwrap) {
 
130
        case GL_REPEAT:
 
131
                hw_qwrap |= R300_TX_REPEAT;
 
132
                break;
 
133
        case GL_CLAMP:
 
134
                hw_qwrap |= R300_TX_CLAMP;
 
135
                break;
 
136
        case GL_CLAMP_TO_EDGE:
 
137
                hw_qwrap |= R300_TX_CLAMP_TO_EDGE;
 
138
                break;
 
139
        case GL_CLAMP_TO_BORDER:
 
140
                hw_qwrap |= R300_TX_CLAMP_TO_BORDER;
 
141
                break;
 
142
        case GL_MIRRORED_REPEAT:
 
143
                hw_qwrap |= R300_TX_REPEAT | R300_TX_MIRRORED;
 
144
                break;
 
145
        case GL_MIRROR_CLAMP_EXT:
 
146
                hw_qwrap |= R300_TX_CLAMP | R300_TX_MIRRORED;
 
147
                break;
 
148
        case GL_MIRROR_CLAMP_TO_EDGE_EXT:
 
149
                hw_qwrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
 
150
                break;
 
151
        case GL_MIRROR_CLAMP_TO_BORDER_EXT:
 
152
                hw_qwrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
 
153
                break;
 
154
        default:
 
155
                _mesa_problem(NULL, "bad R wrap mode in %s", __FUNCTION__);
 
156
        }
 
157
 
 
158
        t->filter |= hw_swrap << R300_TX_WRAP_S_SHIFT;
 
159
        t->filter |= hw_twrap << R300_TX_WRAP_T_SHIFT;
 
160
        t->filter |= hw_qwrap << R300_TX_WRAP_Q_SHIFT;
 
161
}
 
162
 
 
163
static void r300SetTexMaxAnisotropy(r300TexObjPtr t, GLfloat max)
 
164
{
 
165
 
 
166
        t->filter &= ~R300_TX_MAX_ANISO_MASK;
 
167
 
 
168
        if (max <= 1.0) {
 
169
                t->filter |= R300_TX_MAX_ANISO_1_TO_1;
 
170
        } else if (max <= 2.0) {
 
171
                t->filter |= R300_TX_MAX_ANISO_2_TO_1;
 
172
        } else if (max <= 4.0) {
 
173
                t->filter |= R300_TX_MAX_ANISO_4_TO_1;
 
174
        } else if (max <= 8.0) {
 
175
                t->filter |= R300_TX_MAX_ANISO_8_TO_1;
 
176
        } else {
 
177
                t->filter |= R300_TX_MAX_ANISO_16_TO_1;
 
178
        }
 
179
}
 
180
 
 
181
/**
 
182
 * Set the texture magnification and minification modes.
 
183
 *
 
184
 * \param t Texture whose filter modes are to be set
 
185
 * \param minf Texture minification mode
 
186
 * \param magf Texture magnification mode
 
187
 */
 
188
 
 
189
static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf)
 
190
{
 
191
        GLuint anisotropy = (t->filter & R300_TX_MAX_ANISO_MASK);
 
192
 
 
193
        t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK);
 
194
 
 
195
        if (anisotropy == R300_TX_MAX_ANISO_1_TO_1) {
 
196
                switch (minf) {
 
197
                case GL_NEAREST:
 
198
                        t->filter |= R300_TX_MIN_FILTER_NEAREST;
 
199
                        break;
 
200
                case GL_LINEAR:
 
201
                        t->filter |= R300_TX_MIN_FILTER_LINEAR;
 
202
                        break;
 
203
                case GL_NEAREST_MIPMAP_NEAREST:
 
204
                        t->filter |= R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST;
 
205
                        break;
 
206
                case GL_NEAREST_MIPMAP_LINEAR:
 
207
                        t->filter |= R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR;
 
208
                        break;
 
209
                case GL_LINEAR_MIPMAP_NEAREST:
 
210
                        t->filter |= R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST;
 
211
                        break;
 
212
                case GL_LINEAR_MIPMAP_LINEAR:
 
213
                        t->filter |= R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR;
 
214
                        break;
 
215
                }
 
216
        } else {
 
217
                switch (minf) {
 
218
                case GL_NEAREST:
 
219
                        t->filter |= R300_TX_MIN_FILTER_ANISO_NEAREST;
 
220
                        break;
 
221
                case GL_LINEAR:
 
222
                        t->filter |= R300_TX_MIN_FILTER_ANISO_LINEAR;
 
223
                        break;
 
224
                case GL_NEAREST_MIPMAP_NEAREST:
 
225
                case GL_LINEAR_MIPMAP_NEAREST:
 
226
                        t->filter |=
 
227
                            R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
 
228
                        break;
 
229
                case GL_NEAREST_MIPMAP_LINEAR:
 
230
                case GL_LINEAR_MIPMAP_LINEAR:
 
231
                        t->filter |=
 
232
                            R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
 
233
                        break;
 
234
                }
 
235
        }
 
236
 
 
237
        /* Note we don't have 3D mipmaps so only use the mag filter setting
 
238
         * to set the 3D texture filter mode.
 
239
         */
 
240
        switch (magf) {
 
241
        case GL_NEAREST:
 
242
                t->filter |= R300_TX_MAG_FILTER_NEAREST;
 
243
                break;
 
244
        case GL_LINEAR:
 
245
                t->filter |= R300_TX_MAG_FILTER_LINEAR;
 
246
                break;
 
247
        }
 
248
}
 
249
 
 
250
static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4])
 
251
{
 
252
        t->pp_border_color = PACK_COLOR_8888(c[0], c[1], c[2], c[3]);
 
253
}
 
254
 
 
255
/**
 
256
 * Allocate space for and load the mesa images into the texture memory block.
 
257
 * This will happen before drawing with a new texture, or drawing with a
 
258
 * texture after it was swapped out or teximaged again.
 
259
 */
 
260
 
 
261
static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj)
 
262
{
 
263
        r300TexObjPtr t;
 
264
 
 
265
        t = CALLOC_STRUCT(r300_tex_obj);
 
266
        texObj->DriverData = t;
 
267
        if (t != NULL) {
 
268
                if (RADEON_DEBUG & DEBUG_TEXTURE) {
 
269
                        fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
 
270
                                (void *)texObj, (void *)t);
 
271
                }
 
272
 
 
273
                /* Initialize non-image-dependent parts of the state:
 
274
                 */
 
275
                t->base.tObj = texObj;
 
276
                t->border_fallback = GL_FALSE;
 
277
 
 
278
                make_empty_list(&t->base);
 
279
 
 
280
                r300SetTexWrap(t, texObj->WrapS, texObj->WrapT, texObj->WrapR);
 
281
                r300SetTexMaxAnisotropy(t, texObj->MaxAnisotropy);
 
282
                r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter);
 
283
                r300SetTexBorderColor(t, texObj->_BorderChan);
 
284
        }
 
285
 
 
286
        return t;
 
287
}
 
288
 
 
289
/* try to find a format which will only need a memcopy */
 
290
static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
 
291
                                                               GLenum srcType)
 
292
{
 
293
        const GLuint ui = 1;
 
294
        const GLubyte littleEndian = *((const GLubyte *)&ui);
 
295
 
 
296
        if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
 
297
            (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE
 
298
             && !littleEndian) || (srcFormat == GL_ABGR_EXT
 
299
                                   && srcType == GL_UNSIGNED_INT_8_8_8_8_REV)
 
300
            || (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE
 
301
                && littleEndian)) {
 
302
                return &_mesa_texformat_rgba8888;
 
303
        } else
 
304
            if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV)
 
305
                || (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE
 
306
                    && littleEndian) || (srcFormat == GL_ABGR_EXT
 
307
                                         && srcType == GL_UNSIGNED_INT_8_8_8_8)
 
308
                || (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE
 
309
                    && !littleEndian)) {
 
310
                return &_mesa_texformat_rgba8888_rev;
 
311
        } else if (srcFormat == GL_BGRA &&
 
312
                   ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
 
313
                    srcType == GL_UNSIGNED_INT_8_8_8_8)) {
 
314
                return &_mesa_texformat_argb8888_rev;
 
315
        } else if (srcFormat == GL_BGRA &&
 
316
                   ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
 
317
                    srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
 
318
                return &_mesa_texformat_argb8888;
 
319
        } else
 
320
                return _dri_texformat_argb8888;
 
321
}
 
322
 
 
323
static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
 
324
                                                               GLint
 
325
                                                               internalFormat,
 
326
                                                               GLenum format,
 
327
                                                               GLenum type)
 
328
{
 
329
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
330
        const GLboolean do32bpt =
 
331
            (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
 
332
        const GLboolean force16bpt =
 
333
            (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
 
334
        (void)format;
 
335
 
 
336
#if 0
 
337
        fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
 
338
                _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
 
339
                _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
 
340
        fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
 
341
#endif
 
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 :
 
351
                            _dri_texformat_argb1555;
 
352
                case GL_UNSIGNED_SHORT_4_4_4_4:
 
353
                case GL_UNSIGNED_SHORT_4_4_4_4_REV:
 
354
                        return _dri_texformat_argb4444;
 
355
                case GL_UNSIGNED_SHORT_5_5_5_1:
 
356
                case GL_UNSIGNED_SHORT_1_5_5_5_REV:
 
357
                        return _dri_texformat_argb1555;
 
358
                default:
 
359
                        return do32bpt ? r300Choose8888TexFormat(format, type) :
 
360
                            _dri_texformat_argb4444;
 
361
                }
 
362
 
 
363
        case 3:
 
364
        case GL_RGB:
 
365
        case GL_COMPRESSED_RGB:
 
366
                switch (type) {
 
367
                case GL_UNSIGNED_SHORT_4_4_4_4:
 
368
                case GL_UNSIGNED_SHORT_4_4_4_4_REV:
 
369
                        return _dri_texformat_argb4444;
 
370
                case GL_UNSIGNED_SHORT_5_5_5_1:
 
371
                case GL_UNSIGNED_SHORT_1_5_5_5_REV:
 
372
                        return _dri_texformat_argb1555;
 
373
                case GL_UNSIGNED_SHORT_5_6_5:
 
374
                case GL_UNSIGNED_SHORT_5_6_5_REV:
 
375
                        return _dri_texformat_rgb565;
 
376
                default:
 
377
                        return do32bpt ? _dri_texformat_argb8888 :
 
378
                            _dri_texformat_rgb565;
 
379
                }
 
380
 
 
381
        case GL_RGBA8:
 
382
        case GL_RGB10_A2:
 
383
        case GL_RGBA12:
 
384
        case GL_RGBA16:
 
385
                return !force16bpt ?
 
386
                    r300Choose8888TexFormat(format,
 
387
                                            type) : _dri_texformat_argb4444;
 
388
 
 
389
        case GL_RGBA4:
 
390
        case GL_RGBA2:
 
391
                return _dri_texformat_argb4444;
 
392
 
 
393
        case GL_RGB5_A1:
 
394
                return _dri_texformat_argb1555;
 
395
 
 
396
        case GL_RGB8:
 
397
        case GL_RGB10:
 
398
        case GL_RGB12:
 
399
        case GL_RGB16:
 
400
                return !force16bpt ? _dri_texformat_argb8888 :
 
401
                    _dri_texformat_rgb565;
 
402
 
 
403
        case GL_RGB5:
 
404
        case GL_RGB4:
 
405
        case GL_R3_G3_B2:
 
406
                return _dri_texformat_rgb565;
 
407
 
 
408
        case GL_ALPHA:
 
409
        case GL_ALPHA4:
 
410
        case GL_ALPHA8:
 
411
        case GL_ALPHA12:
 
412
        case GL_ALPHA16:
 
413
        case GL_COMPRESSED_ALPHA:
 
414
                return _dri_texformat_a8;
 
415
 
 
416
        case 1:
 
417
        case GL_LUMINANCE:
 
418
        case GL_LUMINANCE4:
 
419
        case GL_LUMINANCE8:
 
420
        case GL_LUMINANCE12:
 
421
        case GL_LUMINANCE16:
 
422
        case GL_COMPRESSED_LUMINANCE:
 
423
                return _dri_texformat_l8;
 
424
 
 
425
        case 2:
 
426
        case GL_LUMINANCE_ALPHA:
 
427
        case GL_LUMINANCE4_ALPHA4:
 
428
        case GL_LUMINANCE6_ALPHA2:
 
429
        case GL_LUMINANCE8_ALPHA8:
 
430
        case GL_LUMINANCE12_ALPHA4:
 
431
        case GL_LUMINANCE12_ALPHA12:
 
432
        case GL_LUMINANCE16_ALPHA16:
 
433
        case GL_COMPRESSED_LUMINANCE_ALPHA:
 
434
                return _dri_texformat_al88;
 
435
 
 
436
        case GL_INTENSITY:
 
437
        case GL_INTENSITY4:
 
438
        case GL_INTENSITY8:
 
439
        case GL_INTENSITY12:
 
440
        case GL_INTENSITY16:
 
441
        case GL_COMPRESSED_INTENSITY:
 
442
                return _dri_texformat_i8;
 
443
 
 
444
        case GL_YCBCR_MESA:
 
445
                if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
 
446
                    type == GL_UNSIGNED_BYTE)
 
447
                        return &_mesa_texformat_ycbcr;
 
448
                else
 
449
                        return &_mesa_texformat_ycbcr_rev;
 
450
 
 
451
        case GL_RGB_S3TC:
 
452
        case GL_RGB4_S3TC:
 
453
        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
 
454
                return &_mesa_texformat_rgb_dxt1;
 
455
 
 
456
        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
 
457
                return &_mesa_texformat_rgba_dxt1;
 
458
 
 
459
        case GL_RGBA_S3TC:
 
460
        case GL_RGBA4_S3TC:
 
461
        case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
 
462
                return &_mesa_texformat_rgba_dxt3;
 
463
 
 
464
        case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
 
465
                return &_mesa_texformat_rgba_dxt5;
 
466
 
 
467
        case GL_ALPHA16F_ARB:
 
468
                return &_mesa_texformat_alpha_float16;
 
469
        case GL_ALPHA32F_ARB:
 
470
                return &_mesa_texformat_alpha_float32;
 
471
        case GL_LUMINANCE16F_ARB:
 
472
                return &_mesa_texformat_luminance_float16;
 
473
        case GL_LUMINANCE32F_ARB:
 
474
                return &_mesa_texformat_luminance_float32;
 
475
        case GL_LUMINANCE_ALPHA16F_ARB:
 
476
                return &_mesa_texformat_luminance_alpha_float16;
 
477
        case GL_LUMINANCE_ALPHA32F_ARB:
 
478
                return &_mesa_texformat_luminance_alpha_float32;
 
479
        case GL_INTENSITY16F_ARB:
 
480
                return &_mesa_texformat_intensity_float16;
 
481
        case GL_INTENSITY32F_ARB:
 
482
                return &_mesa_texformat_intensity_float32;
 
483
        case GL_RGB16F_ARB:
 
484
                return &_mesa_texformat_rgba_float16;
 
485
        case GL_RGB32F_ARB:
 
486
                return &_mesa_texformat_rgba_float32;
 
487
        case GL_RGBA16F_ARB:
 
488
                return &_mesa_texformat_rgba_float16;
 
489
        case GL_RGBA32F_ARB:
 
490
                return &_mesa_texformat_rgba_float32;
 
491
 
 
492
        default:
 
493
                _mesa_problem(ctx,
 
494
                              "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
 
495
                              (int)internalFormat);
 
496
                return NULL;
 
497
        }
 
498
 
 
499
        return NULL;            /* never get here */
 
500
}
 
501
 
 
502
static GLboolean
 
503
r300ValidateClientStorage(GLcontext * ctx, GLenum target,
 
504
                          GLint internalFormat,
 
505
                          GLint srcWidth, GLint srcHeight,
 
506
                          GLenum format, GLenum type, const void *pixels,
 
507
                          const struct gl_pixelstore_attrib *packing,
 
508
                          struct gl_texture_object *texObj,
 
509
                          struct gl_texture_image *texImage)
 
510
{
 
511
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
512
 
 
513
        if (RADEON_DEBUG & DEBUG_TEXTURE)
 
514
                fprintf(stderr, "intformat %s format %s type %s\n",
 
515
                        _mesa_lookup_enum_by_nr(internalFormat),
 
516
                        _mesa_lookup_enum_by_nr(format),
 
517
                        _mesa_lookup_enum_by_nr(type));
 
518
 
 
519
        if (!ctx->Unpack.ClientStorage)
 
520
                return 0;
 
521
 
 
522
        if (ctx->_ImageTransferState ||
 
523
            texImage->IsCompressed || texObj->GenerateMipmap)
 
524
                return 0;
 
525
 
 
526
        /* This list is incomplete, may be different on ppc???
 
527
         */
 
528
        switch (internalFormat) {
 
529
        case GL_RGBA:
 
530
                if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) {
 
531
                        texImage->TexFormat = _dri_texformat_argb8888;
 
532
                } else
 
533
                        return 0;
 
534
                break;
 
535
 
 
536
        case GL_RGB:
 
537
                if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
 
538
                        texImage->TexFormat = _dri_texformat_rgb565;
 
539
                } else
 
540
                        return 0;
 
541
                break;
 
542
 
 
543
        case GL_YCBCR_MESA:
 
544
                if (format == GL_YCBCR_MESA &&
 
545
                    type == GL_UNSIGNED_SHORT_8_8_REV_APPLE) {
 
546
                        texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
 
547
                } else if (format == GL_YCBCR_MESA &&
 
548
                           (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
 
549
                            type == GL_UNSIGNED_BYTE)) {
 
550
                        texImage->TexFormat = &_mesa_texformat_ycbcr;
 
551
                } else
 
552
                        return 0;
 
553
                break;
 
554
 
 
555
        default:
 
556
                return 0;
 
557
        }
 
558
 
 
559
        /* Could deal with these packing issues, but currently don't:
 
560
         */
 
561
        if (packing->SkipPixels ||
 
562
            packing->SkipRows || packing->SwapBytes || packing->LsbFirst) {
 
563
                return 0;
 
564
        }
 
565
 
 
566
        {
 
567
                GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
 
568
                                                            format, type);
 
569
 
 
570
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
571
                        fprintf(stderr, "%s: srcRowStride %d/%x\n",
 
572
                                __FUNCTION__, srcRowStride, srcRowStride);
 
573
 
 
574
                /* Could check this later in upload, pitch restrictions could be
 
575
                 * relaxed, but would need to store the image pitch somewhere,
 
576
                 * as packing details might change before image is uploaded:
 
577
                 */
 
578
                if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
 
579
                    || (srcRowStride & 63))
 
580
                        return 0;
 
581
 
 
582
                /* Have validated that _mesa_transfer_teximage would be a straight
 
583
                 * memcpy at this point.  NOTE: future calls to TexSubImage will
 
584
                 * overwrite the client data.  This is explicitly mentioned in the
 
585
                 * extension spec.
 
586
                 */
 
587
                texImage->Data = (void *)pixels;
 
588
                texImage->IsClientData = GL_TRUE;
 
589
                texImage->RowStride =
 
590
                    srcRowStride / texImage->TexFormat->TexelBytes;
 
591
 
 
592
                return 1;
 
593
        }
 
594
}
 
595
 
 
596
static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level,
 
597
                           GLint internalFormat,
 
598
                           GLint width, GLint border,
 
599
                           GLenum format, GLenum type, const GLvoid * pixels,
 
600
                           const struct gl_pixelstore_attrib *packing,
 
601
                           struct gl_texture_object *texObj,
 
602
                           struct gl_texture_image *texImage)
 
603
{
 
604
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
605
 
 
606
        if (t) {
 
607
                driSwapOutTextureObject(t);
 
608
        } else {
 
609
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
610
                if (!t) {
 
611
                        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
 
612
                        return;
 
613
                }
 
614
        }
 
615
 
 
616
        /* Note, this will call ChooseTextureFormat */
 
617
        _mesa_store_teximage1d(ctx, target, level, internalFormat,
 
618
                               width, border, format, type, pixels,
 
619
                               &ctx->Unpack, texObj, texImage);
 
620
 
 
621
        t->dirty_images[0] |= (1 << level);
 
622
}
 
623
 
 
624
static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
 
625
                              GLint xoffset,
 
626
                              GLsizei width,
 
627
                              GLenum format, GLenum type,
 
628
                              const GLvoid * pixels,
 
629
                              const struct gl_pixelstore_attrib *packing,
 
630
                              struct gl_texture_object *texObj,
 
631
                              struct gl_texture_image *texImage)
 
632
{
 
633
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
634
 
 
635
        assert(t);              /* this _should_ be true */
 
636
        if (t) {
 
637
                driSwapOutTextureObject(t);
 
638
        } else {
 
639
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
640
                if (!t) {
 
641
                        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
 
642
                        return;
 
643
                }
 
644
        }
 
645
 
 
646
        _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
 
647
                                  format, type, pixels, packing, texObj,
 
648
                                  texImage);
 
649
 
 
650
        t->dirty_images[0] |= (1 << level);
 
651
}
 
652
 
 
653
static void r300TexImage2D(GLcontext * ctx, GLenum target, GLint level,
 
654
                           GLint internalFormat,
 
655
                           GLint width, GLint height, GLint border,
 
656
                           GLenum format, GLenum type, const GLvoid * pixels,
 
657
                           const struct gl_pixelstore_attrib *packing,
 
658
                           struct gl_texture_object *texObj,
 
659
                           struct gl_texture_image *texImage)
 
660
{
 
661
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
662
        GLuint face;
 
663
 
 
664
        /* which cube face or ordinary 2D image */
 
665
        switch (target) {
 
666
        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
 
667
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
 
668
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
 
669
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
 
670
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
 
671
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
 
672
                face =
 
673
                    (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
 
674
                ASSERT(face < 6);
 
675
                break;
 
676
        default:
 
677
                face = 0;
 
678
        }
 
679
 
 
680
        if (t != NULL) {
 
681
                driSwapOutTextureObject(t);
 
682
        } else {
 
683
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
684
                if (!t) {
 
685
                        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
 
686
                        return;
 
687
                }
 
688
        }
 
689
 
 
690
        texImage->IsClientData = GL_FALSE;
 
691
 
 
692
        if (r300ValidateClientStorage(ctx, target,
 
693
                                      internalFormat,
 
694
                                      width, height,
 
695
                                      format, type, pixels,
 
696
                                      packing, texObj, texImage)) {
 
697
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
698
                        fprintf(stderr, "%s: Using client storage\n",
 
699
                                __FUNCTION__);
 
700
        } else {
 
701
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
702
                        fprintf(stderr, "%s: Using normal storage\n",
 
703
                                __FUNCTION__);
 
704
 
 
705
                /* Normal path: copy (to cached memory) and eventually upload
 
706
                 * via another copy to GART memory and then a blit...  Could
 
707
                 * eliminate one copy by going straight to (permanent) GART.
 
708
                 *
 
709
                 * Note, this will call r300ChooseTextureFormat.
 
710
                 */
 
711
                _mesa_store_teximage2d(ctx, target, level, internalFormat,
 
712
                                       width, height, border, format, type,
 
713
                                       pixels, &ctx->Unpack, texObj, texImage);
 
714
 
 
715
                t->dirty_images[face] |= (1 << level);
 
716
        }
 
717
}
 
718
 
 
719
static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
 
720
                              GLint xoffset, GLint yoffset,
 
721
                              GLsizei width, GLsizei height,
 
722
                              GLenum format, GLenum type,
 
723
                              const GLvoid * pixels,
 
724
                              const struct gl_pixelstore_attrib *packing,
 
725
                              struct gl_texture_object *texObj,
 
726
                              struct gl_texture_image *texImage)
 
727
{
 
728
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
729
        GLuint face;
 
730
 
 
731
        /* which cube face or ordinary 2D image */
 
732
        switch (target) {
 
733
        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
 
734
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
 
735
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
 
736
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
 
737
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
 
738
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
 
739
                face =
 
740
                    (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
 
741
                ASSERT(face < 6);
 
742
                break;
 
743
        default:
 
744
                face = 0;
 
745
        }
 
746
 
 
747
        assert(t);              /* this _should_ be true */
 
748
        if (t) {
 
749
                driSwapOutTextureObject(t);
 
750
        } else {
 
751
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
752
                if (!t) {
 
753
                        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
 
754
                        return;
 
755
                }
 
756
        }
 
757
 
 
758
        _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
 
759
                                  height, format, type, pixels, packing, texObj,
 
760
                                  texImage);
 
761
 
 
762
        t->dirty_images[face] |= (1 << level);
 
763
}
 
764
 
 
765
static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target,
 
766
                                     GLint level, GLint internalFormat,
 
767
                                     GLint width, GLint height, GLint border,
 
768
                                     GLsizei imageSize, const GLvoid * data,
 
769
                                     struct gl_texture_object *texObj,
 
770
                                     struct gl_texture_image *texImage)
 
771
{
 
772
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
773
        GLuint face;
 
774
 
 
775
        /* which cube face or ordinary 2D image */
 
776
        switch (target) {
 
777
        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
 
778
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
 
779
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
 
780
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
 
781
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
 
782
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
 
783
                face =
 
784
                    (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
 
785
                ASSERT(face < 6);
 
786
                break;
 
787
        default:
 
788
                face = 0;
 
789
        }
 
790
 
 
791
        if (t != NULL) {
 
792
                driSwapOutTextureObject(t);
 
793
        } else {
 
794
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
795
                if (!t) {
 
796
                        _mesa_error(ctx, GL_OUT_OF_MEMORY,
 
797
                                    "glCompressedTexImage2D");
 
798
                        return;
 
799
                }
 
800
        }
 
801
 
 
802
        texImage->IsClientData = GL_FALSE;
 
803
 
 
804
        /* can't call this, different parameters. Would never evaluate to true anyway currently */
 
805
#if 0
 
806
        if (r300ValidateClientStorage(ctx, target,
 
807
                                      internalFormat,
 
808
                                      width, height,
 
809
                                      format, type, pixels,
 
810
                                      packing, texObj, texImage)) {
 
811
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
812
                        fprintf(stderr, "%s: Using client storage\n",
 
813
                                __FUNCTION__);
 
814
        } else
 
815
#endif
 
816
        {
 
817
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
818
                        fprintf(stderr, "%s: Using normal storage\n",
 
819
                                __FUNCTION__);
 
820
 
 
821
                /* Normal path: copy (to cached memory) and eventually upload
 
822
                 * via another copy to GART memory and then a blit...  Could
 
823
                 * eliminate one copy by going straight to (permanent) GART.
 
824
                 *
 
825
                 * Note, this will call r300ChooseTextureFormat.
 
826
                 */
 
827
                _mesa_store_compressed_teximage2d(ctx, target, level,
 
828
                                                  internalFormat, width, height,
 
829
                                                  border, imageSize, data,
 
830
                                                  texObj, texImage);
 
831
 
 
832
                t->dirty_images[face] |= (1 << level);
 
833
        }
 
834
}
 
835
 
 
836
static void r300CompressedTexSubImage2D(GLcontext * ctx, GLenum target,
 
837
                                        GLint level, GLint xoffset,
 
838
                                        GLint yoffset, GLsizei width,
 
839
                                        GLsizei height, GLenum format,
 
840
                                        GLsizei imageSize, const GLvoid * data,
 
841
                                        struct gl_texture_object *texObj,
 
842
                                        struct gl_texture_image *texImage)
 
843
{
 
844
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
845
        GLuint face;
 
846
 
 
847
        /* which cube face or ordinary 2D image */
 
848
        switch (target) {
 
849
        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
 
850
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
 
851
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
 
852
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
 
853
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
 
854
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
 
855
                face =
 
856
                    (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
 
857
                ASSERT(face < 6);
 
858
                break;
 
859
        default:
 
860
                face = 0;
 
861
        }
 
862
 
 
863
        assert(t);              /* this _should_ be true */
 
864
        if (t) {
 
865
                driSwapOutTextureObject(t);
 
866
        } else {
 
867
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
868
                if (!t) {
 
869
                        _mesa_error(ctx, GL_OUT_OF_MEMORY,
 
870
                                    "glCompressedTexSubImage3D");
 
871
                        return;
 
872
                }
 
873
        }
 
874
 
 
875
        _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset,
 
876
                                             yoffset, width, height, format,
 
877
                                             imageSize, data, texObj, texImage);
 
878
 
 
879
        t->dirty_images[face] |= (1 << level);
 
880
}
 
881
 
 
882
static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
 
883
                           GLint internalFormat,
 
884
                           GLint width, GLint height, GLint depth,
 
885
                           GLint border,
 
886
                           GLenum format, GLenum type, const GLvoid * pixels,
 
887
                           const struct gl_pixelstore_attrib *packing,
 
888
                           struct gl_texture_object *texObj,
 
889
                           struct gl_texture_image *texImage)
 
890
{
 
891
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
892
 
 
893
        if (t) {
 
894
                driSwapOutTextureObject(t);
 
895
        } else {
 
896
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
897
                if (!t) {
 
898
                        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
 
899
                        return;
 
900
                }
 
901
        }
 
902
 
 
903
        texImage->IsClientData = GL_FALSE;
 
904
 
 
905
#if 0
 
906
        if (r300ValidateClientStorage(ctx, target,
 
907
                                      internalFormat,
 
908
                                      width, height,
 
909
                                      format, type, pixels,
 
910
                                      packing, texObj, texImage)) {
 
911
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
912
                        fprintf(stderr, "%s: Using client storage\n",
 
913
                                __FUNCTION__);
 
914
        } else
 
915
#endif
 
916
        {
 
917
                if (RADEON_DEBUG & DEBUG_TEXTURE)
 
918
                        fprintf(stderr, "%s: Using normal storage\n",
 
919
                                __FUNCTION__);
 
920
 
 
921
                /* Normal path: copy (to cached memory) and eventually upload
 
922
                 * via another copy to GART memory and then a blit...  Could
 
923
                 * eliminate one copy by going straight to (permanent) GART.
 
924
                 *
 
925
                 * Note, this will call r300ChooseTextureFormat.
 
926
                 */
 
927
                _mesa_store_teximage3d(ctx, target, level, internalFormat,
 
928
                                       width, height, depth, border,
 
929
                                       format, type, pixels,
 
930
                                       &ctx->Unpack, texObj, texImage);
 
931
 
 
932
                t->dirty_images[0] |= (1 << level);
 
933
        }
 
934
}
 
935
 
 
936
static void
 
937
r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
 
938
                  GLint xoffset, GLint yoffset, GLint zoffset,
 
939
                  GLsizei width, GLsizei height, GLsizei depth,
 
940
                  GLenum format, GLenum type,
 
941
                  const GLvoid * pixels,
 
942
                  const struct gl_pixelstore_attrib *packing,
 
943
                  struct gl_texture_object *texObj,
 
944
                  struct gl_texture_image *texImage)
 
945
{
 
946
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
947
 
 
948
/*     fprintf(stderr, "%s\n", __FUNCTION__); */
 
949
 
 
950
        assert(t);              /* this _should_ be true */
 
951
        if (t) {
 
952
                driSwapOutTextureObject(t);
 
953
        } else {
 
954
                t = (driTextureObject *) r300AllocTexObj(texObj);
 
955
                if (!t) {
 
956
                        _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
 
957
                        return;
 
958
                }
 
959
                texObj->DriverData = t;
 
960
        }
 
961
 
 
962
        _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
 
963
                                  width, height, depth,
 
964
                                  format, type, pixels, packing, texObj,
 
965
                                  texImage);
 
966
 
 
967
        t->dirty_images[0] |= (1 << level);
 
968
}
 
969
 
 
970
static void r300TexEnv(GLcontext * ctx, GLenum target,
 
971
                       GLenum pname, const GLfloat * param)
 
972
{
 
973
        if (RADEON_DEBUG & DEBUG_STATE) {
 
974
                fprintf(stderr, "%s( %s )\n",
 
975
                        __FUNCTION__, _mesa_lookup_enum_by_nr(pname));
 
976
        }
 
977
 
 
978
        /* This is incorrect: Need to maintain this data for each of
 
979
         * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
 
980
         * between them according to _ReallyEnabled.
 
981
         */
 
982
        switch (pname) {
 
983
        case GL_TEXTURE_LOD_BIAS_EXT:{
 
984
#if 0                           /* Needs to be relocated in order to make sure we got the right tmu */
 
985
                        GLfloat bias, min;
 
986
                        GLuint b;
 
987
 
 
988
                        /* The R300's LOD bias is a signed 2's complement value with a
 
989
                         * range of -16.0 <= bias < 16.0.
 
990
                         *
 
991
                         * NOTE: Add a small bias to the bias for conform mipsel.c test.
 
992
                         */
 
993
                        bias = *param + .01;
 
994
                        min =
 
995
                            driQueryOptionb(&rmesa->radeon.optionCache,
 
996
                                            "no_neg_lod_bias") ? 0.0 : -16.0;
 
997
                        bias = CLAMP(bias, min, 16.0);
 
998
 
 
999
                        /* 0.0 - 16.0 == 0x0 - 0x1000 */
 
1000
                        /* 0.0 - -16.0 == 0x1001 - 0x1fff */
 
1001
                        b = 0x1000 / 16.0 * bias;
 
1002
                        b &= R300_LOD_BIAS_MASK;
 
1003
 
 
1004
                        if (b !=
 
1005
                            (rmesa->hw.tex.unknown1.
 
1006
                             cmd[R300_TEX_VALUE_0 +
 
1007
                                 unit] & R300_LOD_BIAS_MASK)) {
 
1008
                                R300_STATECHANGE(rmesa, tex.unknown1);
 
1009
                                rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0 +
 
1010
                                                           unit] &=
 
1011
                                    ~R300_LOD_BIAS_MASK;
 
1012
                                rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0 +
 
1013
                                                           unit] |= b;
 
1014
                        }
 
1015
#endif
 
1016
                        break;
 
1017
                }
 
1018
 
 
1019
        default:
 
1020
                return;
 
1021
        }
 
1022
}
 
1023
 
 
1024
/**
 
1025
 * Changes variables and flags for a state update, which will happen at the
 
1026
 * next UpdateTextureState
 
1027
 */
 
1028
 
 
1029
static void r300TexParameter(GLcontext * ctx, GLenum target,
 
1030
                             struct gl_texture_object *texObj,
 
1031
                             GLenum pname, const GLfloat * params)
 
1032
{
 
1033
        r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData;
 
1034
 
 
1035
        if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
 
1036
                fprintf(stderr, "%s( %s )\n", __FUNCTION__,
 
1037
                        _mesa_lookup_enum_by_nr(pname));
 
1038
        }
 
1039
 
 
1040
        switch (pname) {
 
1041
        case GL_TEXTURE_MIN_FILTER:
 
1042
        case GL_TEXTURE_MAG_FILTER:
 
1043
        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
 
1044
                r300SetTexMaxAnisotropy(t, texObj->MaxAnisotropy);
 
1045
                r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter);
 
1046
                break;
 
1047
 
 
1048
        case GL_TEXTURE_WRAP_S:
 
1049
        case GL_TEXTURE_WRAP_T:
 
1050
        case GL_TEXTURE_WRAP_R:
 
1051
                r300SetTexWrap(t, texObj->WrapS, texObj->WrapT, texObj->WrapR);
 
1052
                break;
 
1053
 
 
1054
        case GL_TEXTURE_BORDER_COLOR:
 
1055
                r300SetTexBorderColor(t, texObj->_BorderChan);
 
1056
                break;
 
1057
 
 
1058
        case GL_TEXTURE_BASE_LEVEL:
 
1059
        case GL_TEXTURE_MAX_LEVEL:
 
1060
        case GL_TEXTURE_MIN_LOD:
 
1061
        case GL_TEXTURE_MAX_LOD:
 
1062
                /* This isn't the most efficient solution but there doesn't appear to
 
1063
                 * be a nice alternative.  Since there's no LOD clamping,
 
1064
                 * we just have to rely on loading the right subset of mipmap levels
 
1065
                 * to simulate a clamped LOD.
 
1066
                 */
 
1067
                driSwapOutTextureObject((driTextureObject *) t);
 
1068
                break;
 
1069
 
 
1070
        default:
 
1071
                return;
 
1072
        }
 
1073
 
 
1074
        /* Mark this texobj as dirty (one bit per tex unit)
 
1075
         */
 
1076
        t->dirty_state = TEX_ALL;
 
1077
}
 
1078
 
 
1079
static void r300BindTexture(GLcontext * ctx, GLenum target,
 
1080
                            struct gl_texture_object *texObj)
 
1081
{
 
1082
        if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
 
1083
                fprintf(stderr, "%s( %p ) unit=%d\n", __FUNCTION__,
 
1084
                        (void *)texObj, ctx->Texture.CurrentUnit);
 
1085
        }
 
1086
 
 
1087
        if ((target == GL_TEXTURE_1D)
 
1088
            || (target == GL_TEXTURE_2D)
 
1089
            || (target == GL_TEXTURE_3D)
 
1090
            || (target == GL_TEXTURE_CUBE_MAP)
 
1091
            || (target == GL_TEXTURE_RECTANGLE_NV)) {
 
1092
                assert(texObj->DriverData != NULL);
 
1093
        }
 
1094
}
 
1095
 
 
1096
static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
 
1097
{
 
1098
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
1099
        driTextureObject *t = (driTextureObject *) texObj->DriverData;
 
1100
 
 
1101
        if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
 
1102
                fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
 
1103
                        (void *)texObj,
 
1104
                        _mesa_lookup_enum_by_nr(texObj->Target));
 
1105
        }
 
1106
 
 
1107
        if (t != NULL) {
 
1108
                if (rmesa) {
 
1109
                        R300_FIREVERTICES(rmesa);
 
1110
                }
 
1111
 
 
1112
                driDestroyTextureObject(t);
 
1113
        }
 
1114
        /* Free mipmap images and the texture object itself */
 
1115
        _mesa_delete_texture_object(ctx, texObj);
 
1116
}
 
1117
 
 
1118
/**
 
1119
 * Allocate a new texture object.
 
1120
 * Called via ctx->Driver.NewTextureObject.
 
1121
 * Note: this function will be called during context creation to
 
1122
 * allocate the default texture objects.
 
1123
 * Note: we could use containment here to 'derive' the driver-specific
 
1124
 * texture object from the core mesa gl_texture_object.  Not done at this time.
 
1125
 * Fixup MaxAnisotropy according to user preference.
 
1126
 */
 
1127
static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
 
1128
                                                      GLuint name,
 
1129
                                                      GLenum target)
 
1130
{
 
1131
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
1132
        struct gl_texture_object *obj;
 
1133
        obj = _mesa_new_texture_object(ctx, name, target);
 
1134
        if (!obj)
 
1135
                return NULL;
 
1136
        obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
 
1137
 
 
1138
        r300AllocTexObj(obj);
 
1139
        return obj;
 
1140
}
 
1141
 
 
1142
void r300InitTextureFuncs(struct dd_function_table *functions)
 
1143
{
 
1144
        /* Note: we only plug in the functions we implement in the driver
 
1145
         * since _mesa_init_driver_functions() was already called.
 
1146
         */
 
1147
        functions->ChooseTextureFormat = r300ChooseTextureFormat;
 
1148
        functions->TexImage1D = r300TexImage1D;
 
1149
        functions->TexImage2D = r300TexImage2D;
 
1150
        functions->TexImage3D = r300TexImage3D;
 
1151
        functions->TexSubImage1D = r300TexSubImage1D;
 
1152
        functions->TexSubImage2D = r300TexSubImage2D;
 
1153
        functions->TexSubImage3D = r300TexSubImage3D;
 
1154
        functions->NewTextureObject = r300NewTextureObject;
 
1155
        functions->BindTexture = r300BindTexture;
 
1156
        functions->DeleteTexture = r300DeleteTexture;
 
1157
        functions->IsTextureResident = driIsTextureResident;
 
1158
 
 
1159
        functions->TexEnv = r300TexEnv;
 
1160
        functions->TexParameter = r300TexParameter;
 
1161
 
 
1162
        functions->CompressedTexImage2D = r300CompressedTexImage2D;
 
1163
        functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
 
1164
 
 
1165
        driInitTextureFormats();
 
1166
}