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>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/colormac.h"
38 #include "main/context.h"
39 #include "main/enums.h"
40 #include "main/image.h"
41 #include "main/simple_list.h"
42 #include "main/texformat.h"
43 #include "main/texstore.h"
44 #include "main/teximage.h"
45 #include "main/texobj.h"
49 #include "r300_context.h"
50 #include "r300_state.h"
51 #include "r300_ioctl.h"
57 static unsigned int translate_wrap_mode(GLenum wrapmode
)
60 case GL_REPEAT
: return R300_TX_REPEAT
;
61 case GL_CLAMP
: return R300_TX_CLAMP
;
62 case GL_CLAMP_TO_EDGE
: return R300_TX_CLAMP_TO_EDGE
;
63 case GL_CLAMP_TO_BORDER
: return R300_TX_CLAMP_TO_BORDER
;
64 case GL_MIRRORED_REPEAT
: return R300_TX_REPEAT
| R300_TX_MIRRORED
;
65 case GL_MIRROR_CLAMP_EXT
: return R300_TX_CLAMP
| R300_TX_MIRRORED
;
66 case GL_MIRROR_CLAMP_TO_EDGE_EXT
: return R300_TX_CLAMP_TO_EDGE
| R300_TX_MIRRORED
;
67 case GL_MIRROR_CLAMP_TO_BORDER_EXT
: return R300_TX_CLAMP_TO_BORDER
| R300_TX_MIRRORED
;
69 _mesa_problem(NULL
, "bad wrap mode in %s", __FUNCTION__
);
76 * Update the cached hardware registers based on the current texture wrap modes.
78 * \param t Texture object whose wrap modes are to be set
80 static void r300UpdateTexWrap(r300TexObjPtr t
)
82 struct gl_texture_object
*tObj
= t
->base
.tObj
;
85 ~(R300_TX_WRAP_S_MASK
| R300_TX_WRAP_T_MASK
| R300_TX_WRAP_R_MASK
);
87 t
->filter
|= translate_wrap_mode(tObj
->WrapS
) << R300_TX_WRAP_S_SHIFT
;
89 if (tObj
->Target
!= GL_TEXTURE_1D
) {
90 t
->filter
|= translate_wrap_mode(tObj
->WrapT
) << R300_TX_WRAP_T_SHIFT
;
92 if (tObj
->Target
== GL_TEXTURE_3D
)
93 t
->filter
|= translate_wrap_mode(tObj
->WrapR
) << R300_TX_WRAP_R_SHIFT
;
97 static GLuint
aniso_filter(GLfloat anisotropy
)
99 if (anisotropy
>= 16.0) {
100 return R300_TX_MAX_ANISO_16_TO_1
;
101 } else if (anisotropy
>= 8.0) {
102 return R300_TX_MAX_ANISO_8_TO_1
;
103 } else if (anisotropy
>= 4.0) {
104 return R300_TX_MAX_ANISO_4_TO_1
;
105 } else if (anisotropy
>= 2.0) {
106 return R300_TX_MAX_ANISO_2_TO_1
;
108 return R300_TX_MAX_ANISO_1_TO_1
;
113 * Set the texture magnification and minification modes.
115 * \param t Texture whose filter modes are to be set
116 * \param minf Texture minification mode
117 * \param magf Texture magnification mode
118 * \param anisotropy Maximum anisotropy level
120 static void r300SetTexFilter(r300TexObjPtr t
, GLenum minf
, GLenum magf
, GLfloat anisotropy
)
122 t
->filter
&= ~(R300_TX_MIN_FILTER_MASK
| R300_TX_MIN_FILTER_MIP_MASK
| R300_TX_MAG_FILTER_MASK
| R300_TX_MAX_ANISO_MASK
);
123 t
->filter_1
&= ~R300_EDGE_ANISO_EDGE_ONLY
;
125 /* Note that EXT_texture_filter_anisotropic is extremely vague about
126 * how anisotropic filtering interacts with the "normal" filter modes.
127 * When anisotropic filtering is enabled, we override min and mag
128 * filter settings completely. This includes driconf's settings.
130 if (anisotropy
>= 2.0 && (minf
!= GL_NEAREST
) && (magf
!= GL_NEAREST
)) {
131 t
->filter
|= R300_TX_MAG_FILTER_ANISO
132 | R300_TX_MIN_FILTER_ANISO
133 | R300_TX_MIN_FILTER_MIP_LINEAR
134 | aniso_filter(anisotropy
);
135 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
136 fprintf(stderr
, "Using maximum anisotropy of %f\n", anisotropy
);
142 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
;
145 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
;
147 case GL_NEAREST_MIPMAP_NEAREST
:
148 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
|R300_TX_MIN_FILTER_MIP_NEAREST
;
150 case GL_NEAREST_MIPMAP_LINEAR
:
151 t
->filter
|= R300_TX_MIN_FILTER_NEAREST
|R300_TX_MIN_FILTER_MIP_LINEAR
;
153 case GL_LINEAR_MIPMAP_NEAREST
:
154 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
|R300_TX_MIN_FILTER_MIP_NEAREST
;
156 case GL_LINEAR_MIPMAP_LINEAR
:
157 t
->filter
|= R300_TX_MIN_FILTER_LINEAR
|R300_TX_MIN_FILTER_MIP_LINEAR
;
161 /* Note we don't have 3D mipmaps so only use the mag filter setting
162 * to set the 3D texture filter mode.
166 t
->filter
|= R300_TX_MAG_FILTER_NEAREST
;
169 t
->filter
|= R300_TX_MAG_FILTER_LINEAR
;
174 static void r300SetTexBorderColor(r300TexObjPtr t
, const GLfloat color
[4])
177 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
178 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
179 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
180 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
181 t
->pp_border_color
= PACK_COLOR_8888(c
[3], c
[0], c
[1], c
[2]);
185 * Allocate space for and load the mesa images into the texture memory block.
186 * This will happen before drawing with a new texture, or drawing with a
187 * texture after it was swapped out or teximaged again.
190 static r300TexObjPtr
r300AllocTexObj(struct gl_texture_object
*texObj
)
194 t
= CALLOC_STRUCT(r300_tex_obj
);
195 texObj
->DriverData
= t
;
197 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
198 fprintf(stderr
, "%s( %p, %p )\n", __FUNCTION__
,
199 (void *)texObj
, (void *)t
);
202 /* Initialize non-image-dependent parts of the state:
204 t
->base
.tObj
= texObj
;
205 t
->border_fallback
= GL_FALSE
;
207 make_empty_list(&t
->base
);
209 r300UpdateTexWrap(t
);
210 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
211 r300SetTexBorderColor(t
, texObj
->BorderColor
);
217 /* try to find a format which will only need a memcopy */
218 static const struct gl_texture_format
*r300Choose8888TexFormat(GLenum srcFormat
,
222 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
224 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
225 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
226 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
227 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
228 return &_mesa_texformat_rgba8888
;
229 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
230 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
231 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
232 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
233 return &_mesa_texformat_rgba8888_rev
;
234 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
235 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
236 return &_mesa_texformat_argb8888_rev
;
237 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
238 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
239 return &_mesa_texformat_argb8888
;
241 return _dri_texformat_argb8888
;
244 static const struct gl_texture_format
*r300ChooseTextureFormat(GLcontext
* ctx
,
250 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
251 const GLboolean do32bpt
=
252 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
253 const GLboolean force16bpt
=
254 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
258 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
259 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
260 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
261 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
264 switch (internalFormat
) {
267 case GL_COMPRESSED_RGBA
:
269 case GL_UNSIGNED_INT_10_10_10_2
:
270 case GL_UNSIGNED_INT_2_10_10_10_REV
:
271 return do32bpt
? _dri_texformat_argb8888
:
272 _dri_texformat_argb1555
;
273 case GL_UNSIGNED_SHORT_4_4_4_4
:
274 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
275 return _dri_texformat_argb4444
;
276 case GL_UNSIGNED_SHORT_5_5_5_1
:
277 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
278 return _dri_texformat_argb1555
;
280 return do32bpt
? r300Choose8888TexFormat(format
, type
) :
281 _dri_texformat_argb4444
;
286 case GL_COMPRESSED_RGB
:
288 case GL_UNSIGNED_SHORT_4_4_4_4
:
289 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
290 return _dri_texformat_argb4444
;
291 case GL_UNSIGNED_SHORT_5_5_5_1
:
292 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
293 return _dri_texformat_argb1555
;
294 case GL_UNSIGNED_SHORT_5_6_5
:
295 case GL_UNSIGNED_SHORT_5_6_5_REV
:
296 return _dri_texformat_rgb565
;
298 return do32bpt
? _dri_texformat_argb8888
:
299 _dri_texformat_rgb565
;
307 r300Choose8888TexFormat(format
,
308 type
) : _dri_texformat_argb4444
;
312 return _dri_texformat_argb4444
;
315 return _dri_texformat_argb1555
;
321 return !force16bpt
? _dri_texformat_argb8888
:
322 _dri_texformat_rgb565
;
327 return _dri_texformat_rgb565
;
334 case GL_COMPRESSED_ALPHA
:
335 return _dri_texformat_a8
;
343 case GL_COMPRESSED_LUMINANCE
:
344 return _dri_texformat_l8
;
347 case GL_LUMINANCE_ALPHA
:
348 case GL_LUMINANCE4_ALPHA4
:
349 case GL_LUMINANCE6_ALPHA2
:
350 case GL_LUMINANCE8_ALPHA8
:
351 case GL_LUMINANCE12_ALPHA4
:
352 case GL_LUMINANCE12_ALPHA12
:
353 case GL_LUMINANCE16_ALPHA16
:
354 case GL_COMPRESSED_LUMINANCE_ALPHA
:
355 return _dri_texformat_al88
;
362 case GL_COMPRESSED_INTENSITY
:
363 return _dri_texformat_i8
;
366 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
367 type
== GL_UNSIGNED_BYTE
)
368 return &_mesa_texformat_ycbcr
;
370 return &_mesa_texformat_ycbcr_rev
;
374 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
375 return &_mesa_texformat_rgb_dxt1
;
377 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
378 return &_mesa_texformat_rgba_dxt1
;
382 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
383 return &_mesa_texformat_rgba_dxt3
;
385 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
386 return &_mesa_texformat_rgba_dxt5
;
388 case GL_ALPHA16F_ARB
:
389 return &_mesa_texformat_alpha_float16
;
390 case GL_ALPHA32F_ARB
:
391 return &_mesa_texformat_alpha_float32
;
392 case GL_LUMINANCE16F_ARB
:
393 return &_mesa_texformat_luminance_float16
;
394 case GL_LUMINANCE32F_ARB
:
395 return &_mesa_texformat_luminance_float32
;
396 case GL_LUMINANCE_ALPHA16F_ARB
:
397 return &_mesa_texformat_luminance_alpha_float16
;
398 case GL_LUMINANCE_ALPHA32F_ARB
:
399 return &_mesa_texformat_luminance_alpha_float32
;
400 case GL_INTENSITY16F_ARB
:
401 return &_mesa_texformat_intensity_float16
;
402 case GL_INTENSITY32F_ARB
:
403 return &_mesa_texformat_intensity_float32
;
405 return &_mesa_texformat_rgba_float16
;
407 return &_mesa_texformat_rgba_float32
;
409 return &_mesa_texformat_rgba_float16
;
411 return &_mesa_texformat_rgba_float32
;
413 case GL_DEPTH_COMPONENT
:
414 case GL_DEPTH_COMPONENT16
:
415 case GL_DEPTH_COMPONENT24
:
416 case GL_DEPTH_COMPONENT32
:
419 case GL_UNSIGNED_BYTE
:
420 case GL_UNSIGNED_SHORT
:
421 return &_mesa_texformat_z16
;
422 case GL_UNSIGNED_INT
:
423 return &_mesa_texformat_z32
;
424 case GL_UNSIGNED_INT_24_8_EXT
:
426 return &_mesa_texformat_z24_s8
;
429 return &_mesa_texformat_z16
;
434 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
435 (int)internalFormat
);
439 return NULL
; /* never get here */
443 r300ValidateClientStorage(GLcontext
* ctx
, GLenum target
,
444 GLint internalFormat
,
445 GLint srcWidth
, GLint srcHeight
,
446 GLenum format
, GLenum type
, const void *pixels
,
447 const struct gl_pixelstore_attrib
*packing
,
448 struct gl_texture_object
*texObj
,
449 struct gl_texture_image
*texImage
)
451 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
453 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
454 fprintf(stderr
, "intformat %s format %s type %s\n",
455 _mesa_lookup_enum_by_nr(internalFormat
),
456 _mesa_lookup_enum_by_nr(format
),
457 _mesa_lookup_enum_by_nr(type
));
459 if (!ctx
->Unpack
.ClientStorage
)
462 if (ctx
->_ImageTransferState
||
463 texImage
->IsCompressed
|| texObj
->GenerateMipmap
)
466 /* This list is incomplete, may be different on ppc???
468 switch (internalFormat
) {
470 if (format
== GL_BGRA
&& type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
471 texImage
->TexFormat
= _dri_texformat_argb8888
;
477 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
478 texImage
->TexFormat
= _dri_texformat_rgb565
;
484 if (format
== GL_YCBCR_MESA
&&
485 type
== GL_UNSIGNED_SHORT_8_8_REV_APPLE
) {
486 texImage
->TexFormat
= &_mesa_texformat_ycbcr_rev
;
487 } else if (format
== GL_YCBCR_MESA
&&
488 (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
489 type
== GL_UNSIGNED_BYTE
)) {
490 texImage
->TexFormat
= &_mesa_texformat_ycbcr
;
499 /* Could deal with these packing issues, but currently don't:
501 if (packing
->SkipPixels
||
502 packing
->SkipRows
|| packing
->SwapBytes
|| packing
->LsbFirst
) {
506 GLint srcRowStride
= _mesa_image_row_stride(packing
, srcWidth
,
509 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
510 fprintf(stderr
, "%s: srcRowStride %d/%x\n",
511 __FUNCTION__
, srcRowStride
, srcRowStride
);
513 /* Could check this later in upload, pitch restrictions could be
514 * relaxed, but would need to store the image pitch somewhere,
515 * as packing details might change before image is uploaded:
517 if (!r300IsGartMemory(rmesa
, pixels
, srcHeight
* srcRowStride
)
518 || (srcRowStride
& 63))
521 /* Have validated that _mesa_transfer_teximage would be a straight
522 * memcpy at this point. NOTE: future calls to TexSubImage will
523 * overwrite the client data. This is explicitly mentioned in the
526 texImage
->Data
= (void *)pixels
;
527 texImage
->IsClientData
= GL_TRUE
;
528 texImage
->RowStride
= srcRowStride
/ texImage
->TexFormat
->TexelBytes
;
533 static void r300TexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
534 GLint internalFormat
,
535 GLint width
, GLint border
,
536 GLenum format
, GLenum type
, const GLvoid
* pixels
,
537 const struct gl_pixelstore_attrib
*packing
,
538 struct gl_texture_object
*texObj
,
539 struct gl_texture_image
*texImage
)
541 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
544 driSwapOutTextureObject(t
);
546 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
548 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
553 /* Note, this will call ChooseTextureFormat */
554 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
555 width
, border
, format
, type
, pixels
,
556 &ctx
->Unpack
, texObj
, texImage
);
558 t
->dirty_images
[0] |= (1 << level
);
561 static void r300TexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
564 GLenum format
, GLenum type
,
565 const GLvoid
* pixels
,
566 const struct gl_pixelstore_attrib
*packing
,
567 struct gl_texture_object
*texObj
,
568 struct gl_texture_image
*texImage
)
570 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
572 assert(t
); /* this _should_ be true */
574 driSwapOutTextureObject(t
);
576 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
578 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
583 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
584 format
, type
, pixels
, packing
, texObj
,
587 t
->dirty_images
[0] |= (1 << level
);
590 static void r300TexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
591 GLint internalFormat
,
592 GLint width
, GLint height
, GLint border
,
593 GLenum format
, GLenum type
, const GLvoid
* pixels
,
594 const struct gl_pixelstore_attrib
*packing
,
595 struct gl_texture_object
*texObj
,
596 struct gl_texture_image
*texImage
)
598 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
601 /* which cube face or ordinary 2D image */
603 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
604 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
605 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
606 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
607 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
608 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
610 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
618 driSwapOutTextureObject(t
);
620 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
622 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
627 texImage
->IsClientData
= GL_FALSE
;
629 if (r300ValidateClientStorage(ctx
, target
,
632 format
, type
, pixels
,
633 packing
, texObj
, texImage
)) {
634 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
635 fprintf(stderr
, "%s: Using client storage\n",
638 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
639 fprintf(stderr
, "%s: Using normal storage\n",
642 /* Normal path: copy (to cached memory) and eventually upload
643 * via another copy to GART memory and then a blit... Could
644 * eliminate one copy by going straight to (permanent) GART.
646 * Note, this will call r300ChooseTextureFormat.
648 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
649 width
, height
, border
, format
, type
,
650 pixels
, &ctx
->Unpack
, texObj
, texImage
);
652 t
->dirty_images
[face
] |= (1 << level
);
656 static void r300TexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
657 GLint xoffset
, GLint yoffset
,
658 GLsizei width
, GLsizei height
,
659 GLenum format
, GLenum type
,
660 const GLvoid
* pixels
,
661 const struct gl_pixelstore_attrib
*packing
,
662 struct gl_texture_object
*texObj
,
663 struct gl_texture_image
*texImage
)
665 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
668 /* which cube face or ordinary 2D image */
670 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
671 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
672 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
673 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
674 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
675 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
677 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
684 assert(t
); /* this _should_ be true */
686 driSwapOutTextureObject(t
);
688 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
690 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
695 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
696 height
, format
, type
, pixels
, packing
, texObj
,
699 t
->dirty_images
[face
] |= (1 << level
);
702 static void r300CompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
703 GLint level
, GLint internalFormat
,
704 GLint width
, GLint height
, GLint border
,
705 GLsizei imageSize
, const GLvoid
* data
,
706 struct gl_texture_object
*texObj
,
707 struct gl_texture_image
*texImage
)
709 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
712 /* which cube face or ordinary 2D image */
714 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
715 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
716 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
717 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
718 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
719 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
721 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
729 driSwapOutTextureObject(t
);
731 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
733 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
734 "glCompressedTexImage2D");
739 texImage
->IsClientData
= GL_FALSE
;
741 /* can't call this, different parameters. Would never evaluate to true anyway currently */
743 if (r300ValidateClientStorage(ctx
, target
,
746 format
, type
, pixels
,
747 packing
, texObj
, texImage
)) {
748 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
749 fprintf(stderr
, "%s: Using client storage\n",
754 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
755 fprintf(stderr
, "%s: Using normal storage\n",
758 /* Normal path: copy (to cached memory) and eventually upload
759 * via another copy to GART memory and then a blit... Could
760 * eliminate one copy by going straight to (permanent) GART.
762 * Note, this will call r300ChooseTextureFormat.
764 _mesa_store_compressed_teximage2d(ctx
, target
, level
,
765 internalFormat
, width
, height
,
766 border
, imageSize
, data
,
769 t
->dirty_images
[face
] |= (1 << level
);
773 static void r300CompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
774 GLint level
, GLint xoffset
,
775 GLint yoffset
, GLsizei width
,
776 GLsizei height
, GLenum format
,
777 GLsizei imageSize
, const GLvoid
* data
,
778 struct gl_texture_object
*texObj
,
779 struct gl_texture_image
*texImage
)
781 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
784 /* which cube face or ordinary 2D image */
786 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
787 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
788 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
789 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
790 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
791 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
793 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
800 assert(t
); /* this _should_ be true */
802 driSwapOutTextureObject(t
);
804 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
806 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
807 "glCompressedTexSubImage3D");
812 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
,
813 yoffset
, width
, height
, format
,
814 imageSize
, data
, texObj
, texImage
);
816 t
->dirty_images
[face
] |= (1 << level
);
819 static void r300TexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
820 GLint internalFormat
,
821 GLint width
, GLint height
, GLint depth
,
823 GLenum format
, GLenum type
, const GLvoid
* pixels
,
824 const struct gl_pixelstore_attrib
*packing
,
825 struct gl_texture_object
*texObj
,
826 struct gl_texture_image
*texImage
)
828 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
831 driSwapOutTextureObject(t
);
833 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
835 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
840 texImage
->IsClientData
= GL_FALSE
;
843 if (r300ValidateClientStorage(ctx
, target
,
846 format
, type
, pixels
,
847 packing
, texObj
, texImage
)) {
848 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
849 fprintf(stderr
, "%s: Using client storage\n",
854 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
855 fprintf(stderr
, "%s: Using normal storage\n",
858 /* Normal path: copy (to cached memory) and eventually upload
859 * via another copy to GART memory and then a blit... Could
860 * eliminate one copy by going straight to (permanent) GART.
862 * Note, this will call r300ChooseTextureFormat.
864 _mesa_store_teximage3d(ctx
, target
, level
, internalFormat
,
865 width
, height
, depth
, border
,
866 format
, type
, pixels
,
867 &ctx
->Unpack
, texObj
, texImage
);
869 t
->dirty_images
[0] |= (1 << level
);
874 r300TexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
875 GLint xoffset
, GLint yoffset
, GLint zoffset
,
876 GLsizei width
, GLsizei height
, GLsizei depth
,
877 GLenum format
, GLenum type
,
878 const GLvoid
* pixels
,
879 const struct gl_pixelstore_attrib
*packing
,
880 struct gl_texture_object
*texObj
,
881 struct gl_texture_image
*texImage
)
883 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
885 /* fprintf(stderr, "%s\n", __FUNCTION__); */
887 assert(t
); /* this _should_ be true */
889 driSwapOutTextureObject(t
);
891 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
893 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
896 texObj
->DriverData
= t
;
899 _mesa_store_texsubimage3d(ctx
, target
, level
, xoffset
, yoffset
, zoffset
,
900 width
, height
, depth
,
901 format
, type
, pixels
, packing
, texObj
,
904 t
->dirty_images
[0] |= (1 << level
);
908 * Changes variables and flags for a state update, which will happen at the
909 * next UpdateTextureState
912 static void r300TexParameter(GLcontext
* ctx
, GLenum target
,
913 struct gl_texture_object
*texObj
,
914 GLenum pname
, const GLfloat
* params
)
916 r300TexObjPtr t
= (r300TexObjPtr
) texObj
->DriverData
;
918 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
919 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
920 _mesa_lookup_enum_by_nr(pname
));
924 case GL_TEXTURE_MIN_FILTER
:
925 case GL_TEXTURE_MAG_FILTER
:
926 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
927 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
930 case GL_TEXTURE_WRAP_S
:
931 case GL_TEXTURE_WRAP_T
:
932 case GL_TEXTURE_WRAP_R
:
933 r300UpdateTexWrap(t
);
936 case GL_TEXTURE_BORDER_COLOR
:
937 r300SetTexBorderColor(t
, texObj
->BorderColor
);
940 case GL_TEXTURE_BASE_LEVEL
:
941 case GL_TEXTURE_MAX_LEVEL
:
942 case GL_TEXTURE_MIN_LOD
:
943 case GL_TEXTURE_MAX_LOD
:
944 /* This isn't the most efficient solution but there doesn't appear to
945 * be a nice alternative. Since there's no LOD clamping,
946 * we just have to rely on loading the right subset of mipmap levels
947 * to simulate a clamped LOD.
949 driSwapOutTextureObject((driTextureObject
*) t
);
952 case GL_DEPTH_TEXTURE_MODE
:
953 if (!texObj
->Image
[0][texObj
->BaseLevel
])
955 if (texObj
->Image
[0][texObj
->BaseLevel
]->TexFormat
->BaseFormat
956 == GL_DEPTH_COMPONENT
) {
957 r300SetDepthTexMode(texObj
);
960 /* If the texture isn't a depth texture, changing this
961 * state won't cause any changes to the hardware.
962 * Don't force a flush of texture state.
972 static void r300BindTexture(GLcontext
* ctx
, GLenum target
,
973 struct gl_texture_object
*texObj
)
975 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
976 fprintf(stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
,
977 (void *)texObj
, ctx
->Texture
.CurrentUnit
);
980 if ((target
== GL_TEXTURE_1D
)
981 || (target
== GL_TEXTURE_2D
)
982 || (target
== GL_TEXTURE_3D
)
983 || (target
== GL_TEXTURE_CUBE_MAP
)
984 || (target
== GL_TEXTURE_RECTANGLE_NV
)) {
985 assert(texObj
->DriverData
!= NULL
);
989 static void r300DeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
991 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
992 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
994 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
995 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
997 _mesa_lookup_enum_by_nr(texObj
->Target
));
1002 R300_FIREVERTICES(rmesa
);
1005 driDestroyTextureObject(t
);
1007 /* Free mipmap images and the texture object itself */
1008 _mesa_delete_texture_object(ctx
, texObj
);
1012 * Allocate a new texture object.
1013 * Called via ctx->Driver.NewTextureObject.
1014 * Note: this function will be called during context creation to
1015 * allocate the default texture objects.
1016 * Note: we could use containment here to 'derive' the driver-specific
1017 * texture object from the core mesa gl_texture_object. Not done at this time.
1018 * Fixup MaxAnisotropy according to user preference.
1020 static struct gl_texture_object
*r300NewTextureObject(GLcontext
* ctx
,
1024 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1025 struct gl_texture_object
*obj
;
1026 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1029 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
1031 r300AllocTexObj(obj
);
1035 void r300InitTextureFuncs(struct dd_function_table
*functions
)
1037 /* Note: we only plug in the functions we implement in the driver
1038 * since _mesa_init_driver_functions() was already called.
1040 functions
->ChooseTextureFormat
= r300ChooseTextureFormat
;
1041 functions
->TexImage1D
= r300TexImage1D
;
1042 functions
->TexImage2D
= r300TexImage2D
;
1043 functions
->TexImage3D
= r300TexImage3D
;
1044 functions
->TexSubImage1D
= r300TexSubImage1D
;
1045 functions
->TexSubImage2D
= r300TexSubImage2D
;
1046 functions
->TexSubImage3D
= r300TexSubImage3D
;
1047 functions
->NewTextureObject
= r300NewTextureObject
;
1048 functions
->BindTexture
= r300BindTexture
;
1049 functions
->DeleteTexture
= r300DeleteTexture
;
1050 functions
->IsTextureResident
= driIsTextureResident
;
1052 functions
->TexParameter
= r300TexParameter
;
1054 functions
->CompressedTexImage2D
= r300CompressedTexImage2D
;
1055 functions
->CompressedTexSubImage2D
= r300CompressedTexSubImage2D
;
1057 driInitTextureFormats();