1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.7 2002/11/05 17:46:10 tsi Exp $ */
30 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
33 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
36 * Gareth Hughes <gareth@valinux.com>
37 * Brian Paul <brianp@valinux.com>
42 #include "texcompress.h"
43 #include "texformat.h"
47 #include "tdfx_context.h"
49 #include "tdfx_texman.h"
52 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
54 _mesa_halve2x2_teximage2d ( GLcontext
*ctx
,
55 struct gl_texture_image
*texImage
,
57 GLint srcWidth
, GLint srcHeight
,
58 const GLvoid
*srcImage
, GLvoid
*dstImage
)
61 GLint dstWidth
= srcWidth
/ 2;
62 GLint dstHeight
= srcHeight
/ 2;
63 GLint srcRowStride
= srcWidth
* bytesPerPixel
;
64 GLubyte
*src
= (GLubyte
*)srcImage
;
65 GLubyte
*dst
= dstImage
;
72 if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_RGB565
) {
73 _t
= GL_UNSIGNED_SHORT_5_6_5_REV
;
75 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
76 _t
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
78 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
79 _t
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
84 srcRowStride
= srcWidth
* bytesPerPixel
;
91 _s
= src
= MALLOC(srcRowStride
* srcHeight
);
92 _d
= dst
= MALLOC(dstWidth
* bytesPerPixel
* dstHeight
);
93 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
94 &_mesa_texformat_rgba8888_rev
, src
,
95 0, 0, 0, /* dstX/Y/Zoffset */
96 srcRowStride
, /* dstRowStride */
97 0, /* dstImageStride */
98 srcWidth
, srcHeight
, 1,
99 texImage
->Format
, _t
, srcImage
, &ctx
->DefaultPacking
);
102 if (srcHeight
== 1) {
103 for (i
= 0; i
< dstWidth
; i
++) {
104 for (k
= 0; k
< bytesPerPixel
; k
++) {
105 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
109 src
+= bytesPerPixel
;
111 } else if (srcWidth
== 1) {
112 for (j
= 0; j
< dstHeight
; j
++) {
113 for (k
= 0; k
< bytesPerPixel
; k
++) {
114 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
121 for (j
= 0; j
< dstHeight
; j
++) {
122 for (i
= 0; i
< dstWidth
; i
++) {
123 for (k
= 0; k
< bytesPerPixel
; k
++) {
127 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
131 src
+= bytesPerPixel
;
140 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
141 texImage
->TexFormat
, dstImage
,
142 0, 0, 0, /* dstX/Y/Zoffset */
144 0, /* dstImageStride */
145 dstWidth
, dstHeight
, 1,
146 GL_BGRA
, CHAN_TYPE
, dst
, &ctx
->DefaultPacking
);
177 * Compute various texture image parameters.
178 * Input: w, h - source texture width and height
179 * Output: lodlevel - Glide lod level token for the larger texture dimension
180 * aspectratio - Glide aspect ratio token
181 * sscale - S scale factor used during triangle setup
182 * tscale - T scale factor used during triangle setup
183 * wscale - OpenGL -> Glide image width scale factor
184 * hscale - OpenGL -> Glide image height scale factor
187 * w h lodlevel aspectRatio
188 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
189 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
190 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
191 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
192 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
195 tdfxTexGetInfo(const GLcontext
*ctx
, int w
, int h
,
196 GrLOD_t
*lodlevel
, GrAspectRatio_t
*aspectratio
,
197 float *sscale
, float *tscale
,
198 int *wscale
, int *hscale
)
200 int logw
, logh
, ar
, lod
, ws
, hs
;
208 ar
= logw
- logh
; /* aspect ratio = difference in log dimensions */
212 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
213 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
215 ASSERT(width
>= height
);
217 if (ar
<= GR_ASPECT_LOG2_8x1
) {
221 /* have to stretch image height */
224 ar
= GR_ASPECT_LOG2_8x1
;
228 ASSERT(width
< height
);
230 if (ar
>= GR_ASPECT_LOG2_1x8
) {
234 /* have to stretch image width */
237 ar
= GR_ASPECT_LOG2_1x8
;
242 *lodlevel
= (GrLOD_t
) lod
;
244 *aspectratio
= (GrAspectRatio_t
) ar
;
257 * We need to call this when a texture object's minification filter
258 * or texture image sizes change.
260 static void RevalidateTexture(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
262 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
268 minl
= maxl
= tObj
->BaseLevel
;
270 if (tObj
->Image
[0][minl
]) {
271 maxl
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0][minl
]->MaxLog2
);
273 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
274 tdfxTexGetInfo(ctx
, tObj
->Image
[0][minl
]->Width
, tObj
->Image
[0][minl
]->Height
,
275 &ti
->info
.largeLodLog2
,
276 &ti
->info
.aspectRatioLog2
,
277 &(ti
->sScale
), &(ti
->tScale
), NULL
, NULL
);
280 if (tObj
->Image
[0][maxl
] && (tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
281 /* mipmapping: need to compute smallLodLog2 */
282 tdfxTexGetInfo(ctx
, tObj
->Image
[0][maxl
]->Width
,
283 tObj
->Image
[0][maxl
]->Height
,
284 &ti
->info
.smallLodLog2
, NULL
,
285 NULL
, NULL
, NULL
, NULL
);
288 /* not mipmapping: smallLodLog2 = largeLodLog2 */
289 ti
->info
.smallLodLog2
= ti
->info
.largeLodLog2
;
295 ti
->info
.data
= NULL
;
297 /* this is necessary because of fxDDCompressedTexImage2D */
299 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
300 tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
301 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
302 ti
->sScale
/= mml
->wScale
;
303 ti
->tScale
/= mml
->hScale
;
310 fxAllocTexObjData(tdfxContextPtr fxMesa
)
314 if (!(ti
= CALLOC(sizeof(tdfxTexInfo
)))) {
315 _mesa_problem(NULL
, "tdfx driver: out of memory");
319 ti
->isInTM
= GL_FALSE
;
321 ti
->whichTMU
= TDFX_TMU_NONE
;
323 ti
->tm
[TDFX_TMU0
] = NULL
;
324 ti
->tm
[TDFX_TMU1
] = NULL
;
326 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
327 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
329 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
330 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
332 ti
->mmMode
= GR_MIPMAP_NEAREST
;
333 ti
->LODblend
= FXFALSE
;
340 * Called via glBindTexture.
343 tdfxBindTexture(GLcontext
* ctx
, GLenum target
,
344 struct gl_texture_object
*tObj
)
346 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
349 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
350 fprintf(stderr
, "fxmesa: fxDDTexBind(%d,%p)\n", tObj
->Name
,
354 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
357 if (!tObj
->DriverData
) {
358 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
361 ti
= TDFX_TEXTURE_DATA(tObj
);
362 ti
->lastTimeUsed
= fxMesa
->texBindNumber
++;
364 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
369 * Called via glTexEnv.
372 tdfxTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
373 const GLfloat
* param
)
375 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
377 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
379 fprintf(stderr
, "fxmesa: texenv(%x,%x)\n", pname
,
382 fprintf(stderr
, "fxmesa: texenv(%x)\n", pname
);
385 /* XXX this is a bit of a hack to force the Glide texture
386 * state to be updated.
388 fxMesa
->TexState
.EnvMode
[ctx
->Texture
.CurrentUnit
] = 0;
390 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
395 * Called via glTexParameter.
398 tdfxTexParameter(GLcontext
* ctx
, GLenum target
,
399 struct gl_texture_object
*tObj
,
400 GLenum pname
, const GLfloat
* params
)
402 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
403 GLenum param
= (GLenum
) (GLint
) params
[0];
406 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
407 fprintf(stderr
, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj
->Name
,
408 tObj
->DriverData
, pname
, param
);
411 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
414 if (!tObj
->DriverData
)
415 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
417 ti
= TDFX_TEXTURE_DATA(tObj
);
420 case GL_TEXTURE_MIN_FILTER
:
423 ti
->mmMode
= GR_MIPMAP_DISABLE
;
424 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
425 ti
->LODblend
= FXFALSE
;
428 ti
->mmMode
= GR_MIPMAP_DISABLE
;
429 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
430 ti
->LODblend
= FXFALSE
;
432 case GL_NEAREST_MIPMAP_LINEAR
:
433 if (!fxMesa
->Glide
.HaveCombineExt
) {
434 if (fxMesa
->haveTwoTMUs
) {
435 ti
->mmMode
= GR_MIPMAP_NEAREST
;
436 ti
->LODblend
= FXTRUE
;
439 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
440 ti
->LODblend
= FXFALSE
;
442 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
445 /* XXX Voodoo3/Banshee mipmap blending seems to produce
446 * incorrectly filtered colors for the smallest mipmap levels.
447 * To work-around we fall-through here and use a different filter.
449 case GL_NEAREST_MIPMAP_NEAREST
:
450 ti
->mmMode
= GR_MIPMAP_NEAREST
;
451 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
452 ti
->LODblend
= FXFALSE
;
454 case GL_LINEAR_MIPMAP_LINEAR
:
455 if (!fxMesa
->Glide
.HaveCombineExt
) {
456 if (fxMesa
->haveTwoTMUs
) {
457 ti
->mmMode
= GR_MIPMAP_NEAREST
;
458 ti
->LODblend
= FXTRUE
;
461 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
462 ti
->LODblend
= FXFALSE
;
464 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
467 /* XXX Voodoo3/Banshee mipmap blending seems to produce
468 * incorrectly filtered colors for the smallest mipmap levels.
469 * To work-around we fall-through here and use a different filter.
471 case GL_LINEAR_MIPMAP_NEAREST
:
472 ti
->mmMode
= GR_MIPMAP_NEAREST
;
473 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
474 ti
->LODblend
= FXFALSE
;
479 ti
->reloadImages
= GL_TRUE
;
480 RevalidateTexture(ctx
, tObj
);
481 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
484 case GL_TEXTURE_MAG_FILTER
:
487 ti
->magFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
490 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
495 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
498 case GL_TEXTURE_WRAP_S
:
500 case GL_CLAMP_TO_BORDER
:
501 case GL_CLAMP_TO_EDGE
:
503 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
506 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
508 case GL_MIRRORED_REPEAT
:
509 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
514 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
517 case GL_TEXTURE_WRAP_T
:
519 case GL_CLAMP_TO_BORDER
:
520 case GL_CLAMP_TO_EDGE
:
522 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
525 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
527 case GL_MIRRORED_REPEAT
:
528 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
533 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
536 case GL_TEXTURE_BORDER_COLOR
:
539 case GL_TEXTURE_MIN_LOD
:
542 case GL_TEXTURE_MAX_LOD
:
545 case GL_TEXTURE_BASE_LEVEL
:
546 RevalidateTexture(ctx
, tObj
);
548 case GL_TEXTURE_MAX_LEVEL
:
549 RevalidateTexture(ctx
, tObj
);
559 * Called via glDeleteTextures to delete a texture object.
560 * Here, we delete the Glide data associated with the texture.
563 tdfxDeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
565 if (ctx
&& ctx
->DriverCtx
) {
566 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
567 tdfxTMFreeTexture(fxMesa
, tObj
);
568 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
569 /* Free mipmap images and the texture object itself */
570 _mesa_delete_texture_object(ctx
, tObj
);
576 * Return true if texture is resident, false otherwise.
579 tdfxIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
581 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
582 return (GLboolean
) (ti
&& ti
->isInTM
);
588 * Convert a gl_color_table texture palette to Glide's format.
591 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
593 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
594 GLint width
= table
->Size
;
598 ASSERT(table
->TableType
== GL_UNSIGNED_BYTE
);
600 switch (table
->Format
) {
602 for (i
= 0; i
< width
; i
++) {
607 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
609 return GR_TEXTABLE_PALETTE_6666_EXT
;
611 for (i
= 0; i
< width
; i
++) {
616 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
618 return GR_TEXTABLE_PALETTE
;
620 for (i
= 0; i
< width
; i
++) {
623 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
625 return GR_TEXTABLE_PALETTE_6666_EXT
;
626 case GL_LUMINANCE_ALPHA
:
627 for (i
= 0; i
< width
; i
++) {
628 r
= g
= b
= tableUB
[i
* 2 + 0];
629 a
= tableUB
[i
* 2 + 1];
630 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
632 return GR_TEXTABLE_PALETTE_6666_EXT
;
634 for (i
= 0; i
< width
; i
++) {
635 r
= tableUB
[i
* 3 + 0];
636 g
= tableUB
[i
* 3 + 1];
637 b
= tableUB
[i
* 3 + 2];
639 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
641 return GR_TEXTABLE_PALETTE
;
643 for (i
= 0; i
< width
; i
++) {
644 r
= tableUB
[i
* 4 + 0];
645 g
= tableUB
[i
* 4 + 1];
646 b
= tableUB
[i
* 4 + 2];
647 a
= tableUB
[i
* 4 + 3];
648 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
650 return GR_TEXTABLE_PALETTE_6666_EXT
;
657 tdfxUpdateTexturePalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
659 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
662 /* per-texture palette */
665 /* This might be a proxy texture. */
666 if (!tObj
->Palette
.Table
)
669 if (!tObj
->DriverData
)
670 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
671 ti
= TDFX_TEXTURE_DATA(tObj
);
673 ti
->paltype
= convertPalette(ti
->palette
.data
, &tObj
->Palette
);
674 /*tdfxTexInvalidate(ctx, tObj);*/
677 /* global texture palette */
678 fxMesa
->TexPalette
.Type
= convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
679 fxMesa
->TexPalette
.Data
= &(fxMesa
->glbPalette
.data
);
680 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
682 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX too heavy-handed */
686 /**********************************************************************/
687 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
688 /**********************************************************************/
691 static FxBool TexusFatalError
= FXFALSE
;
692 static FxBool TexusError
= FXFALSE
;
694 #define TX_DITHER_NONE 0x00000000
697 fxTexusError(const char *string
, FxBool fatal
)
699 _mesa_problem(NULL
, string
);
701 * Just propagate the fatal value up.
704 TexusFatalError
= fatal
;
709 static const struct gl_texture_format
*
710 tdfxChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
711 GLenum srcFormat
, GLenum srcType
)
713 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
714 const GLboolean allow32bpt
= TDFX_IS_NAPALM(fxMesa
);
716 switch (internalFormat
) {
722 case GL_COMPRESSED_ALPHA
:
723 return &_mesa_texformat_a8
;
730 case GL_COMPRESSED_LUMINANCE
:
731 return &_mesa_texformat_l8
;
733 case GL_LUMINANCE_ALPHA
:
734 case GL_LUMINANCE4_ALPHA4
:
735 case GL_LUMINANCE6_ALPHA2
:
736 case GL_LUMINANCE8_ALPHA8
:
737 case GL_LUMINANCE12_ALPHA4
:
738 case GL_LUMINANCE12_ALPHA12
:
739 case GL_LUMINANCE16_ALPHA16
:
740 case GL_COMPRESSED_LUMINANCE_ALPHA
:
741 return &_mesa_texformat_al88
;
747 case GL_COMPRESSED_INTENSITY
:
748 return &_mesa_texformat_i8
;
752 return &_mesa_texformat_rgb565
;
753 case GL_COMPRESSED_RGB
:
754 /* intentional fall-through */
757 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
758 return &_mesa_texformat_rgb565
;
760 /* intentional fall through */
765 return (allow32bpt
) ? &_mesa_texformat_argb8888
766 : &_mesa_texformat_rgb565
;
769 return &_mesa_texformat_argb4444
;
770 case GL_COMPRESSED_RGBA
:
771 /* intentional fall-through */
774 if ( srcFormat
== GL_BGRA
) {
775 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
776 return &_mesa_texformat_argb8888
;
778 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
779 return &_mesa_texformat_argb4444
;
781 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
782 return &_mesa_texformat_argb1555
;
785 /* intentional fall through */
790 return allow32bpt
? &_mesa_texformat_argb8888
791 : &_mesa_texformat_argb4444
;
793 return &_mesa_texformat_argb1555
;
795 case GL_COLOR_INDEX1_EXT
:
796 case GL_COLOR_INDEX2_EXT
:
797 case GL_COLOR_INDEX4_EXT
:
798 case GL_COLOR_INDEX8_EXT
:
799 case GL_COLOR_INDEX12_EXT
:
800 case GL_COLOR_INDEX16_EXT
:
801 return &_mesa_texformat_ci8
;
802 /* GL_EXT_texture_compression_s3tc */
804 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
807 return &_mesa_texformat_rgb_dxt1
;
808 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
809 return &_mesa_texformat_rgba_dxt1
;
810 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
813 return &_mesa_texformat_rgba_dxt3
;
814 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
815 return &_mesa_texformat_rgba_dxt5
;
816 /* GL_3DFX_texture_compression_FXT1 */
817 case GL_COMPRESSED_RGB_FXT1_3DFX
:
818 return &_mesa_texformat_rgb_fxt1
;
819 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
820 return &_mesa_texformat_rgba_fxt1
;
822 _mesa_problem(ctx
, "unexpected format in tdfxChooseTextureFormat");
829 * Return the Glide format for the given mesa texture format.
831 static GrTextureFormat_t
832 fxGlideFormat(GLint mesaFormat
)
834 switch (mesaFormat
) {
836 return GR_TEXFMT_ALPHA_8
;
838 return GR_TEXFMT_ALPHA_8
;
840 return GR_TEXFMT_INTENSITY_8
;
841 case MESA_FORMAT_CI8
:
842 return GR_TEXFMT_P_8
;
843 case MESA_FORMAT_AL88
:
844 return GR_TEXFMT_ALPHA_INTENSITY_88
;
845 case MESA_FORMAT_RGB565
:
846 return GR_TEXFMT_RGB_565
;
847 case MESA_FORMAT_ARGB4444
:
848 return GR_TEXFMT_ARGB_4444
;
849 case MESA_FORMAT_ARGB1555
:
850 return GR_TEXFMT_ARGB_1555
;
851 case MESA_FORMAT_ARGB8888
:
852 return GR_TEXFMT_ARGB_8888
;
853 case MESA_FORMAT_RGB_FXT1
:
854 case MESA_FORMAT_RGBA_FXT1
:
855 return GR_TEXFMT_ARGB_CMP_FXT1
;
856 case MESA_FORMAT_RGB_DXT1
:
857 case MESA_FORMAT_RGBA_DXT1
:
858 return GR_TEXFMT_ARGB_CMP_DXT1
;
859 case MESA_FORMAT_RGBA_DXT3
:
860 return GR_TEXFMT_ARGB_CMP_DXT3
;
861 case MESA_FORMAT_RGBA_DXT5
:
862 return GR_TEXFMT_ARGB_CMP_DXT5
;
864 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
870 /* Texel-fetch functions for software texturing and glGetTexImage().
871 * We should have been able to use some "standard" fetch functions (which
872 * may get defined in texutil.c) but we have to account for scaled texture
873 * images on tdfx hardware (the 8:1 aspect ratio limit).
874 * Hence, we need special functions here.
877 fxt1_decode_1 (const void *texture
, int width
,
878 int i
, int j
, unsigned char *rgba
);
881 fetch_intensity8(const struct gl_texture_image
*texImage
,
882 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
884 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
885 const GLubyte
*texel
;
890 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
891 rgba
[RCOMP
] = *texel
;
892 rgba
[GCOMP
] = *texel
;
893 rgba
[BCOMP
] = *texel
;
894 rgba
[ACOMP
] = *texel
;
899 fetch_luminance8(const struct gl_texture_image
*texImage
,
900 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
902 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
903 const GLubyte
*texel
;
908 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
909 rgba
[RCOMP
] = *texel
;
910 rgba
[GCOMP
] = *texel
;
911 rgba
[BCOMP
] = *texel
;
917 fetch_alpha8(const struct gl_texture_image
*texImage
,
918 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
920 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
921 const GLubyte
*texel
;
926 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
930 rgba
[ACOMP
] = *texel
;
935 fetch_index8(const struct gl_texture_image
*texImage
,
936 GLint i
, GLint j
, GLint k
, GLchan
* indexOut
)
938 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
939 const GLubyte
*texel
;
944 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
950 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
951 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
953 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
954 const GLubyte
*texel
;
959 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
960 rgba
[RCOMP
] = texel
[0];
961 rgba
[GCOMP
] = texel
[0];
962 rgba
[BCOMP
] = texel
[0];
963 rgba
[ACOMP
] = texel
[1];
968 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
969 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
971 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
972 const GLushort
*texel
;
977 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
978 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
979 rgba
[GCOMP
] = (((*texel
) >> 5) & 0x3f) * 255 / 63;
980 rgba
[BCOMP
] = (((*texel
) >> 0) & 0x1f) * 255 / 31;
986 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
987 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
989 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
990 const GLushort
*texel
;
995 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
996 rgba
[RCOMP
] = (((*texel
) >> 12) & 0xf) * 255 / 15;
997 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xf) * 255 / 15;
998 rgba
[BCOMP
] = (((*texel
) >> 4) & 0xf) * 255 / 15;
999 rgba
[ACOMP
] = (((*texel
) >> 0) & 0xf) * 255 / 15;
1004 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
1005 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1007 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1008 const GLushort
*texel
;
1010 i
= i
* mml
->wScale
;
1011 j
= j
* mml
->hScale
;
1013 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1014 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
1015 rgba
[GCOMP
] = (((*texel
) >> 6) & 0x1f) * 255 / 31;
1016 rgba
[BCOMP
] = (((*texel
) >> 1) & 0x1f) * 255 / 31;
1017 rgba
[ACOMP
] = (((*texel
) >> 0) & 0x01) * 255;
1022 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
1023 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1025 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1026 const GLuint
*texel
;
1028 i
= i
* mml
->wScale
;
1029 j
= j
* mml
->hScale
;
1031 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
1032 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
1033 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
1034 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
1035 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
1040 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
1041 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1043 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1045 i
= i
* mml
->wScale
;
1046 j
= j
* mml
->hScale
;
1048 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1054 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
1055 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1057 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1059 i
= i
* mml
->wScale
;
1060 j
= j
* mml
->hScale
;
1062 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1067 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
1068 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1070 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1072 i
= i
* mml
->wScale
;
1073 j
= j
* mml
->hScale
;
1075 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1080 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
1081 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1083 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1085 i
= i
* mml
->wScale
;
1086 j
= j
* mml
->hScale
;
1088 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1093 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
1094 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1096 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1098 i
= i
* mml
->wScale
;
1099 j
= j
* mml
->hScale
;
1101 _mesa_texformat_rgba_dxt3
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1106 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
1107 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1109 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1111 i
= i
* mml
->wScale
;
1112 j
= j
* mml
->hScale
;
1114 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1118 static FetchTexelFuncC
1119 fxFetchFunction(GLint mesaFormat
)
1121 switch (mesaFormat
) {
1122 case MESA_FORMAT_I8
:
1123 return &fetch_intensity8
;
1124 case MESA_FORMAT_A8
:
1125 return &fetch_alpha8
;
1126 case MESA_FORMAT_L8
:
1127 return &fetch_luminance8
;
1128 case MESA_FORMAT_CI8
:
1129 return &fetch_index8
;
1130 case MESA_FORMAT_AL88
:
1131 return &fetch_luminance8_alpha8
;
1132 case MESA_FORMAT_RGB565
:
1133 return &fetch_r5g6b5
;
1134 case MESA_FORMAT_ARGB4444
:
1135 return &fetch_r4g4b4a4
;
1136 case MESA_FORMAT_ARGB1555
:
1137 return &fetch_r5g5b5a1
;
1138 case MESA_FORMAT_ARGB8888
:
1139 return &fetch_a8r8g8b8
;
1140 case MESA_FORMAT_RGB_FXT1
:
1141 return &fetch_rgb_fxt1
;
1142 case MESA_FORMAT_RGBA_FXT1
:
1143 return &fetch_rgba_fxt1
;
1144 case MESA_FORMAT_RGB_DXT1
:
1145 return &fetch_rgb_dxt1
;
1146 case MESA_FORMAT_RGBA_DXT1
:
1147 return &fetch_rgba_dxt1
;
1148 case MESA_FORMAT_RGBA_DXT3
:
1149 return &fetch_rgba_dxt3
;
1150 case MESA_FORMAT_RGBA_DXT5
:
1151 return &fetch_rgba_dxt5
;
1153 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1160 adjust2DRatio (GLcontext
*ctx
,
1161 GLint xoffset
, GLint yoffset
,
1162 GLint width
, GLint height
,
1163 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1164 const struct gl_pixelstore_attrib
*packing
,
1165 tdfxMipMapLevel
*mml
,
1166 struct gl_texture_image
*texImage
,
1170 const GLint newWidth
= width
* mml
->wScale
;
1171 const GLint newHeight
= height
* mml
->hScale
;
1174 if (!texImage
->IsCompressed
) {
1176 tempImage
= MALLOC(width
* height
* texelBytes
);
1181 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1182 texImage
->TexFormat
, tempImage
,
1183 0, 0, 0, /* dstX/Y/Zoffset */
1184 width
* texelBytes
, /* dstRowStride */
1185 0, /* dstImageStride */
1187 format
, type
, pixels
, packing
);
1190 /* compute address of dest subimage within the overal tex image */
1191 destAddr
= (GLubyte
*) texImage
->Data
1192 + (yoffset
* mml
->hScale
* mml
->width
1193 + xoffset
* mml
->wScale
) * texelBytes
;
1195 _mesa_rescale_teximage2d(texelBytes
,
1196 dstRowStride
, /* dst stride */
1198 newWidth
, newHeight
,
1199 tempImage
, destAddr
);
1201 const GLint rawBytes
= 4;
1202 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1206 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1210 /* unpack image, apply transfer ops and store in rawImage */
1211 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
1212 &_mesa_texformat_rgba8888_rev
, rawImage
,
1213 0, 0, 0, /* dstX/Y/Zoffset */
1214 width
* rawBytes
, /* dstRowStride */
1215 0, /* dstImageStride */
1217 format
, type
, pixels
, packing
);
1218 _mesa_rescale_teximage2d(rawBytes
,
1219 newWidth
* rawBytes
, /* dst stride */
1220 width
, height
, /* src */
1221 newWidth
, newHeight
, /* dst */
1222 rawImage
/*src*/, tempImage
/*dst*/ );
1223 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1224 texImage
->TexFormat
, texImage
->Data
,
1225 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1227 0, /* dstImageStride */
1228 newWidth
, newHeight
, 1,
1229 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1240 tdfxTexImage2D(GLcontext
*ctx
, GLenum target
, GLint level
,
1241 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1242 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1243 const struct gl_pixelstore_attrib
*packing
,
1244 struct gl_texture_object
*texObj
,
1245 struct gl_texture_image
*texImage
)
1247 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1249 tdfxMipMapLevel
*mml
;
1250 GLint texelBytes
, dstRowStride
;
1253 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1254 texObj->Name, texImage->IntFormat, format, type,
1255 texImage->Width, texImage->Height);
1258 ti
= TDFX_TEXTURE_DATA(texObj
);
1260 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1261 if (!texObj
->DriverData
) {
1262 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1265 ti
= TDFX_TEXTURE_DATA(texObj
);
1269 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1271 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1272 if (!texImage
->DriverData
) {
1273 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1276 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1279 /* Determine width and height scale factors for texture.
1280 * Remember, Glide is limited to 8:1 aspect ratios.
1283 texImage
->Width
, texImage
->Height
,
1284 NULL
, /* lod level */
1285 NULL
, /* aspect ratio */
1286 NULL
, NULL
, /* sscale, tscale */
1287 &mml
->wScale
, &mml
->hScale
);
1289 /* rescaled size: */
1290 mml
->width
= width
* mml
->wScale
;
1291 mml
->height
= height
* mml
->hScale
;
1293 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1294 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1295 /* [dBorca] we should update texture's attribute, then,
1296 * because if the application asks us to decompress, we
1297 * have to know the REAL format! Also, DXT3/5 might not
1298 * be correct, since it would mess with "compressedSize".
1299 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1301 if (texImage
->IsCompressed
) {
1302 switch (internalFormat
) {
1303 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1306 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1308 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1309 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1310 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1313 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1315 texImage
->IntFormat
= internalFormat
;
1319 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1320 GLenum texNapalm
= 0;
1321 if (internalFormat
== GL_COMPRESSED_RGB
) {
1322 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1323 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1324 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1327 texImage
->IntFormat
= internalFormat
= texNapalm
;
1328 texImage
->IsCompressed
= GL_TRUE
;
1333 /* choose the texture format */
1334 assert(ctx
->Driver
.ChooseTextureFormat
);
1335 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1336 internalFormat
, format
, type
);
1337 assert(texImage
->TexFormat
);
1338 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1339 ti
->info
.format
= mml
->glideFormat
;
1340 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1341 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1343 if (texImage
->IsCompressed
) {
1344 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1349 dstRowStride
= _mesa_compressed_row_stride(internalFormat
, mml
->width
);
1350 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1352 dstRowStride
= mml
->width
* texelBytes
;
1353 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1355 if (!texImage
->Data
) {
1356 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1360 if (pixels
!= NULL
) {
1361 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1362 /* rescale image to overcome 1:8 aspect limitation */
1363 if (!adjust2DRatio(ctx
,
1366 format
, type
, pixels
,
1373 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1378 /* no rescaling needed */
1379 /* unpack image, apply transfer ops and store in texImage->Data */
1380 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1381 texImage
->TexFormat
, texImage
->Data
,
1382 0, 0, 0, /* dstX/Y/Zoffset */
1384 0, /* dstImageStride */
1386 format
, type
, pixels
, packing
);
1389 /* GL_SGIS_generate_mipmap */
1390 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1391 GLint mipWidth
, mipHeight
;
1392 tdfxMipMapLevel
*mip
;
1393 struct gl_texture_image
*mipImage
;
1394 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1395 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1397 assert(!texImage
->IsCompressed
);
1399 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1400 mipWidth
= width
/ 2;
1404 mipHeight
= height
/ 2;
1408 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1411 _mesa_TexImage2D(target
, ++level
, internalFormat
,
1412 mipWidth
, mipHeight
, border
,
1415 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1416 mip
= TDFX_TEXIMAGE_DATA(mipImage
);
1417 _mesa_halve2x2_teximage2d(ctx
,
1420 mml
->width
, mml
->height
,
1421 texImage
->Data
, mipImage
->Data
);
1422 texImage
= mipImage
;
1430 RevalidateTexture(ctx
, texObj
);
1432 ti
->reloadImages
= GL_TRUE
;
1433 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1438 tdfxTexSubImage2D(GLcontext
*ctx
, GLenum target
, GLint level
,
1439 GLint xoffset
, GLint yoffset
,
1440 GLsizei width
, GLsizei height
,
1441 GLenum format
, GLenum type
,
1442 const GLvoid
*pixels
,
1443 const struct gl_pixelstore_attrib
*packing
,
1444 struct gl_texture_object
*texObj
,
1445 struct gl_texture_image
*texImage
)
1447 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1449 tdfxMipMapLevel
*mml
;
1450 GLint texelBytes
, dstRowStride
;
1452 if (!texObj
->DriverData
) {
1453 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1457 ti
= TDFX_TEXTURE_DATA(texObj
);
1459 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1462 assert(texImage
->Data
); /* must have an existing texture image! */
1463 assert(texImage
->Format
);
1465 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1466 if (texImage
->IsCompressed
) {
1467 dstRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, mml
->width
);
1469 dstRowStride
= mml
->width
* texelBytes
;
1472 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1473 /* need to rescale subimage to match mipmap level's rescale factors */
1474 if (!adjust2DRatio(ctx
,
1477 format
, type
, pixels
,
1484 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1489 /* no rescaling needed */
1490 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1491 texImage
->TexFormat
, texImage
->Data
,
1492 xoffset
, yoffset
, 0,
1494 0, /* dstImageStride */
1496 format
, type
, pixels
, packing
);
1499 /* GL_SGIS_generate_mipmap */
1500 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1501 GLint mipWidth
, mipHeight
;
1502 tdfxMipMapLevel
*mip
;
1503 struct gl_texture_image
*mipImage
;
1504 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1505 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1507 assert(!texImage
->IsCompressed
);
1509 width
= texImage
->Width
;
1510 height
= texImage
->Height
;
1511 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1512 mipWidth
= width
/ 2;
1516 mipHeight
= height
/ 2;
1520 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1524 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1525 mip
= TDFX_TEXIMAGE_DATA(mipImage
);
1526 _mesa_halve2x2_teximage2d(ctx
,
1529 mml
->width
, mml
->height
,
1530 texImage
->Data
, mipImage
->Data
);
1531 texImage
= mipImage
;
1538 ti
->reloadImages
= GL_TRUE
; /* signal the image needs to be reloaded */
1539 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX this might be a bit much */
1544 tdfxTexImage1D(GLcontext
*ctx
, GLenum target
, GLint level
,
1545 GLint internalFormat
, GLint width
, GLint border
,
1546 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1547 const struct gl_pixelstore_attrib
*packing
,
1548 struct gl_texture_object
*texObj
,
1549 struct gl_texture_image
*texImage
)
1551 tdfxTexImage2D(ctx
, target
, level
,
1552 internalFormat
, width
, 1, border
,
1553 format
, type
, pixels
,
1560 tdfxTexSubImage1D(GLcontext
*ctx
, GLenum target
, GLint level
,
1563 GLenum format
, GLenum type
,
1564 const GLvoid
*pixels
,
1565 const struct gl_pixelstore_attrib
*packing
,
1566 struct gl_texture_object
*texObj
,
1567 struct gl_texture_image
*texImage
)
1569 tdfxTexSubImage2D(ctx
, target
, level
,
1579 /**********************************************************************/
1580 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1581 /**********************************************************************/
1584 tdfxCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1585 GLint level
, GLint internalFormat
,
1586 GLsizei width
, GLsizei height
, GLint border
,
1587 GLsizei imageSize
, const GLvoid
*data
,
1588 struct gl_texture_object
*texObj
,
1589 struct gl_texture_image
*texImage
)
1591 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1593 tdfxMipMapLevel
*mml
;
1595 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1596 fprintf(stderr
, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1597 texObj
->Name
, internalFormat
,
1601 if ((target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
) || texImage
->Border
> 0) {
1602 _mesa_problem(NULL
, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
1606 assert(texImage
->IsCompressed
);
1608 ti
= TDFX_TEXTURE_DATA(texObj
);
1610 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1611 if (!texObj
->DriverData
) {
1612 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1615 ti
= TDFX_TEXTURE_DATA(texObj
);
1619 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1621 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1622 if (!texImage
->DriverData
) {
1623 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1626 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1629 tdfxTexGetInfo(ctx
, width
, height
, NULL
, NULL
, NULL
, NULL
,
1630 &mml
->wScale
, &mml
->hScale
);
1632 mml
->width
= width
* mml
->wScale
;
1633 mml
->height
= height
* mml
->hScale
;
1636 /* choose the texture format */
1637 assert(ctx
->Driver
.ChooseTextureFormat
);
1638 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1639 internalFormat
, -1/*format*/, -1/*type*/);
1640 assert(texImage
->TexFormat
);
1642 /* Determine the appropriate Glide texel format,
1643 * given the user's internal texture format hint.
1645 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1646 ti
->info
.format
= mml
->glideFormat
;
1647 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1649 /* allocate new storage for texture image, if needed */
1650 if (!texImage
->Data
) {
1651 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1656 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1657 if (!texImage
->Data
) {
1658 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1663 /* save the texture data */
1664 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1665 /* [dBorca] Hack alert:
1666 * now we're screwed. We can't decompress,
1667 * unless we do it in HW (via textureBuffer).
1668 * We still have some chances:
1669 * 1) we got FXT1 textures - we CAN decompress, rescale for
1670 * aspectratio, then compress back.
1671 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1672 * Thus, we don't care about textureclamp and we could lower
1673 * MIN("uscale", "vscale") below 32. We still have to have
1674 * our data aligned inside a 8:1 rectangle.
1675 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1676 * we replicate the data over the padded area.
1677 * For now, we take 2) + 3) but texelfetchers will be wrong!
1679 GLuint srcRowStride
= _mesa_compressed_row_stride(internalFormat
, width
);
1681 GLuint destRowStride
= _mesa_compressed_row_stride(internalFormat
,
1684 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1685 destRowStride
, (mml
->height
+3) / 4,
1686 1, data
, srcRowStride
,
1688 ti
->padded
= GL_TRUE
;
1690 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1693 /* GL_SGIS_generate_mipmap */
1694 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1695 assert(!texImage
->IsCompressed
);
1698 RevalidateTexture(ctx
, texObj
);
1700 ti
->reloadImages
= GL_TRUE
;
1701 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1706 tdfxCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1707 GLint level
, GLint xoffset
,
1708 GLint yoffset
, GLsizei width
,
1709 GLint height
, GLenum format
,
1710 GLsizei imageSize
, const GLvoid
*data
,
1711 struct gl_texture_object
*texObj
,
1712 struct gl_texture_image
*texImage
)
1714 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1716 tdfxMipMapLevel
*mml
;
1717 GLint destRowStride
, srcRowStride
;
1721 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1722 fprintf(stderr
, "tdfxCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1725 ti
= TDFX_TEXTURE_DATA(texObj
);
1727 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1730 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, width
);
1732 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1734 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1735 texImage
->IntFormat
,
1737 (GLubyte
*) texImage
->Data
);
1739 rows
= height
/ 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1741 for (i
= 0; i
< rows
; i
++) {
1742 MEMCPY(dest
, data
, srcRowStride
);
1743 dest
+= destRowStride
;
1744 data
= (GLvoid
*)((GLuint
)data
+ (GLuint
)srcRowStride
);
1747 /* [dBorca] Hack alert:
1748 * see fxDDCompressedTexImage2D for caveats
1750 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1751 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, texImage
->Width
);
1753 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1755 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1756 destRowStride
, mml
->height
/ 4,
1757 1, texImage
->Data
, destRowStride
,
1761 /* GL_SGIS_generate_mipmap */
1762 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1763 assert(!texImage
->IsCompressed
);
1766 RevalidateTexture(ctx
, texObj
);
1768 ti
->reloadImages
= GL_TRUE
;
1769 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1775 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1778 for (i
= 0; i
< h
; i
++) {
1779 for (j
= 0; j
< w
; j
++) {
1781 printf("%02x %02x ", data
[0], data
[1]);
1783 printf("%02x %02x %02x ", data
[0], data
[1], data
[2]);
1793 tdfxTestProxyTexImage(GLcontext
*ctx
, GLenum target
,
1794 GLint level
, GLint internalFormat
,
1795 GLenum format
, GLenum type
,
1796 GLint width
, GLint height
,
1797 GLint depth
, GLint border
)
1799 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1800 struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1801 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1804 case GL_PROXY_TEXTURE_1D
:
1806 case GL_PROXY_TEXTURE_2D
:
1808 struct gl_texture_object
*tObj
;
1812 tObj
= ctx
->Texture
.Proxy2D
;
1813 if (!tObj
->DriverData
)
1814 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1815 ti
= TDFX_TEXTURE_DATA(tObj
);
1818 /* assign the parameters to test against */
1819 tObj
->Image
[0][level
]->Width
= width
;
1820 tObj
->Image
[0][level
]->Height
= height
;
1821 tObj
->Image
[0][level
]->Border
= border
;
1823 tObj
->Image
[0][level
]->IntFormat
= internalFormat
;
1826 /* don't use mipmap levels > 0 */
1827 tObj
->MinFilter
= tObj
->MagFilter
= GL_NEAREST
;
1830 /* test with all mipmap levels */
1831 tObj
->MinFilter
= GL_LINEAR_MIPMAP_LINEAR
;
1832 tObj
->MagFilter
= GL_NEAREST
;
1834 RevalidateTexture(ctx
, tObj
);
1837 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1838 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1839 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1840 printf("glide format 0x%x\n", ti->info.format);
1841 printf("data %p\n", ti->info.data);
1842 printf("lodblend %d\n", (int) ti->LODblend);
1845 /* determine where texture will reside */
1846 if (ti
->LODblend
&& !shared
->umaTexMemory
) {
1847 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1848 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1849 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1852 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1853 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1854 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1857 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1859 if (memNeeded
> shared
->totalTexMem
[0])
1864 case GL_PROXY_TEXTURE_3D
:
1865 return GL_TRUE
; /* software rendering */
1867 return GL_TRUE
; /* never happens, silence compiler */
1873 * Allocate a new texture object.
1874 * Called via ctx->Driver.NewTextureObject.
1875 * Note: this function will be called during context creation to
1876 * allocate the default texture objects.
1877 * Note: we could use containment here to 'derive' the driver-specific
1878 * texture object from the core mesa gl_texture_object. Not done at this time.
1880 static struct gl_texture_object
*
1881 tdfxNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
1883 struct gl_texture_object
*obj
;
1884 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1889 void tdfxInitTextureFuncs( struct dd_function_table
*functions
)
1891 functions
->BindTexture
= tdfxBindTexture
;
1892 functions
->NewTextureObject
= tdfxNewTextureObject
;
1893 functions
->DeleteTexture
= tdfxDeleteTexture
;
1894 functions
->TexEnv
= tdfxTexEnv
;
1895 functions
->TexParameter
= tdfxTexParameter
;
1896 functions
->ChooseTextureFormat
= tdfxChooseTextureFormat
;
1897 functions
->TexImage1D
= tdfxTexImage1D
;
1898 functions
->TexSubImage1D
= tdfxTexSubImage1D
;
1899 functions
->TexImage2D
= tdfxTexImage2D
;
1900 functions
->TexSubImage2D
= tdfxTexSubImage2D
;
1901 functions
->IsTextureResident
= tdfxIsTextureResident
;
1902 functions
->CompressedTexImage2D
= tdfxCompressedTexImage2D
;
1903 functions
->CompressedTexSubImage2D
= tdfxCompressedTexSubImage2D
;
1904 functions
->UpdateTexturePalette
= tdfxUpdateTexturePalette
;