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
, GLubyte c
[4])
176 t
->pp_border_color
= PACK_COLOR_8888(c
[3], c
[0], c
[1], c
[2]);
180 * Allocate space for and load the mesa images into the texture memory block.
181 * This will happen before drawing with a new texture, or drawing with a
182 * texture after it was swapped out or teximaged again.
185 static r300TexObjPtr
r300AllocTexObj(struct gl_texture_object
*texObj
)
189 t
= CALLOC_STRUCT(r300_tex_obj
);
190 texObj
->DriverData
= t
;
192 if (RADEON_DEBUG
& DEBUG_TEXTURE
) {
193 fprintf(stderr
, "%s( %p, %p )\n", __FUNCTION__
,
194 (void *)texObj
, (void *)t
);
197 /* Initialize non-image-dependent parts of the state:
199 t
->base
.tObj
= texObj
;
200 t
->border_fallback
= GL_FALSE
;
202 make_empty_list(&t
->base
);
204 r300UpdateTexWrap(t
);
205 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
206 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
212 /* try to find a format which will only need a memcopy */
213 static const struct gl_texture_format
*r300Choose8888TexFormat(GLenum srcFormat
,
217 const GLubyte littleEndian
= *((const GLubyte
*)&ui
);
219 if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
220 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
221 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
222 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
)) {
223 return &_mesa_texformat_rgba8888
;
224 } else if ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
225 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
226 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
227 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
)) {
228 return &_mesa_texformat_rgba8888_rev
;
229 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
230 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
231 return &_mesa_texformat_argb8888_rev
;
232 } else if (srcFormat
== GL_BGRA
&& ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
233 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
234 return &_mesa_texformat_argb8888
;
236 return _dri_texformat_argb8888
;
239 static const struct gl_texture_format
*r300ChooseTextureFormat(GLcontext
* ctx
,
245 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
246 const GLboolean do32bpt
=
247 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
248 const GLboolean force16bpt
=
249 (rmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
253 fprintf(stderr
, "InternalFormat=%s(%d) type=%s format=%s\n",
254 _mesa_lookup_enum_by_nr(internalFormat
), internalFormat
,
255 _mesa_lookup_enum_by_nr(type
), _mesa_lookup_enum_by_nr(format
));
256 fprintf(stderr
, "do32bpt=%d force16bpt=%d\n", do32bpt
, force16bpt
);
259 switch (internalFormat
) {
262 case GL_COMPRESSED_RGBA
:
264 case GL_UNSIGNED_INT_10_10_10_2
:
265 case GL_UNSIGNED_INT_2_10_10_10_REV
:
266 return do32bpt
? _dri_texformat_argb8888
:
267 _dri_texformat_argb1555
;
268 case GL_UNSIGNED_SHORT_4_4_4_4
:
269 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
270 return _dri_texformat_argb4444
;
271 case GL_UNSIGNED_SHORT_5_5_5_1
:
272 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
273 return _dri_texformat_argb1555
;
275 return do32bpt
? r300Choose8888TexFormat(format
, type
) :
276 _dri_texformat_argb4444
;
281 case GL_COMPRESSED_RGB
:
283 case GL_UNSIGNED_SHORT_4_4_4_4
:
284 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
285 return _dri_texformat_argb4444
;
286 case GL_UNSIGNED_SHORT_5_5_5_1
:
287 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
288 return _dri_texformat_argb1555
;
289 case GL_UNSIGNED_SHORT_5_6_5
:
290 case GL_UNSIGNED_SHORT_5_6_5_REV
:
291 return _dri_texformat_rgb565
;
293 return do32bpt
? _dri_texformat_argb8888
:
294 _dri_texformat_rgb565
;
302 r300Choose8888TexFormat(format
,
303 type
) : _dri_texformat_argb4444
;
307 return _dri_texformat_argb4444
;
310 return _dri_texformat_argb1555
;
316 return !force16bpt
? _dri_texformat_argb8888
:
317 _dri_texformat_rgb565
;
322 return _dri_texformat_rgb565
;
329 case GL_COMPRESSED_ALPHA
:
330 return _dri_texformat_a8
;
338 case GL_COMPRESSED_LUMINANCE
:
339 return _dri_texformat_l8
;
342 case GL_LUMINANCE_ALPHA
:
343 case GL_LUMINANCE4_ALPHA4
:
344 case GL_LUMINANCE6_ALPHA2
:
345 case GL_LUMINANCE8_ALPHA8
:
346 case GL_LUMINANCE12_ALPHA4
:
347 case GL_LUMINANCE12_ALPHA12
:
348 case GL_LUMINANCE16_ALPHA16
:
349 case GL_COMPRESSED_LUMINANCE_ALPHA
:
350 return _dri_texformat_al88
;
357 case GL_COMPRESSED_INTENSITY
:
358 return _dri_texformat_i8
;
361 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
362 type
== GL_UNSIGNED_BYTE
)
363 return &_mesa_texformat_ycbcr
;
365 return &_mesa_texformat_ycbcr_rev
;
369 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
370 return &_mesa_texformat_rgb_dxt1
;
372 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
373 return &_mesa_texformat_rgba_dxt1
;
377 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
378 return &_mesa_texformat_rgba_dxt3
;
380 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
381 return &_mesa_texformat_rgba_dxt5
;
383 case GL_ALPHA16F_ARB
:
384 return &_mesa_texformat_alpha_float16
;
385 case GL_ALPHA32F_ARB
:
386 return &_mesa_texformat_alpha_float32
;
387 case GL_LUMINANCE16F_ARB
:
388 return &_mesa_texformat_luminance_float16
;
389 case GL_LUMINANCE32F_ARB
:
390 return &_mesa_texformat_luminance_float32
;
391 case GL_LUMINANCE_ALPHA16F_ARB
:
392 return &_mesa_texformat_luminance_alpha_float16
;
393 case GL_LUMINANCE_ALPHA32F_ARB
:
394 return &_mesa_texformat_luminance_alpha_float32
;
395 case GL_INTENSITY16F_ARB
:
396 return &_mesa_texformat_intensity_float16
;
397 case GL_INTENSITY32F_ARB
:
398 return &_mesa_texformat_intensity_float32
;
400 return &_mesa_texformat_rgba_float16
;
402 return &_mesa_texformat_rgba_float32
;
404 return &_mesa_texformat_rgba_float16
;
406 return &_mesa_texformat_rgba_float32
;
408 case GL_DEPTH_COMPONENT
:
409 case GL_DEPTH_COMPONENT16
:
410 case GL_DEPTH_COMPONENT24
:
411 case GL_DEPTH_COMPONENT32
:
414 case GL_UNSIGNED_BYTE
:
415 case GL_UNSIGNED_SHORT
:
416 return &_mesa_texformat_z16
;
417 case GL_UNSIGNED_INT
:
418 return &_mesa_texformat_z32
;
419 case GL_UNSIGNED_INT_24_8_EXT
:
421 return &_mesa_texformat_z24_s8
;
424 return &_mesa_texformat_z16
;
429 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
430 (int)internalFormat
);
434 return NULL
; /* never get here */
438 r300ValidateClientStorage(GLcontext
* ctx
, GLenum target
,
439 GLint internalFormat
,
440 GLint srcWidth
, GLint srcHeight
,
441 GLenum format
, GLenum type
, const void *pixels
,
442 const struct gl_pixelstore_attrib
*packing
,
443 struct gl_texture_object
*texObj
,
444 struct gl_texture_image
*texImage
)
446 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
448 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
449 fprintf(stderr
, "intformat %s format %s type %s\n",
450 _mesa_lookup_enum_by_nr(internalFormat
),
451 _mesa_lookup_enum_by_nr(format
),
452 _mesa_lookup_enum_by_nr(type
));
454 if (!ctx
->Unpack
.ClientStorage
)
457 if (ctx
->_ImageTransferState
||
458 texImage
->IsCompressed
|| texObj
->GenerateMipmap
)
461 /* This list is incomplete, may be different on ppc???
463 switch (internalFormat
) {
465 if (format
== GL_BGRA
&& type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
466 texImage
->TexFormat
= _dri_texformat_argb8888
;
472 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
473 texImage
->TexFormat
= _dri_texformat_rgb565
;
479 if (format
== GL_YCBCR_MESA
&&
480 type
== GL_UNSIGNED_SHORT_8_8_REV_APPLE
) {
481 texImage
->TexFormat
= &_mesa_texformat_ycbcr_rev
;
482 } else if (format
== GL_YCBCR_MESA
&&
483 (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
484 type
== GL_UNSIGNED_BYTE
)) {
485 texImage
->TexFormat
= &_mesa_texformat_ycbcr
;
494 /* Could deal with these packing issues, but currently don't:
496 if (packing
->SkipPixels
||
497 packing
->SkipRows
|| packing
->SwapBytes
|| packing
->LsbFirst
) {
501 GLint srcRowStride
= _mesa_image_row_stride(packing
, srcWidth
,
504 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
505 fprintf(stderr
, "%s: srcRowStride %d/%x\n",
506 __FUNCTION__
, srcRowStride
, srcRowStride
);
508 /* Could check this later in upload, pitch restrictions could be
509 * relaxed, but would need to store the image pitch somewhere,
510 * as packing details might change before image is uploaded:
512 if (!r300IsGartMemory(rmesa
, pixels
, srcHeight
* srcRowStride
)
513 || (srcRowStride
& 63))
516 /* Have validated that _mesa_transfer_teximage would be a straight
517 * memcpy at this point. NOTE: future calls to TexSubImage will
518 * overwrite the client data. This is explicitly mentioned in the
521 texImage
->Data
= (void *)pixels
;
522 texImage
->IsClientData
= GL_TRUE
;
523 texImage
->RowStride
= srcRowStride
/ texImage
->TexFormat
->TexelBytes
;
528 static void r300TexImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
529 GLint internalFormat
,
530 GLint width
, GLint border
,
531 GLenum format
, GLenum type
, const GLvoid
* pixels
,
532 const struct gl_pixelstore_attrib
*packing
,
533 struct gl_texture_object
*texObj
,
534 struct gl_texture_image
*texImage
)
536 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
539 driSwapOutTextureObject(t
);
541 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
543 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
548 /* Note, this will call ChooseTextureFormat */
549 _mesa_store_teximage1d(ctx
, target
, level
, internalFormat
,
550 width
, border
, format
, type
, pixels
,
551 &ctx
->Unpack
, texObj
, texImage
);
553 t
->dirty_images
[0] |= (1 << level
);
556 static void r300TexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
559 GLenum format
, GLenum type
,
560 const GLvoid
* pixels
,
561 const struct gl_pixelstore_attrib
*packing
,
562 struct gl_texture_object
*texObj
,
563 struct gl_texture_image
*texImage
)
565 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
567 assert(t
); /* this _should_ be true */
569 driSwapOutTextureObject(t
);
571 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
573 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
578 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
579 format
, type
, pixels
, packing
, texObj
,
582 t
->dirty_images
[0] |= (1 << level
);
585 static void r300TexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
586 GLint internalFormat
,
587 GLint width
, GLint height
, GLint border
,
588 GLenum format
, GLenum type
, const GLvoid
* pixels
,
589 const struct gl_pixelstore_attrib
*packing
,
590 struct gl_texture_object
*texObj
,
591 struct gl_texture_image
*texImage
)
593 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
596 /* which cube face or ordinary 2D image */
598 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
599 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
600 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
601 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
602 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
603 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
605 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
613 driSwapOutTextureObject(t
);
615 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
617 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
622 texImage
->IsClientData
= GL_FALSE
;
624 if (r300ValidateClientStorage(ctx
, target
,
627 format
, type
, pixels
,
628 packing
, texObj
, texImage
)) {
629 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
630 fprintf(stderr
, "%s: Using client storage\n",
633 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
634 fprintf(stderr
, "%s: Using normal storage\n",
637 /* Normal path: copy (to cached memory) and eventually upload
638 * via another copy to GART memory and then a blit... Could
639 * eliminate one copy by going straight to (permanent) GART.
641 * Note, this will call r300ChooseTextureFormat.
643 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
644 width
, height
, border
, format
, type
,
645 pixels
, &ctx
->Unpack
, texObj
, texImage
);
647 t
->dirty_images
[face
] |= (1 << level
);
651 static void r300TexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
652 GLint xoffset
, GLint yoffset
,
653 GLsizei width
, GLsizei height
,
654 GLenum format
, GLenum type
,
655 const GLvoid
* pixels
,
656 const struct gl_pixelstore_attrib
*packing
,
657 struct gl_texture_object
*texObj
,
658 struct gl_texture_image
*texImage
)
660 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
663 /* which cube face or ordinary 2D image */
665 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
666 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
667 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
668 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
669 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
670 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
672 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
679 assert(t
); /* this _should_ be true */
681 driSwapOutTextureObject(t
);
683 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
685 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
690 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
691 height
, format
, type
, pixels
, packing
, texObj
,
694 t
->dirty_images
[face
] |= (1 << level
);
697 static void r300CompressedTexImage2D(GLcontext
* ctx
, GLenum target
,
698 GLint level
, GLint internalFormat
,
699 GLint width
, GLint height
, GLint border
,
700 GLsizei imageSize
, const GLvoid
* data
,
701 struct gl_texture_object
*texObj
,
702 struct gl_texture_image
*texImage
)
704 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
707 /* which cube face or ordinary 2D image */
709 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
710 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
711 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
712 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
713 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
714 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
716 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
724 driSwapOutTextureObject(t
);
726 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
728 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
729 "glCompressedTexImage2D");
734 texImage
->IsClientData
= GL_FALSE
;
736 /* can't call this, different parameters. Would never evaluate to true anyway currently */
738 if (r300ValidateClientStorage(ctx
, target
,
741 format
, type
, pixels
,
742 packing
, texObj
, texImage
)) {
743 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
744 fprintf(stderr
, "%s: Using client storage\n",
749 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
750 fprintf(stderr
, "%s: Using normal storage\n",
753 /* Normal path: copy (to cached memory) and eventually upload
754 * via another copy to GART memory and then a blit... Could
755 * eliminate one copy by going straight to (permanent) GART.
757 * Note, this will call r300ChooseTextureFormat.
759 _mesa_store_compressed_teximage2d(ctx
, target
, level
,
760 internalFormat
, width
, height
,
761 border
, imageSize
, data
,
764 t
->dirty_images
[face
] |= (1 << level
);
768 static void r300CompressedTexSubImage2D(GLcontext
* ctx
, GLenum target
,
769 GLint level
, GLint xoffset
,
770 GLint yoffset
, GLsizei width
,
771 GLsizei height
, GLenum format
,
772 GLsizei imageSize
, const GLvoid
* data
,
773 struct gl_texture_object
*texObj
,
774 struct gl_texture_image
*texImage
)
776 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
779 /* which cube face or ordinary 2D image */
781 case GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
782 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X
:
783 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y
:
784 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
:
785 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z
:
786 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
:
788 (GLuint
) target
- (GLuint
) GL_TEXTURE_CUBE_MAP_POSITIVE_X
;
795 assert(t
); /* this _should_ be true */
797 driSwapOutTextureObject(t
);
799 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
801 _mesa_error(ctx
, GL_OUT_OF_MEMORY
,
802 "glCompressedTexSubImage3D");
807 _mesa_store_compressed_texsubimage2d(ctx
, target
, level
, xoffset
,
808 yoffset
, width
, height
, format
,
809 imageSize
, data
, texObj
, texImage
);
811 t
->dirty_images
[face
] |= (1 << level
);
814 static void r300TexImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
815 GLint internalFormat
,
816 GLint width
, GLint height
, GLint depth
,
818 GLenum format
, GLenum type
, const GLvoid
* pixels
,
819 const struct gl_pixelstore_attrib
*packing
,
820 struct gl_texture_object
*texObj
,
821 struct gl_texture_image
*texImage
)
823 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
826 driSwapOutTextureObject(t
);
828 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
830 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
835 texImage
->IsClientData
= GL_FALSE
;
838 if (r300ValidateClientStorage(ctx
, target
,
841 format
, type
, pixels
,
842 packing
, texObj
, texImage
)) {
843 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
844 fprintf(stderr
, "%s: Using client storage\n",
849 if (RADEON_DEBUG
& DEBUG_TEXTURE
)
850 fprintf(stderr
, "%s: Using normal storage\n",
853 /* Normal path: copy (to cached memory) and eventually upload
854 * via another copy to GART memory and then a blit... Could
855 * eliminate one copy by going straight to (permanent) GART.
857 * Note, this will call r300ChooseTextureFormat.
859 _mesa_store_teximage3d(ctx
, target
, level
, internalFormat
,
860 width
, height
, depth
, border
,
861 format
, type
, pixels
,
862 &ctx
->Unpack
, texObj
, texImage
);
864 t
->dirty_images
[0] |= (1 << level
);
869 r300TexSubImage3D(GLcontext
* ctx
, GLenum target
, GLint level
,
870 GLint xoffset
, GLint yoffset
, GLint zoffset
,
871 GLsizei width
, GLsizei height
, GLsizei depth
,
872 GLenum format
, GLenum type
,
873 const GLvoid
* pixels
,
874 const struct gl_pixelstore_attrib
*packing
,
875 struct gl_texture_object
*texObj
,
876 struct gl_texture_image
*texImage
)
878 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
880 /* fprintf(stderr, "%s\n", __FUNCTION__); */
882 assert(t
); /* this _should_ be true */
884 driSwapOutTextureObject(t
);
886 t
= (driTextureObject
*) r300AllocTexObj(texObj
);
888 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
891 texObj
->DriverData
= t
;
894 _mesa_store_texsubimage3d(ctx
, target
, level
, xoffset
, yoffset
, zoffset
,
895 width
, height
, depth
,
896 format
, type
, pixels
, packing
, texObj
,
899 t
->dirty_images
[0] |= (1 << level
);
903 * Changes variables and flags for a state update, which will happen at the
904 * next UpdateTextureState
907 static void r300TexParameter(GLcontext
* ctx
, GLenum target
,
908 struct gl_texture_object
*texObj
,
909 GLenum pname
, const GLfloat
* params
)
911 r300TexObjPtr t
= (r300TexObjPtr
) texObj
->DriverData
;
913 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
914 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
915 _mesa_lookup_enum_by_nr(pname
));
919 case GL_TEXTURE_MIN_FILTER
:
920 case GL_TEXTURE_MAG_FILTER
:
921 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
922 r300SetTexFilter(t
, texObj
->MinFilter
, texObj
->MagFilter
, texObj
->MaxAnisotropy
);
925 case GL_TEXTURE_WRAP_S
:
926 case GL_TEXTURE_WRAP_T
:
927 case GL_TEXTURE_WRAP_R
:
928 r300UpdateTexWrap(t
);
931 case GL_TEXTURE_BORDER_COLOR
:
932 r300SetTexBorderColor(t
, texObj
->_BorderChan
);
935 case GL_TEXTURE_BASE_LEVEL
:
936 case GL_TEXTURE_MAX_LEVEL
:
937 case GL_TEXTURE_MIN_LOD
:
938 case GL_TEXTURE_MAX_LOD
:
939 /* This isn't the most efficient solution but there doesn't appear to
940 * be a nice alternative. Since there's no LOD clamping,
941 * we just have to rely on loading the right subset of mipmap levels
942 * to simulate a clamped LOD.
944 driSwapOutTextureObject((driTextureObject
*) t
);
947 case GL_DEPTH_TEXTURE_MODE
:
948 if (!texObj
->Image
[0][texObj
->BaseLevel
])
950 if (texObj
->Image
[0][texObj
->BaseLevel
]->TexFormat
->BaseFormat
951 == GL_DEPTH_COMPONENT
) {
952 r300SetDepthTexMode(texObj
);
955 /* If the texture isn't a depth texture, changing this
956 * state won't cause any changes to the hardware.
957 * Don't force a flush of texture state.
967 static void r300BindTexture(GLcontext
* ctx
, GLenum target
,
968 struct gl_texture_object
*texObj
)
970 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
971 fprintf(stderr
, "%s( %p ) unit=%d\n", __FUNCTION__
,
972 (void *)texObj
, ctx
->Texture
.CurrentUnit
);
975 if ((target
== GL_TEXTURE_1D
)
976 || (target
== GL_TEXTURE_2D
)
977 || (target
== GL_TEXTURE_3D
)
978 || (target
== GL_TEXTURE_CUBE_MAP
)
979 || (target
== GL_TEXTURE_RECTANGLE_NV
)) {
980 assert(texObj
->DriverData
!= NULL
);
984 static void r300DeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*texObj
)
986 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
987 driTextureObject
*t
= (driTextureObject
*) texObj
->DriverData
;
989 if (RADEON_DEBUG
& (DEBUG_STATE
| DEBUG_TEXTURE
)) {
990 fprintf(stderr
, "%s( %p (target = %s) )\n", __FUNCTION__
,
992 _mesa_lookup_enum_by_nr(texObj
->Target
));
997 R300_FIREVERTICES(rmesa
);
1000 driDestroyTextureObject(t
);
1002 /* Free mipmap images and the texture object itself */
1003 _mesa_delete_texture_object(ctx
, texObj
);
1007 * Allocate a new texture object.
1008 * Called via ctx->Driver.NewTextureObject.
1009 * Note: this function will be called during context creation to
1010 * allocate the default texture objects.
1011 * Note: we could use containment here to 'derive' the driver-specific
1012 * texture object from the core mesa gl_texture_object. Not done at this time.
1013 * Fixup MaxAnisotropy according to user preference.
1015 static struct gl_texture_object
*r300NewTextureObject(GLcontext
* ctx
,
1019 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1020 struct gl_texture_object
*obj
;
1021 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1024 obj
->MaxAnisotropy
= rmesa
->initialMaxAnisotropy
;
1026 r300AllocTexObj(obj
);
1030 void r300InitTextureFuncs(struct dd_function_table
*functions
)
1032 /* Note: we only plug in the functions we implement in the driver
1033 * since _mesa_init_driver_functions() was already called.
1035 functions
->ChooseTextureFormat
= r300ChooseTextureFormat
;
1036 functions
->TexImage1D
= r300TexImage1D
;
1037 functions
->TexImage2D
= r300TexImage2D
;
1038 functions
->TexImage3D
= r300TexImage3D
;
1039 functions
->TexSubImage1D
= r300TexSubImage1D
;
1040 functions
->TexSubImage2D
= r300TexSubImage2D
;
1041 functions
->TexSubImage3D
= r300TexSubImage3D
;
1042 functions
->NewTextureObject
= r300NewTextureObject
;
1043 functions
->BindTexture
= r300BindTexture
;
1044 functions
->DeleteTexture
= r300DeleteTexture
;
1045 functions
->IsTextureResident
= driIsTextureResident
;
1047 functions
->TexParameter
= r300TexParameter
;
1049 functions
->CompressedTexImage2D
= r300CompressedTexImage2D
;
1050 functions
->CompressedTexSubImage2D
= r300CompressedTexSubImage2D
;
1052 driInitTextureFormats();