2
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
32
* \author Keith Whitwell <keith@tungstengraphics.com>
41
#include "simple_list.h"
42
#include "texformat.h"
48
#include "r300_context.h"
49
#include "r300_state.h"
50
#include "r300_ioctl.h"
56
* Set the texture wrap modes.
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
63
static void r300SetTexWrap(r300TexObjPtr t, GLenum swrap, GLenum twrap,
66
unsigned long hw_swrap = 0, hw_twrap = 0, hw_qwrap = 0;
69
~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_Q_MASK);
73
hw_swrap |= R300_TX_REPEAT;
76
hw_swrap |= R300_TX_CLAMP;
78
case GL_CLAMP_TO_EDGE:
79
hw_swrap |= R300_TX_CLAMP_TO_EDGE;
81
case GL_CLAMP_TO_BORDER:
82
hw_swrap |= R300_TX_CLAMP_TO_BORDER;
84
case GL_MIRRORED_REPEAT:
85
hw_swrap |= R300_TX_REPEAT | R300_TX_MIRRORED;
87
case GL_MIRROR_CLAMP_EXT:
88
hw_swrap |= R300_TX_CLAMP | R300_TX_MIRRORED;
90
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
91
hw_swrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
93
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
94
hw_swrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
97
_mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
102
hw_twrap |= R300_TX_REPEAT;
105
hw_twrap |= R300_TX_CLAMP;
107
case GL_CLAMP_TO_EDGE:
108
hw_twrap |= R300_TX_CLAMP_TO_EDGE;
110
case GL_CLAMP_TO_BORDER:
111
hw_twrap |= R300_TX_CLAMP_TO_BORDER;
113
case GL_MIRRORED_REPEAT:
114
hw_twrap |= R300_TX_REPEAT | R300_TX_MIRRORED;
116
case GL_MIRROR_CLAMP_EXT:
117
hw_twrap |= R300_TX_CLAMP | R300_TX_MIRRORED;
119
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
120
hw_twrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
122
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
123
hw_twrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
126
_mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
131
hw_qwrap |= R300_TX_REPEAT;
134
hw_qwrap |= R300_TX_CLAMP;
136
case GL_CLAMP_TO_EDGE:
137
hw_qwrap |= R300_TX_CLAMP_TO_EDGE;
139
case GL_CLAMP_TO_BORDER:
140
hw_qwrap |= R300_TX_CLAMP_TO_BORDER;
142
case GL_MIRRORED_REPEAT:
143
hw_qwrap |= R300_TX_REPEAT | R300_TX_MIRRORED;
145
case GL_MIRROR_CLAMP_EXT:
146
hw_qwrap |= R300_TX_CLAMP | R300_TX_MIRRORED;
148
case GL_MIRROR_CLAMP_TO_EDGE_EXT:
149
hw_qwrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
151
case GL_MIRROR_CLAMP_TO_BORDER_EXT:
152
hw_qwrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
155
_mesa_problem(NULL, "bad R wrap mode in %s", __FUNCTION__);
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;
163
static void r300SetTexMaxAnisotropy(r300TexObjPtr t, GLfloat max)
166
t->filter &= ~R300_TX_MAX_ANISO_MASK;
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;
177
t->filter |= R300_TX_MAX_ANISO_16_TO_1;
182
* Set the texture magnification and minification modes.
184
* \param t Texture whose filter modes are to be set
185
* \param minf Texture minification mode
186
* \param magf Texture magnification mode
189
static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf)
191
GLuint anisotropy = (t->filter & R300_TX_MAX_ANISO_MASK);
193
t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK);
195
if (anisotropy == R300_TX_MAX_ANISO_1_TO_1) {
198
t->filter |= R300_TX_MIN_FILTER_NEAREST;
201
t->filter |= R300_TX_MIN_FILTER_LINEAR;
203
case GL_NEAREST_MIPMAP_NEAREST:
204
t->filter |= R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST;
206
case GL_NEAREST_MIPMAP_LINEAR:
207
t->filter |= R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR;
209
case GL_LINEAR_MIPMAP_NEAREST:
210
t->filter |= R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST;
212
case GL_LINEAR_MIPMAP_LINEAR:
213
t->filter |= R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR;
219
t->filter |= R300_TX_MIN_FILTER_ANISO_NEAREST;
222
t->filter |= R300_TX_MIN_FILTER_ANISO_LINEAR;
224
case GL_NEAREST_MIPMAP_NEAREST:
225
case GL_LINEAR_MIPMAP_NEAREST:
227
R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST;
229
case GL_NEAREST_MIPMAP_LINEAR:
230
case GL_LINEAR_MIPMAP_LINEAR:
232
R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR;
237
/* Note we don't have 3D mipmaps so only use the mag filter setting
238
* to set the 3D texture filter mode.
242
t->filter |= R300_TX_MAG_FILTER_NEAREST;
245
t->filter |= R300_TX_MAG_FILTER_LINEAR;
250
static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4])
252
t->pp_border_color = PACK_COLOR_8888(c[0], c[1], c[2], c[3]);
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.
261
static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj)
265
t = CALLOC_STRUCT(r300_tex_obj);
266
texObj->DriverData = t;
268
if (RADEON_DEBUG & DEBUG_TEXTURE) {
269
fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
270
(void *)texObj, (void *)t);
273
/* Initialize non-image-dependent parts of the state:
275
t->base.tObj = texObj;
276
t->border_fallback = GL_FALSE;
278
make_empty_list(&t->base);
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);
289
/* try to find a format which will only need a memcopy */
290
static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
294
const GLubyte littleEndian = *((const GLubyte *)&ui);
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
302
return &_mesa_texformat_rgba8888;
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
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;
320
return _dri_texformat_argb8888;
323
static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
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);
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);
343
switch (internalFormat) {
346
case GL_COMPRESSED_RGBA:
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;
359
return do32bpt ? r300Choose8888TexFormat(format, type) :
360
_dri_texformat_argb4444;
365
case GL_COMPRESSED_RGB:
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;
377
return do32bpt ? _dri_texformat_argb8888 :
378
_dri_texformat_rgb565;
386
r300Choose8888TexFormat(format,
387
type) : _dri_texformat_argb4444;
391
return _dri_texformat_argb4444;
394
return _dri_texformat_argb1555;
400
return !force16bpt ? _dri_texformat_argb8888 :
401
_dri_texformat_rgb565;
406
return _dri_texformat_rgb565;
413
case GL_COMPRESSED_ALPHA:
414
return _dri_texformat_a8;
422
case GL_COMPRESSED_LUMINANCE:
423
return _dri_texformat_l8;
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;
441
case GL_COMPRESSED_INTENSITY:
442
return _dri_texformat_i8;
445
if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
446
type == GL_UNSIGNED_BYTE)
447
return &_mesa_texformat_ycbcr;
449
return &_mesa_texformat_ycbcr_rev;
453
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
454
return &_mesa_texformat_rgb_dxt1;
456
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
457
return &_mesa_texformat_rgba_dxt1;
461
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
462
return &_mesa_texformat_rgba_dxt3;
464
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
465
return &_mesa_texformat_rgba_dxt5;
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;
484
return &_mesa_texformat_rgba_float16;
486
return &_mesa_texformat_rgba_float32;
488
return &_mesa_texformat_rgba_float16;
490
return &_mesa_texformat_rgba_float32;
494
"unexpected internalFormat 0x%x in r300ChooseTextureFormat",
495
(int)internalFormat);
499
return NULL; /* never get here */
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)
511
r300ContextPtr rmesa = R300_CONTEXT(ctx);
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));
519
if (!ctx->Unpack.ClientStorage)
522
if (ctx->_ImageTransferState ||
523
texImage->IsCompressed || texObj->GenerateMipmap)
526
/* This list is incomplete, may be different on ppc???
528
switch (internalFormat) {
530
if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) {
531
texImage->TexFormat = _dri_texformat_argb8888;
537
if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
538
texImage->TexFormat = _dri_texformat_rgb565;
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;
559
/* Could deal with these packing issues, but currently don't:
561
if (packing->SkipPixels ||
562
packing->SkipRows || packing->SwapBytes || packing->LsbFirst) {
567
GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
570
if (RADEON_DEBUG & DEBUG_TEXTURE)
571
fprintf(stderr, "%s: srcRowStride %d/%x\n",
572
__FUNCTION__, srcRowStride, srcRowStride);
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:
578
if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
579
|| (srcRowStride & 63))
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
587
texImage->Data = (void *)pixels;
588
texImage->IsClientData = GL_TRUE;
589
texImage->RowStride =
590
srcRowStride / texImage->TexFormat->TexelBytes;
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)
604
driTextureObject *t = (driTextureObject *) texObj->DriverData;
607
driSwapOutTextureObject(t);
609
t = (driTextureObject *) r300AllocTexObj(texObj);
611
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
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);
621
t->dirty_images[0] |= (1 << level);
624
static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
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)
633
driTextureObject *t = (driTextureObject *) texObj->DriverData;
635
assert(t); /* this _should_ be true */
637
driSwapOutTextureObject(t);
639
t = (driTextureObject *) r300AllocTexObj(texObj);
641
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
646
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
647
format, type, pixels, packing, texObj,
650
t->dirty_images[0] |= (1 << level);
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)
661
driTextureObject *t = (driTextureObject *) texObj->DriverData;
664
/* which cube face or ordinary 2D image */
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:
673
(GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
681
driSwapOutTextureObject(t);
683
t = (driTextureObject *) r300AllocTexObj(texObj);
685
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
690
texImage->IsClientData = GL_FALSE;
692
if (r300ValidateClientStorage(ctx, target,
695
format, type, pixels,
696
packing, texObj, texImage)) {
697
if (RADEON_DEBUG & DEBUG_TEXTURE)
698
fprintf(stderr, "%s: Using client storage\n",
701
if (RADEON_DEBUG & DEBUG_TEXTURE)
702
fprintf(stderr, "%s: Using normal storage\n",
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.
709
* Note, this will call r300ChooseTextureFormat.
711
_mesa_store_teximage2d(ctx, target, level, internalFormat,
712
width, height, border, format, type,
713
pixels, &ctx->Unpack, texObj, texImage);
715
t->dirty_images[face] |= (1 << level);
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)
728
driTextureObject *t = (driTextureObject *) texObj->DriverData;
731
/* which cube face or ordinary 2D image */
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:
740
(GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
747
assert(t); /* this _should_ be true */
749
driSwapOutTextureObject(t);
751
t = (driTextureObject *) r300AllocTexObj(texObj);
753
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
758
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
759
height, format, type, pixels, packing, texObj,
762
t->dirty_images[face] |= (1 << level);
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)
772
driTextureObject *t = (driTextureObject *) texObj->DriverData;
775
/* which cube face or ordinary 2D image */
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:
784
(GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
792
driSwapOutTextureObject(t);
794
t = (driTextureObject *) r300AllocTexObj(texObj);
796
_mesa_error(ctx, GL_OUT_OF_MEMORY,
797
"glCompressedTexImage2D");
802
texImage->IsClientData = GL_FALSE;
804
/* can't call this, different parameters. Would never evaluate to true anyway currently */
806
if (r300ValidateClientStorage(ctx, target,
809
format, type, pixels,
810
packing, texObj, texImage)) {
811
if (RADEON_DEBUG & DEBUG_TEXTURE)
812
fprintf(stderr, "%s: Using client storage\n",
817
if (RADEON_DEBUG & DEBUG_TEXTURE)
818
fprintf(stderr, "%s: Using normal storage\n",
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.
825
* Note, this will call r300ChooseTextureFormat.
827
_mesa_store_compressed_teximage2d(ctx, target, level,
828
internalFormat, width, height,
829
border, imageSize, data,
832
t->dirty_images[face] |= (1 << level);
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)
844
driTextureObject *t = (driTextureObject *) texObj->DriverData;
847
/* which cube face or ordinary 2D image */
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:
856
(GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
863
assert(t); /* this _should_ be true */
865
driSwapOutTextureObject(t);
867
t = (driTextureObject *) r300AllocTexObj(texObj);
869
_mesa_error(ctx, GL_OUT_OF_MEMORY,
870
"glCompressedTexSubImage3D");
875
_mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset,
876
yoffset, width, height, format,
877
imageSize, data, texObj, texImage);
879
t->dirty_images[face] |= (1 << level);
882
static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
883
GLint internalFormat,
884
GLint width, GLint height, GLint depth,
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)
891
driTextureObject *t = (driTextureObject *) texObj->DriverData;
894
driSwapOutTextureObject(t);
896
t = (driTextureObject *) r300AllocTexObj(texObj);
898
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
903
texImage->IsClientData = GL_FALSE;
906
if (r300ValidateClientStorage(ctx, target,
909
format, type, pixels,
910
packing, texObj, texImage)) {
911
if (RADEON_DEBUG & DEBUG_TEXTURE)
912
fprintf(stderr, "%s: Using client storage\n",
917
if (RADEON_DEBUG & DEBUG_TEXTURE)
918
fprintf(stderr, "%s: Using normal storage\n",
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.
925
* Note, this will call r300ChooseTextureFormat.
927
_mesa_store_teximage3d(ctx, target, level, internalFormat,
928
width, height, depth, border,
929
format, type, pixels,
930
&ctx->Unpack, texObj, texImage);
932
t->dirty_images[0] |= (1 << level);
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)
946
driTextureObject *t = (driTextureObject *) texObj->DriverData;
948
/* fprintf(stderr, "%s\n", __FUNCTION__); */
950
assert(t); /* this _should_ be true */
952
driSwapOutTextureObject(t);
954
t = (driTextureObject *) r300AllocTexObj(texObj);
956
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
959
texObj->DriverData = t;
962
_mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
963
width, height, depth,
964
format, type, pixels, packing, texObj,
967
t->dirty_images[0] |= (1 << level);
970
static void r300TexEnv(GLcontext * ctx, GLenum target,
971
GLenum pname, const GLfloat * param)
973
if (RADEON_DEBUG & DEBUG_STATE) {
974
fprintf(stderr, "%s( %s )\n",
975
__FUNCTION__, _mesa_lookup_enum_by_nr(pname));
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.
983
case GL_TEXTURE_LOD_BIAS_EXT:{
984
#if 0 /* Needs to be relocated in order to make sure we got the right tmu */
988
/* The R300's LOD bias is a signed 2's complement value with a
989
* range of -16.0 <= bias < 16.0.
991
* NOTE: Add a small bias to the bias for conform mipsel.c test.
995
driQueryOptionb(&rmesa->radeon.optionCache,
996
"no_neg_lod_bias") ? 0.0 : -16.0;
997
bias = CLAMP(bias, min, 16.0);
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;
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 +
1011
~R300_LOD_BIAS_MASK;
1012
rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0 +
1025
* Changes variables and flags for a state update, which will happen at the
1026
* next UpdateTextureState
1029
static void r300TexParameter(GLcontext * ctx, GLenum target,
1030
struct gl_texture_object *texObj,
1031
GLenum pname, const GLfloat * params)
1033
r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData;
1035
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
1036
fprintf(stderr, "%s( %s )\n", __FUNCTION__,
1037
_mesa_lookup_enum_by_nr(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);
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);
1054
case GL_TEXTURE_BORDER_COLOR:
1055
r300SetTexBorderColor(t, texObj->_BorderChan);
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.
1067
driSwapOutTextureObject((driTextureObject *) t);
1074
/* Mark this texobj as dirty (one bit per tex unit)
1076
t->dirty_state = TEX_ALL;
1079
static void r300BindTexture(GLcontext * ctx, GLenum target,
1080
struct gl_texture_object *texObj)
1082
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
1083
fprintf(stderr, "%s( %p ) unit=%d\n", __FUNCTION__,
1084
(void *)texObj, ctx->Texture.CurrentUnit);
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);
1096
static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
1098
r300ContextPtr rmesa = R300_CONTEXT(ctx);
1099
driTextureObject *t = (driTextureObject *) texObj->DriverData;
1101
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
1102
fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
1104
_mesa_lookup_enum_by_nr(texObj->Target));
1109
R300_FIREVERTICES(rmesa);
1112
driDestroyTextureObject(t);
1114
/* Free mipmap images and the texture object itself */
1115
_mesa_delete_texture_object(ctx, texObj);
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.
1127
static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
1131
r300ContextPtr rmesa = R300_CONTEXT(ctx);
1132
struct gl_texture_object *obj;
1133
obj = _mesa_new_texture_object(ctx, name, target);
1136
obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
1138
r300AllocTexObj(obj);
1142
void r300InitTextureFuncs(struct dd_function_table *functions)
1144
/* Note: we only plug in the functions we implement in the driver
1145
* since _mesa_init_driver_functions() was already called.
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;
1159
functions->TexEnv = r300TexEnv;
1160
functions->TexParameter = r300TexParameter;
1162
functions->CompressedTexImage2D = r300CompressedTexImage2D;
1163
functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
1165
driInitTextureFormats();