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
29 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
32 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
35 * Gareth Hughes <gareth@valinux.com>
36 * Brian Paul <brianp@valinux.com>
41 #include "main/enums.h"
42 #include "main/image.h"
43 #include "main/mipmap.h"
44 #include "main/texcompress.h"
45 #include "main/teximage.h"
46 #include "main/texstore.h"
47 #include "main/texobj.h"
48 #include "tdfx_context.h"
50 #include "tdfx_texman.h"
53 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
55 _mesa_halve2x2_teximage2d ( struct gl_context
*ctx
,
56 struct gl_texture_image
*texImage
,
58 GLint srcWidth
, GLint srcHeight
,
59 const GLvoid
*srcImage
, GLvoid
*dstImage
)
62 GLint dstWidth
= srcWidth
/ 2;
63 GLint dstHeight
= srcHeight
/ 2;
64 GLint srcRowStride
= srcWidth
* bytesPerPixel
;
65 GLubyte
*src
= (GLubyte
*)srcImage
;
66 GLubyte
*dst
= dstImage
;
67 GLuint dstImageOffsets
= 0;
74 if (texImage
->TexFormat
== MESA_FORMAT_RGB565
) {
75 _t
= GL_UNSIGNED_SHORT_5_6_5_REV
;
77 } else if (texImage
->TexFormat
== MESA_FORMAT_ARGB4444
) {
78 _t
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
80 } else if (texImage
->TexFormat
== MESA_FORMAT_ARGB1555
) {
81 _t
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
86 srcRowStride
= srcWidth
* bytesPerPixel
;
93 _s
= src
= MALLOC(srcRowStride
* srcHeight
);
94 _d
= dst
= MALLOC(dstWidth
* bytesPerPixel
* dstHeight
);
95 _mesa_texstore(ctx
, 2, GL_RGBA
,
96 MESA_FORMAT_RGBA8888_REV
, src
,
97 0, 0, 0, /* dstX/Y/Zoffset */
98 srcRowStride
, /* dstRowStride */
100 srcWidth
, srcHeight
, 1,
101 texImage
->_BaseFormat
, _t
, srcImage
, &ctx
->DefaultPacking
);
104 if (srcHeight
== 1) {
105 for (i
= 0; i
< dstWidth
; i
++) {
106 for (k
= 0; k
< bytesPerPixel
; k
++) {
107 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
111 src
+= bytesPerPixel
;
113 } else if (srcWidth
== 1) {
114 for (j
= 0; j
< dstHeight
; j
++) {
115 for (k
= 0; k
< bytesPerPixel
; k
++) {
116 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
123 for (j
= 0; j
< dstHeight
; j
++) {
124 for (i
= 0; i
< dstWidth
; i
++) {
125 for (k
= 0; k
< bytesPerPixel
; k
++) {
129 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
133 src
+= bytesPerPixel
;
142 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
143 texImage
->TexFormat
, dstImage
,
144 0, 0, 0, /* dstX/Y/Zoffset */
147 dstWidth
, dstHeight
, 1,
148 GL_BGRA
, CHAN_TYPE
, dst
, &ctx
->DefaultPacking
);
179 tdfxGenerateMipmap(struct gl_context
*ctx
, GLenum target
,
180 struct gl_texture_object
*texObj
)
182 GLint mipWidth
, mipHeight
;
183 tdfxMipMapLevel
*mip
;
184 struct gl_texture_image
*mipImage
; /* the new/next image */
185 struct gl_texture_image
*texImage
;
186 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
187 GLint level
= texObj
->BaseLevel
;
188 GLsizei width
, height
, texelBytes
;
189 const tdfxMipMapLevel
*mml
;
191 texImage
= _mesa_get_tex_image(ctx
, texObj
, target
, level
);
192 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
194 mml
= TDFX_TEXIMAGE_DATA(texImage
);
196 width
= texImage
->Width
;
197 height
= texImage
->Height
;
198 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
199 mipWidth
= width
/ 2;
203 mipHeight
= height
/ 2;
207 if ((mipWidth
== width
) && (mipHeight
== height
)) {
211 mipImage
= _mesa_select_tex_image(ctx
, texObj
, target
, level
);
212 mip
= TDFX_TEXIMAGE_DATA(mipImage
);
213 _mesa_halve2x2_teximage2d(ctx
,
216 mml
->width
, mml
->height
,
217 texImage
->Data
, mipImage
->Data
);
227 * Compute various texture image parameters.
228 * Input: w, h - source texture width and height
229 * Output: lodlevel - Glide lod level token for the larger texture dimension
230 * aspectratio - Glide aspect ratio token
231 * sscale - S scale factor used during triangle setup
232 * tscale - T scale factor used during triangle setup
233 * wscale - OpenGL -> Glide image width scale factor
234 * hscale - OpenGL -> Glide image height scale factor
237 * w h lodlevel aspectRatio
238 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
239 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
240 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
241 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
242 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
245 tdfxTexGetInfo(const struct gl_context
*ctx
, int w
, int h
,
246 GrLOD_t
*lodlevel
, GrAspectRatio_t
*aspectratio
,
247 float *sscale
, float *tscale
,
248 int *wscale
, int *hscale
)
250 int logw
, logh
, ar
, lod
, ws
, hs
;
258 ar
= logw
- logh
; /* aspect ratio = difference in log dimensions */
262 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
263 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
267 if (ar
<= GR_ASPECT_LOG2_8x1
) {
271 /* have to stretch image height */
274 ar
= GR_ASPECT_LOG2_8x1
;
280 if (ar
>= GR_ASPECT_LOG2_1x8
) {
284 /* have to stretch image width */
287 ar
= GR_ASPECT_LOG2_1x8
;
292 *lodlevel
= (GrLOD_t
) lod
;
294 *aspectratio
= (GrAspectRatio_t
) ar
;
307 * We need to call this when a texture object's minification filter
308 * or texture image sizes change.
310 static void RevalidateTexture(struct gl_context
*ctx
, struct gl_texture_object
*tObj
)
312 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
318 minl
= maxl
= tObj
->BaseLevel
;
320 if (tObj
->Image
[0][minl
]) {
321 maxl
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0][minl
]->MaxLog2
);
323 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
324 tdfxTexGetInfo(ctx
, tObj
->Image
[0][minl
]->Width
, tObj
->Image
[0][minl
]->Height
,
325 &ti
->info
.largeLodLog2
,
326 &ti
->info
.aspectRatioLog2
,
327 &(ti
->sScale
), &(ti
->tScale
), NULL
, NULL
);
330 if (tObj
->Image
[0][maxl
] && (tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
331 /* mipmapping: need to compute smallLodLog2 */
332 tdfxTexGetInfo(ctx
, tObj
->Image
[0][maxl
]->Width
,
333 tObj
->Image
[0][maxl
]->Height
,
334 &ti
->info
.smallLodLog2
, NULL
,
335 NULL
, NULL
, NULL
, NULL
);
338 /* not mipmapping: smallLodLog2 = largeLodLog2 */
339 ti
->info
.smallLodLog2
= ti
->info
.largeLodLog2
;
345 ti
->info
.data
= NULL
;
347 /* this is necessary because of fxDDCompressedTexImage2D */
349 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
350 tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
351 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
352 ti
->sScale
/= mml
->wScale
;
353 ti
->tScale
/= mml
->hScale
;
360 fxAllocTexObjData(tdfxContextPtr fxMesa
)
364 if (!(ti
= CALLOC(sizeof(tdfxTexInfo
)))) {
365 _mesa_problem(NULL
, "tdfx driver: out of memory");
369 ti
->isInTM
= GL_FALSE
;
371 ti
->whichTMU
= TDFX_TMU_NONE
;
373 ti
->tm
[TDFX_TMU0
] = NULL
;
374 ti
->tm
[TDFX_TMU1
] = NULL
;
376 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
377 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
379 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
380 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
382 ti
->mmMode
= GR_MIPMAP_NEAREST
;
383 ti
->LODblend
= FXFALSE
;
390 * Called via glBindTexture.
393 tdfxBindTexture(struct gl_context
* ctx
, GLenum target
,
394 struct gl_texture_object
*tObj
)
396 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
399 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
400 fprintf(stderr
, "fxmesa: fxDDTexBind(%d,%p)\n", tObj
->Name
,
404 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
407 if (!tObj
->DriverData
) {
408 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
411 ti
= TDFX_TEXTURE_DATA(tObj
);
412 ti
->lastTimeUsed
= fxMesa
->texBindNumber
++;
414 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
419 * Called via glTexEnv.
422 tdfxTexEnv(struct gl_context
* ctx
, GLenum target
, GLenum pname
,
423 const GLfloat
* param
)
425 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
427 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
429 fprintf(stderr
, "fxmesa: texenv(%x,%x)\n", pname
,
432 fprintf(stderr
, "fxmesa: texenv(%x)\n", pname
);
435 /* XXX this is a bit of a hack to force the Glide texture
436 * state to be updated.
438 fxMesa
->TexState
.EnvMode
[ctx
->Texture
.CurrentUnit
] = 0;
440 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
445 * Called via glTexParameter.
448 tdfxTexParameter(struct gl_context
* ctx
, GLenum target
,
449 struct gl_texture_object
*tObj
,
450 GLenum pname
, const GLfloat
* params
)
452 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
453 GLenum param
= (GLenum
) (GLint
) params
[0];
456 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
457 fprintf(stderr
, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj
->Name
,
458 tObj
->DriverData
, pname
, param
);
461 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
464 if (!tObj
->DriverData
)
465 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
467 ti
= TDFX_TEXTURE_DATA(tObj
);
470 case GL_TEXTURE_MIN_FILTER
:
473 ti
->mmMode
= GR_MIPMAP_DISABLE
;
474 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
475 ti
->LODblend
= FXFALSE
;
478 ti
->mmMode
= GR_MIPMAP_DISABLE
;
479 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
480 ti
->LODblend
= FXFALSE
;
482 case GL_NEAREST_MIPMAP_LINEAR
:
483 if (!fxMesa
->Glide
.HaveCombineExt
) {
484 if (fxMesa
->haveTwoTMUs
) {
485 ti
->mmMode
= GR_MIPMAP_NEAREST
;
486 ti
->LODblend
= FXTRUE
;
489 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
490 ti
->LODblend
= FXFALSE
;
492 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
495 /* XXX Voodoo3/Banshee mipmap blending seems to produce
496 * incorrectly filtered colors for the smallest mipmap levels.
497 * To work-around we fall-through here and use a different filter.
499 case GL_NEAREST_MIPMAP_NEAREST
:
500 ti
->mmMode
= GR_MIPMAP_NEAREST
;
501 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
502 ti
->LODblend
= FXFALSE
;
504 case GL_LINEAR_MIPMAP_LINEAR
:
505 if (!fxMesa
->Glide
.HaveCombineExt
) {
506 if (fxMesa
->haveTwoTMUs
) {
507 ti
->mmMode
= GR_MIPMAP_NEAREST
;
508 ti
->LODblend
= FXTRUE
;
511 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
512 ti
->LODblend
= FXFALSE
;
514 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
517 /* XXX Voodoo3/Banshee mipmap blending seems to produce
518 * incorrectly filtered colors for the smallest mipmap levels.
519 * To work-around we fall-through here and use a different filter.
521 case GL_LINEAR_MIPMAP_NEAREST
:
522 ti
->mmMode
= GR_MIPMAP_NEAREST
;
523 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
524 ti
->LODblend
= FXFALSE
;
529 ti
->reloadImages
= GL_TRUE
;
530 RevalidateTexture(ctx
, tObj
);
531 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
534 case GL_TEXTURE_MAG_FILTER
:
537 ti
->magFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
540 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
545 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
548 case GL_TEXTURE_WRAP_S
:
550 case GL_CLAMP_TO_BORDER
:
551 case GL_CLAMP_TO_EDGE
:
553 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
556 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
558 case GL_MIRRORED_REPEAT
:
559 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
564 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
567 case GL_TEXTURE_WRAP_T
:
569 case GL_CLAMP_TO_BORDER
:
570 case GL_CLAMP_TO_EDGE
:
572 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
575 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
577 case GL_MIRRORED_REPEAT
:
578 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
583 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
586 case GL_TEXTURE_BORDER_COLOR
:
589 case GL_TEXTURE_MIN_LOD
:
592 case GL_TEXTURE_MAX_LOD
:
595 case GL_TEXTURE_BASE_LEVEL
:
596 RevalidateTexture(ctx
, tObj
);
598 case GL_TEXTURE_MAX_LEVEL
:
599 RevalidateTexture(ctx
, tObj
);
609 * Called via glDeleteTextures to delete a texture object.
610 * Here, we delete the Glide data associated with the texture.
613 tdfxDeleteTexture(struct gl_context
* ctx
, struct gl_texture_object
*tObj
)
615 if (ctx
&& ctx
->DriverCtx
) {
616 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
617 tdfxTMFreeTexture(fxMesa
, tObj
);
618 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
619 /* Free mipmap images and the texture object itself */
620 _mesa_delete_texture_object(ctx
, tObj
);
626 * Return true if texture is resident, false otherwise.
629 tdfxIsTextureResident(struct gl_context
*ctx
, struct gl_texture_object
*tObj
)
631 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
632 return (GLboolean
) (ti
&& ti
->isInTM
);
638 * Convert a gl_color_table texture palette to Glide's format.
641 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
643 const GLubyte
*tableUB
= table
->TableUB
;
644 GLint width
= table
->Size
;
648 switch (table
->_BaseFormat
) {
650 for (i
= 0; i
< width
; i
++) {
655 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
657 return GR_TEXTABLE_PALETTE_6666_EXT
;
659 for (i
= 0; i
< width
; i
++) {
664 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
666 return GR_TEXTABLE_PALETTE
;
668 for (i
= 0; i
< width
; i
++) {
671 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
673 return GR_TEXTABLE_PALETTE_6666_EXT
;
674 case GL_LUMINANCE_ALPHA
:
675 for (i
= 0; i
< width
; i
++) {
676 r
= g
= b
= tableUB
[i
* 2 + 0];
677 a
= tableUB
[i
* 2 + 1];
678 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
680 return GR_TEXTABLE_PALETTE_6666_EXT
;
682 for (i
= 0; i
< width
; i
++) {
683 r
= tableUB
[i
* 3 + 0];
684 g
= tableUB
[i
* 3 + 1];
685 b
= tableUB
[i
* 3 + 2];
687 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
689 return GR_TEXTABLE_PALETTE
;
691 for (i
= 0; i
< width
; i
++) {
692 r
= tableUB
[i
* 4 + 0];
693 g
= tableUB
[i
* 4 + 1];
694 b
= tableUB
[i
* 4 + 2];
695 a
= tableUB
[i
* 4 + 3];
696 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
698 return GR_TEXTABLE_PALETTE_6666_EXT
;
700 /* XXX fixme: how can this happen? */
701 _mesa_error(NULL
, GL_INVALID_ENUM
, "convertPalette: table->Format == %s",
702 _mesa_lookup_enum_by_nr(table
->Format
));
703 return GR_TEXTABLE_PALETTE
;
710 tdfxUpdateTexturePalette(struct gl_context
* ctx
, struct gl_texture_object
*tObj
)
712 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
715 /* per-texture palette */
718 /* This might be a proxy texture. */
719 if (!tObj
->Palette
.TableUB
)
722 if (!tObj
->DriverData
)
723 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
724 ti
= TDFX_TEXTURE_DATA(tObj
);
726 ti
->paltype
= convertPalette(ti
->palette
.data
, &tObj
->Palette
);
727 /*tdfxTexInvalidate(ctx, tObj);*/
730 /* global texture palette */
731 fxMesa
->TexPalette
.Type
= convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
732 fxMesa
->TexPalette
.Data
= &(fxMesa
->glbPalette
.data
);
733 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
735 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX too heavy-handed */
739 /**********************************************************************/
740 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
741 /**********************************************************************/
744 static FxBool TexusFatalError
= FXFALSE
;
745 static FxBool TexusError
= FXFALSE
;
747 #define TX_DITHER_NONE 0x00000000
750 fxTexusError(const char *string
, FxBool fatal
)
752 _mesa_problem(NULL
, string
);
754 * Just propagate the fatal value up.
757 TexusFatalError
= fatal
;
763 tdfxChooseTextureFormat( struct gl_context
*ctx
, GLint internalFormat
,
764 GLenum srcFormat
, GLenum srcType
)
766 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
767 const GLboolean allow32bpt
= TDFX_IS_NAPALM(fxMesa
);
769 switch (internalFormat
) {
775 case GL_COMPRESSED_ALPHA
:
776 return MESA_FORMAT_A8
;
783 case GL_COMPRESSED_LUMINANCE
:
784 return MESA_FORMAT_L8
;
786 case GL_LUMINANCE_ALPHA
:
787 case GL_LUMINANCE4_ALPHA4
:
788 case GL_LUMINANCE6_ALPHA2
:
789 case GL_LUMINANCE8_ALPHA8
:
790 case GL_LUMINANCE12_ALPHA4
:
791 case GL_LUMINANCE12_ALPHA12
:
792 case GL_LUMINANCE16_ALPHA16
:
793 case GL_COMPRESSED_LUMINANCE_ALPHA
:
794 return MESA_FORMAT_AL88
;
800 case GL_COMPRESSED_INTENSITY
:
801 return MESA_FORMAT_I8
;
805 return MESA_FORMAT_RGB565
;
806 case GL_COMPRESSED_RGB
:
807 /* intentional fall-through */
810 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
811 return MESA_FORMAT_RGB565
;
813 /* intentional fall through */
818 return (allow32bpt
) ? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
821 return MESA_FORMAT_ARGB4444
;
822 case GL_COMPRESSED_RGBA
:
823 /* intentional fall-through */
826 if ( srcFormat
== GL_BGRA
) {
827 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
828 return MESA_FORMAT_ARGB8888
;
830 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
831 return MESA_FORMAT_ARGB4444
;
833 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
834 return MESA_FORMAT_ARGB1555
;
837 /* intentional fall through */
842 return allow32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
844 return MESA_FORMAT_ARGB1555
;
846 case GL_COLOR_INDEX1_EXT
:
847 case GL_COLOR_INDEX2_EXT
:
848 case GL_COLOR_INDEX4_EXT
:
849 case GL_COLOR_INDEX8_EXT
:
850 case GL_COLOR_INDEX12_EXT
:
851 case GL_COLOR_INDEX16_EXT
:
852 return MESA_FORMAT_CI8
;
853 /* GL_EXT_texture_compression_s3tc */
855 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
858 return MESA_FORMAT_RGB_DXT1
;
859 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
860 return MESA_FORMAT_RGBA_DXT1
;
861 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
864 return MESA_FORMAT_RGBA_DXT3
;
865 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
866 return MESA_FORMAT_RGBA_DXT5
;
867 /* GL_3DFX_texture_compression_FXT1 */
868 case GL_COMPRESSED_RGB_FXT1_3DFX
:
869 return MESA_FORMAT_RGB_FXT1
;
870 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
871 return MESA_FORMAT_RGBA_FXT1
;
873 _mesa_problem(ctx
, "unexpected format in tdfxChooseTextureFormat");
874 return MESA_FORMAT_NONE
;
880 * Return the Glide format for the given mesa texture format.
882 static GrTextureFormat_t
883 fxGlideFormat(GLint mesaFormat
)
885 switch (mesaFormat
) {
887 return GR_TEXFMT_ALPHA_8
;
889 return GR_TEXFMT_ALPHA_8
;
891 return GR_TEXFMT_INTENSITY_8
;
892 case MESA_FORMAT_CI8
:
893 return GR_TEXFMT_P_8
;
894 case MESA_FORMAT_AL88
:
895 return GR_TEXFMT_ALPHA_INTENSITY_88
;
896 case MESA_FORMAT_RGB565
:
897 return GR_TEXFMT_RGB_565
;
898 case MESA_FORMAT_ARGB4444
:
899 return GR_TEXFMT_ARGB_4444
;
900 case MESA_FORMAT_ARGB1555
:
901 return GR_TEXFMT_ARGB_1555
;
902 case MESA_FORMAT_ARGB8888
:
903 return GR_TEXFMT_ARGB_8888
;
904 case MESA_FORMAT_RGB_FXT1
:
905 case MESA_FORMAT_RGBA_FXT1
:
906 return GR_TEXFMT_ARGB_CMP_FXT1
;
907 case MESA_FORMAT_RGB_DXT1
:
908 case MESA_FORMAT_RGBA_DXT1
:
909 return GR_TEXFMT_ARGB_CMP_DXT1
;
910 case MESA_FORMAT_RGBA_DXT3
:
911 return GR_TEXFMT_ARGB_CMP_DXT3
;
912 case MESA_FORMAT_RGBA_DXT5
:
913 return GR_TEXFMT_ARGB_CMP_DXT5
;
915 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
921 /* Texel-fetch functions for software texturing and glGetTexImage().
922 * We should have been able to use some "standard" fetch functions (which
923 * may get defined in texutil.c) but we have to account for scaled texture
924 * images on tdfx hardware (the 8:1 aspect ratio limit).
925 * Hence, we need special functions here.
928 fxt1_decode_1 (const void *texture
, int width
,
929 int i
, int j
, unsigned char *rgba
);
932 fetch_intensity8(const struct gl_texture_image
*texImage
,
933 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
935 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
936 const GLubyte
*texel
;
941 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
942 rgba
[RCOMP
] = *texel
;
943 rgba
[GCOMP
] = *texel
;
944 rgba
[BCOMP
] = *texel
;
945 rgba
[ACOMP
] = *texel
;
950 fetch_luminance8(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
;
960 rgba
[RCOMP
] = *texel
;
961 rgba
[GCOMP
] = *texel
;
962 rgba
[BCOMP
] = *texel
;
968 fetch_alpha8(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 GLubyte
*texel
;
977 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
981 rgba
[ACOMP
] = *texel
;
986 fetch_index8(const struct gl_texture_image
*texImage
,
987 GLint i
, GLint j
, GLint k
, GLchan
* indexOut
)
989 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
990 const GLubyte
*texel
;
995 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
1001 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
1002 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1004 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1005 const GLubyte
*texel
;
1007 i
= i
* mml
->wScale
;
1008 j
= j
* mml
->hScale
;
1010 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
1011 rgba
[RCOMP
] = texel
[0];
1012 rgba
[GCOMP
] = texel
[0];
1013 rgba
[BCOMP
] = texel
[0];
1014 rgba
[ACOMP
] = texel
[1];
1019 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
1020 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1022 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1023 const GLushort
*texel
;
1025 i
= i
* mml
->wScale
;
1026 j
= j
* mml
->hScale
;
1028 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1029 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
1030 rgba
[GCOMP
] = (((*texel
) >> 5) & 0x3f) * 255 / 63;
1031 rgba
[BCOMP
] = (((*texel
) >> 0) & 0x1f) * 255 / 31;
1037 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
1038 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1040 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1041 const GLushort
*texel
;
1043 i
= i
* mml
->wScale
;
1044 j
= j
* mml
->hScale
;
1046 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1047 rgba
[RCOMP
] = (((*texel
) >> 12) & 0xf) * 255 / 15;
1048 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xf) * 255 / 15;
1049 rgba
[BCOMP
] = (((*texel
) >> 4) & 0xf) * 255 / 15;
1050 rgba
[ACOMP
] = (((*texel
) >> 0) & 0xf) * 255 / 15;
1055 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
1056 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1058 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1059 const GLushort
*texel
;
1061 i
= i
* mml
->wScale
;
1062 j
= j
* mml
->hScale
;
1064 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1065 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
1066 rgba
[GCOMP
] = (((*texel
) >> 6) & 0x1f) * 255 / 31;
1067 rgba
[BCOMP
] = (((*texel
) >> 1) & 0x1f) * 255 / 31;
1068 rgba
[ACOMP
] = (((*texel
) >> 0) & 0x01) * 255;
1073 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
1074 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1076 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1077 const GLuint
*texel
;
1079 i
= i
* mml
->wScale
;
1080 j
= j
* mml
->hScale
;
1082 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
1083 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
1084 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
1085 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
1086 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
1091 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
1092 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1094 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1096 i
= i
* mml
->wScale
;
1097 j
= j
* mml
->hScale
;
1099 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1105 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
1106 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1108 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1110 i
= i
* mml
->wScale
;
1111 j
= j
* mml
->hScale
;
1113 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1118 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
1119 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1121 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1123 i
= i
* mml
->wScale
;
1124 j
= j
* mml
->hScale
;
1126 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1127 _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
1133 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
1134 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1136 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1138 i
= i
* mml
->wScale
;
1139 j
= j
* mml
->hScale
;
1141 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1142 _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
1148 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
1149 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1151 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1153 i
= i
* mml
->wScale
;
1154 j
= j
* mml
->hScale
;
1156 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1157 _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba);
1163 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
1164 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1166 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1168 i
= i
* mml
->wScale
;
1169 j
= j
* mml
->hScale
;
1171 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1172 _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba);
1177 static FetchTexelFuncC
1178 fxFetchFunction(GLint mesaFormat
)
1180 switch (mesaFormat
) {
1181 case MESA_FORMAT_I8
:
1182 return &fetch_intensity8
;
1183 case MESA_FORMAT_A8
:
1184 return &fetch_alpha8
;
1185 case MESA_FORMAT_L8
:
1186 return &fetch_luminance8
;
1187 case MESA_FORMAT_CI8
:
1188 return &fetch_index8
;
1189 case MESA_FORMAT_AL88
:
1190 return &fetch_luminance8_alpha8
;
1191 case MESA_FORMAT_RGB565
:
1192 return &fetch_r5g6b5
;
1193 case MESA_FORMAT_ARGB4444
:
1194 return &fetch_r4g4b4a4
;
1195 case MESA_FORMAT_ARGB1555
:
1196 return &fetch_r5g5b5a1
;
1197 case MESA_FORMAT_ARGB8888
:
1198 return &fetch_a8r8g8b8
;
1199 case MESA_FORMAT_RGB_FXT1
:
1200 return &fetch_rgb_fxt1
;
1201 case MESA_FORMAT_RGBA_FXT1
:
1202 return &fetch_rgba_fxt1
;
1203 case MESA_FORMAT_RGB_DXT1
:
1204 return &fetch_rgb_dxt1
;
1205 case MESA_FORMAT_RGBA_DXT1
:
1206 return &fetch_rgba_dxt1
;
1207 case MESA_FORMAT_RGBA_DXT3
:
1208 return &fetch_rgba_dxt3
;
1209 case MESA_FORMAT_RGBA_DXT5
:
1210 return &fetch_rgba_dxt5
;
1212 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1219 adjust2DRatio (struct gl_context
*ctx
,
1220 GLint xoffset
, GLint yoffset
,
1221 GLint width
, GLint height
,
1222 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1223 const struct gl_pixelstore_attrib
*packing
,
1224 tdfxMipMapLevel
*mml
,
1225 struct gl_texture_image
*texImage
,
1229 const GLint newWidth
= width
* mml
->wScale
;
1230 const GLint newHeight
= height
* mml
->hScale
;
1232 GLuint dstImageOffsets
= 0;
1234 if (!_mesa_is_format_compressed(texImage
->TexFormat
)) {
1237 tempImage
= MALLOC(width
* height
* texelBytes
);
1242 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1243 texImage
->TexFormat
, tempImage
,
1244 0, 0, 0, /* dstX/Y/Zoffset */
1245 width
* texelBytes
, /* dstRowStride */
1248 format
, type
, pixels
, packing
);
1251 /* compute address of dest subimage within the overal tex image */
1252 destAddr
= (GLubyte
*) texImage
->Data
1253 + (yoffset
* mml
->hScale
* mml
->width
1254 + xoffset
* mml
->wScale
) * texelBytes
;
1256 _mesa_rescale_teximage2d(texelBytes
,
1258 dstRowStride
, /* dst stride */
1260 newWidth
, newHeight
,
1261 tempImage
, destAddr
);
1263 const GLint rawBytes
= 4;
1264 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1269 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1274 /* unpack image, apply transfer ops and store in rawImage */
1275 _mesa_texstore(ctx
, 2, GL_RGBA
,
1276 MESA_FORMAT_RGBA8888_REV
, rawImage
,
1277 0, 0, 0, /* dstX/Y/Zoffset */
1278 width
* rawBytes
, /* dstRowStride */
1281 format
, type
, pixels
, packing
);
1282 _mesa_rescale_teximage2d(rawBytes
,
1284 newWidth
* rawBytes
, /* dst stride */
1285 width
, height
, /* src */
1286 newWidth
, newHeight
, /* dst */
1287 rawImage
/*src*/, tempImage
/*dst*/ );
1288 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1289 texImage
->TexFormat
, texImage
->Data
,
1290 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1293 newWidth
, newHeight
, 1,
1294 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1305 tdfxTexImage2D(struct gl_context
*ctx
, GLenum target
, GLint level
,
1306 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1307 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1308 const struct gl_pixelstore_attrib
*packing
,
1309 struct gl_texture_object
*texObj
,
1310 struct gl_texture_image
*texImage
)
1312 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1314 tdfxMipMapLevel
*mml
;
1315 GLint texelBytes
, dstRowStride
;
1319 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1320 texObj->Name, texImage->InternalFormat, format, type,
1321 texImage->Width, texImage->Height);
1324 ti
= TDFX_TEXTURE_DATA(texObj
);
1326 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1327 if (!texObj
->DriverData
) {
1328 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1331 ti
= TDFX_TEXTURE_DATA(texObj
);
1335 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1337 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1338 if (!texImage
->DriverData
) {
1339 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1342 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1345 /* Determine width and height scale factors for texture.
1346 * Remember, Glide is limited to 8:1 aspect ratios.
1349 texImage
->Width
, texImage
->Height
,
1350 NULL
, /* lod level */
1351 NULL
, /* aspect ratio */
1352 NULL
, NULL
, /* sscale, tscale */
1353 &mml
->wScale
, &mml
->hScale
);
1355 /* rescaled size: */
1356 mml
->width
= width
* mml
->wScale
;
1357 mml
->height
= height
* mml
->hScale
;
1359 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1360 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1361 /* [dBorca] we should update texture's attribute, then,
1362 * because if the application asks us to decompress, we
1363 * have to know the REAL format! Also, DXT3/5 might not
1364 * be correct, since it would mess with "compressedSize".
1365 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1367 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
1368 switch (internalFormat
) {
1369 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1372 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1374 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1375 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1376 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1379 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1381 texImage
->InternalFormat
= internalFormat
;
1385 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1386 GLenum texNapalm
= 0;
1387 if (internalFormat
== GL_COMPRESSED_RGB
) {
1388 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1389 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1390 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1393 texImage
->InternalFormat
= internalFormat
= texNapalm
;
1394 _mesa_is_format_compressed(texImage
->TexFormat
) = GL_TRUE
;
1399 mesaFormat
= texImage
->TexFormat
;
1400 mml
->glideFormat
= fxGlideFormat(mesaFormat
);
1401 ti
->info
.format
= mml
->glideFormat
;
1402 texImage
->FetchTexelc
= fxFetchFunction(mesaFormat
);
1403 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
1405 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
1406 GLuint compressedSize
= _mesa_format_image_size(mesaFormat
, mml
->width
,
1408 dstRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, mml
->width
);
1409 texImage
->Data
= _mesa_alloc_texmemory(compressedSize
);
1411 dstRowStride
= mml
->width
* texelBytes
;
1412 texImage
->Data
= _mesa_alloc_texmemory(mml
->width
* mml
->height
* texelBytes
);
1414 if (!texImage
->Data
) {
1415 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1419 if (pixels
!= NULL
) {
1420 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1421 /* rescale image to overcome 1:8 aspect limitation */
1422 if (!adjust2DRatio(ctx
,
1425 format
, type
, pixels
,
1432 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1437 /* no rescaling needed */
1438 /* unpack image, apply transfer ops and store in texImage->Data */
1439 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1440 texImage
->TexFormat
, texImage
->Data
,
1441 0, 0, 0, /* dstX/Y/Zoffset */
1443 texImage
->ImageOffsets
,
1445 format
, type
, pixels
, packing
);
1449 RevalidateTexture(ctx
, texObj
);
1451 ti
->reloadImages
= GL_TRUE
;
1452 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1457 tdfxTexSubImage2D(struct gl_context
*ctx
, GLenum target
, GLint level
,
1458 GLint xoffset
, GLint yoffset
,
1459 GLsizei width
, GLsizei height
,
1460 GLenum format
, GLenum type
,
1461 const GLvoid
*pixels
,
1462 const struct gl_pixelstore_attrib
*packing
,
1463 struct gl_texture_object
*texObj
,
1464 struct gl_texture_image
*texImage
)
1466 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1468 tdfxMipMapLevel
*mml
;
1469 GLint texelBytes
, dstRowStride
;
1471 if (!texObj
->DriverData
) {
1472 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1476 ti
= TDFX_TEXTURE_DATA(texObj
);
1478 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1481 assert(texImage
->Data
); /* must have an existing texture image! */
1482 assert(texImage
->_BaseFormat
);
1484 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
1485 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
1486 dstRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, mml
->width
);
1488 dstRowStride
= mml
->width
* texelBytes
;
1491 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1492 /* need to rescale subimage to match mipmap level's rescale factors */
1493 if (!adjust2DRatio(ctx
,
1496 format
, type
, pixels
,
1503 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1508 /* no rescaling needed */
1509 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1510 texImage
->TexFormat
, texImage
->Data
,
1511 xoffset
, yoffset
, 0,
1513 texImage
->ImageOffsets
,
1515 format
, type
, pixels
, packing
);
1518 ti
->reloadImages
= GL_TRUE
; /* signal the image needs to be reloaded */
1519 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX this might be a bit much */
1524 tdfxTexImage1D(struct gl_context
*ctx
, GLenum target
, GLint level
,
1525 GLint internalFormat
, GLint width
, GLint border
,
1526 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1527 const struct gl_pixelstore_attrib
*packing
,
1528 struct gl_texture_object
*texObj
,
1529 struct gl_texture_image
*texImage
)
1531 tdfxTexImage2D(ctx
, target
, level
,
1532 internalFormat
, width
, 1, border
,
1533 format
, type
, pixels
,
1540 tdfxTexSubImage1D(struct gl_context
*ctx
, GLenum target
, GLint level
,
1543 GLenum format
, GLenum type
,
1544 const GLvoid
*pixels
,
1545 const struct gl_pixelstore_attrib
*packing
,
1546 struct gl_texture_object
*texObj
,
1547 struct gl_texture_image
*texImage
)
1549 tdfxTexSubImage2D(ctx
, target
, level
,
1559 /**********************************************************************/
1560 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1561 /**********************************************************************/
1564 tdfxCompressedTexImage2D (struct gl_context
*ctx
, GLenum target
,
1565 GLint level
, GLint internalFormat
,
1566 GLsizei width
, GLsizei height
, GLint border
,
1567 GLsizei imageSize
, const GLvoid
*data
,
1568 struct gl_texture_object
*texObj
,
1569 struct gl_texture_image
*texImage
)
1571 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1573 tdfxMipMapLevel
*mml
;
1574 gl_format mesaFormat
;
1575 GLuint compressedSize
= 0;
1577 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1578 fprintf(stderr
, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1579 texObj
->Name
, internalFormat
,
1583 if ((target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
) || texImage
->Border
> 0) {
1584 _mesa_problem(NULL
, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
1588 ti
= TDFX_TEXTURE_DATA(texObj
);
1590 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1591 if (!texObj
->DriverData
) {
1592 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1595 ti
= TDFX_TEXTURE_DATA(texObj
);
1599 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1601 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1602 if (!texImage
->DriverData
) {
1603 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1606 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1609 tdfxTexGetInfo(ctx
, width
, height
, NULL
, NULL
, NULL
, NULL
,
1610 &mml
->wScale
, &mml
->hScale
);
1612 mml
->width
= width
* mml
->wScale
;
1613 mml
->height
= height
* mml
->hScale
;
1616 /* Determine the appropriate Glide texel format,
1617 * given the user's internal texture format hint.
1619 mesaFormat
= texImage
->TexFormat
;
1620 mml
->glideFormat
= fxGlideFormat(mesaFormat
);
1621 ti
->info
.format
= mml
->glideFormat
;
1622 texImage
->FetchTexelc
= fxFetchFunction(mesaFormat
);
1624 /* allocate new storage for texture image, if needed */
1625 if (!texImage
->Data
) {
1626 compressedSize
= _mesa_format_image_size(mesaFormat
, mml
->width
,
1628 texImage
->Data
= _mesa_alloc_texmemory(compressedSize
);
1629 if (!texImage
->Data
) {
1630 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1635 /* save the texture data */
1636 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1637 /* [dBorca] Hack alert:
1638 * now we're screwed. We can't decompress,
1639 * unless we do it in HW (via textureBuffer).
1640 * We still have some chances:
1641 * 1) we got FXT1 textures - we CAN decompress, rescale for
1642 * aspectratio, then compress back.
1643 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1644 * Thus, we don't care about textureclamp and we could lower
1645 * MIN("uscale", "vscale") below 32. We still have to have
1646 * our data aligned inside a 8:1 rectangle.
1647 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1648 * we replicate the data over the padded area.
1649 * For now, we take 2) + 3) but texelfetchers will be wrong!
1651 const GLuint mesaFormat
= texImage
->TexFormat
;
1652 GLuint srcRowStride
= _mesa_format_row_stride(mesaFormat
, width
);
1654 GLuint destRowStride
= _mesa_format_row_stride(mesaFormat
,
1657 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1658 destRowStride
, (mml
->height
+3) / 4,
1659 1, data
, srcRowStride
,
1661 ti
->padded
= GL_TRUE
;
1663 memcpy(texImage
->Data
, data
, compressedSize
);
1666 RevalidateTexture(ctx
, texObj
);
1668 ti
->reloadImages
= GL_TRUE
;
1669 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1674 tdfxCompressedTexSubImage2D( struct gl_context
*ctx
, GLenum target
,
1675 GLint level
, GLint xoffset
,
1676 GLint yoffset
, GLsizei width
,
1677 GLint height
, GLenum format
,
1678 GLsizei imageSize
, const GLvoid
*data
,
1679 struct gl_texture_object
*texObj
,
1680 struct gl_texture_image
*texImage
)
1682 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1684 tdfxMipMapLevel
*mml
;
1685 GLint destRowStride
, srcRowStride
;
1688 const GLuint mesaFormat
= texImage
->TexFormat
;
1690 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1691 fprintf(stderr
, "tdfxCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1694 ti
= TDFX_TEXTURE_DATA(texObj
);
1696 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1699 srcRowStride
= _mesa_format_row_stride(mesaFormat
, width
);
1701 destRowStride
= _mesa_format_row_stride(mesaFormat
, mml
->width
);
1702 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1705 (GLubyte
*) texImage
->Data
);
1707 rows
= height
/ 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1709 for (i
= 0; i
< rows
; i
++) {
1710 memcpy(dest
, data
, srcRowStride
);
1711 dest
+= destRowStride
;
1712 data
= (GLvoid
*)((intptr_t)data
+ (intptr_t)srcRowStride
);
1715 /* [dBorca] Hack alert:
1716 * see fxDDCompressedTexImage2D for caveats
1718 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1719 srcRowStride
= _mesa_format_row_stride(mesaFormat
, texImage
->Width
);
1721 destRowStride
= _mesa_format_row_stride(mesaFormat
, mml
->width
);
1722 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1723 destRowStride
, mml
->height
/ 4,
1724 1, texImage
->Data
, destRowStride
,
1728 RevalidateTexture(ctx
, texObj
);
1730 ti
->reloadImages
= GL_TRUE
;
1731 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1737 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1740 for (i
= 0; i
< h
; i
++) {
1741 for (j
= 0; j
< w
; j
++) {
1743 printf("%02x %02x ", data
[0], data
[1]);
1745 printf("%02x %02x %02x ", data
[0], data
[1], data
[2]);
1755 tdfxTestProxyTexImage(struct gl_context
*ctx
, GLenum target
,
1756 GLint level
, GLint internalFormat
,
1757 GLenum format
, GLenum type
,
1758 GLint width
, GLint height
,
1759 GLint depth
, GLint border
)
1761 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1762 struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1763 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1766 case GL_PROXY_TEXTURE_1D
:
1768 case GL_PROXY_TEXTURE_2D
:
1770 struct gl_texture_object
*tObj
;
1774 tObj
= ctx
->Texture
.ProxyTex
[TEXTURE_2D_INDEX
];
1775 if (!tObj
->DriverData
)
1776 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1777 ti
= TDFX_TEXTURE_DATA(tObj
);
1780 /* assign the parameters to test against */
1781 tObj
->Image
[0][level
]->Width
= width
;
1782 tObj
->Image
[0][level
]->Height
= height
;
1783 tObj
->Image
[0][level
]->Border
= border
;
1785 tObj
->Image
[0][level
]->InternalFormat
= internalFormat
;
1788 /* don't use mipmap levels > 0 */
1789 tObj
->MinFilter
= tObj
->MagFilter
= GL_NEAREST
;
1792 /* test with all mipmap levels */
1793 tObj
->MinFilter
= GL_LINEAR_MIPMAP_LINEAR
;
1794 tObj
->MagFilter
= GL_NEAREST
;
1796 RevalidateTexture(ctx
, tObj
);
1799 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1800 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1801 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1802 printf("glide format 0x%x\n", ti->info.format);
1803 printf("data %p\n", ti->info.data);
1804 printf("lodblend %d\n", (int) ti->LODblend);
1807 /* determine where texture will reside */
1808 if (ti
->LODblend
&& !shared
->umaTexMemory
) {
1809 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1810 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1811 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1814 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1815 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1816 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1819 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1821 if (memNeeded
> shared
->totalTexMem
[0])
1826 case GL_PROXY_TEXTURE_3D
:
1827 return GL_TRUE
; /* software rendering */
1829 return GL_TRUE
; /* never happens, silence compiler */
1835 * Allocate a new texture object.
1836 * Called via ctx->Driver.NewTextureObject.
1837 * Note: this function will be called during context creation to
1838 * allocate the default texture objects.
1839 * Note: we could use containment here to 'derive' the driver-specific
1840 * texture object from the core mesa gl_texture_object. Not done at this time.
1842 static struct gl_texture_object
*
1843 tdfxNewTextureObject( struct gl_context
*ctx
, GLuint name
, GLenum target
)
1845 struct gl_texture_object
*obj
;
1846 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1851 void tdfxInitTextureFuncs( struct dd_function_table
*functions
)
1853 functions
->BindTexture
= tdfxBindTexture
;
1854 functions
->NewTextureObject
= tdfxNewTextureObject
;
1855 functions
->DeleteTexture
= tdfxDeleteTexture
;
1856 functions
->TexEnv
= tdfxTexEnv
;
1857 functions
->TexParameter
= tdfxTexParameter
;
1858 functions
->ChooseTextureFormat
= tdfxChooseTextureFormat
;
1859 functions
->TexImage1D
= tdfxTexImage1D
;
1860 functions
->TexSubImage1D
= tdfxTexSubImage1D
;
1861 functions
->TexImage2D
= tdfxTexImage2D
;
1862 functions
->TexSubImage2D
= tdfxTexSubImage2D
;
1863 functions
->IsTextureResident
= tdfxIsTextureResident
;
1864 functions
->CompressedTexImage2D
= tdfxCompressedTexImage2D
;
1865 functions
->CompressedTexSubImage2D
= tdfxCompressedTexSubImage2D
;
1866 functions
->UpdateTexturePalette
= tdfxUpdateTexturePalette
;
1867 functions
->GenerateMipmap
= tdfxGenerateMipmap
;