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/texformat.h"
46 #include "main/teximage.h"
47 #include "main/texstore.h"
48 #include "main/texobj.h"
49 #include "tdfx_context.h"
51 #include "tdfx_texman.h"
54 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
56 _mesa_halve2x2_teximage2d ( GLcontext
*ctx
,
57 struct gl_texture_image
*texImage
,
59 GLint srcWidth
, GLint srcHeight
,
60 const GLvoid
*srcImage
, GLvoid
*dstImage
)
63 GLint dstWidth
= srcWidth
/ 2;
64 GLint dstHeight
= srcHeight
/ 2;
65 GLint srcRowStride
= srcWidth
* bytesPerPixel
;
66 GLubyte
*src
= (GLubyte
*)srcImage
;
67 GLubyte
*dst
= dstImage
;
68 GLuint dstImageOffsets
= 0;
75 if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_RGB565
) {
76 _t
= GL_UNSIGNED_SHORT_5_6_5_REV
;
78 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
79 _t
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
81 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
82 _t
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
87 srcRowStride
= srcWidth
* bytesPerPixel
;
94 _s
= src
= MALLOC(srcRowStride
* srcHeight
);
95 _d
= dst
= MALLOC(dstWidth
* bytesPerPixel
* dstHeight
);
96 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
97 &_mesa_texformat_rgba8888_rev
, src
,
98 0, 0, 0, /* dstX/Y/Zoffset */
99 srcRowStride
, /* dstRowStride */
101 srcWidth
, srcHeight
, 1,
102 texImage
->_BaseFormat
, _t
, srcImage
, &ctx
->DefaultPacking
);
105 if (srcHeight
== 1) {
106 for (i
= 0; i
< dstWidth
; i
++) {
107 for (k
= 0; k
< bytesPerPixel
; k
++) {
108 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
112 src
+= bytesPerPixel
;
114 } else if (srcWidth
== 1) {
115 for (j
= 0; j
< dstHeight
; j
++) {
116 for (k
= 0; k
< bytesPerPixel
; k
++) {
117 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
124 for (j
= 0; j
< dstHeight
; j
++) {
125 for (i
= 0; i
< dstWidth
; i
++) {
126 for (k
= 0; k
< bytesPerPixel
; k
++) {
130 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
134 src
+= bytesPerPixel
;
141 StoreTexImageFunc storeImage
=
142 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
146 storeImage(ctx
, 2, texImage
->_BaseFormat
,
147 texImage
->TexFormat
, dstImage
,
148 0, 0, 0, /* dstX/Y/Zoffset */
151 dstWidth
, dstHeight
, 1,
152 GL_BGRA
, CHAN_TYPE
, dst
, &ctx
->DefaultPacking
);
183 tdfxGenerateMipmap(GLcontext
*ctx
, GLenum target
,
184 struct gl_texture_object
*texObj
)
186 GLint mipWidth
, mipHeight
;
187 tdfxMipMapLevel
*mip
;
188 struct gl_texture_image
*mipImage
; /* the new/next image */
189 struct gl_texture_image
*texImage
;
190 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
191 GLint level
= texObj
->BaseLevel
;
192 GLsizei width
, height
, texelBytes
;
193 const tdfxMipMapLevel
*mml
;
195 texImage
= _mesa_get_tex_image(ctx
, texObj
, target
, level
);
196 assert(!texImage
->IsCompressed
);
198 mml
= TDFX_TEXIMAGE_DATA(texImage
);
200 width
= texImage
->Width
;
201 height
= texImage
->Height
;
202 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
203 mipWidth
= width
/ 2;
207 mipHeight
= height
/ 2;
211 if ((mipWidth
== width
) && (mipHeight
== height
)) {
215 mipImage
= _mesa_select_tex_image(ctx
, texObj
, target
, level
);
216 mip
= TDFX_TEXIMAGE_DATA(mipImage
);
217 _mesa_halve2x2_teximage2d(ctx
,
220 mml
->width
, mml
->height
,
221 texImage
->Data
, mipImage
->Data
);
231 * Compute various texture image parameters.
232 * Input: w, h - source texture width and height
233 * Output: lodlevel - Glide lod level token for the larger texture dimension
234 * aspectratio - Glide aspect ratio token
235 * sscale - S scale factor used during triangle setup
236 * tscale - T scale factor used during triangle setup
237 * wscale - OpenGL -> Glide image width scale factor
238 * hscale - OpenGL -> Glide image height scale factor
241 * w h lodlevel aspectRatio
242 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
243 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
244 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
245 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
246 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
249 tdfxTexGetInfo(const GLcontext
*ctx
, int w
, int h
,
250 GrLOD_t
*lodlevel
, GrAspectRatio_t
*aspectratio
,
251 float *sscale
, float *tscale
,
252 int *wscale
, int *hscale
)
254 int logw
, logh
, ar
, lod
, ws
, hs
;
262 ar
= logw
- logh
; /* aspect ratio = difference in log dimensions */
266 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
267 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
271 if (ar
<= GR_ASPECT_LOG2_8x1
) {
275 /* have to stretch image height */
278 ar
= GR_ASPECT_LOG2_8x1
;
284 if (ar
>= GR_ASPECT_LOG2_1x8
) {
288 /* have to stretch image width */
291 ar
= GR_ASPECT_LOG2_1x8
;
296 *lodlevel
= (GrLOD_t
) lod
;
298 *aspectratio
= (GrAspectRatio_t
) ar
;
311 * We need to call this when a texture object's minification filter
312 * or texture image sizes change.
314 static void RevalidateTexture(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
316 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
322 minl
= maxl
= tObj
->BaseLevel
;
324 if (tObj
->Image
[0][minl
]) {
325 maxl
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0][minl
]->MaxLog2
);
327 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
328 tdfxTexGetInfo(ctx
, tObj
->Image
[0][minl
]->Width
, tObj
->Image
[0][minl
]->Height
,
329 &ti
->info
.largeLodLog2
,
330 &ti
->info
.aspectRatioLog2
,
331 &(ti
->sScale
), &(ti
->tScale
), NULL
, NULL
);
334 if (tObj
->Image
[0][maxl
] && (tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
335 /* mipmapping: need to compute smallLodLog2 */
336 tdfxTexGetInfo(ctx
, tObj
->Image
[0][maxl
]->Width
,
337 tObj
->Image
[0][maxl
]->Height
,
338 &ti
->info
.smallLodLog2
, NULL
,
339 NULL
, NULL
, NULL
, NULL
);
342 /* not mipmapping: smallLodLog2 = largeLodLog2 */
343 ti
->info
.smallLodLog2
= ti
->info
.largeLodLog2
;
349 ti
->info
.data
= NULL
;
351 /* this is necessary because of fxDDCompressedTexImage2D */
353 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
354 tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
355 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
356 ti
->sScale
/= mml
->wScale
;
357 ti
->tScale
/= mml
->hScale
;
364 fxAllocTexObjData(tdfxContextPtr fxMesa
)
368 if (!(ti
= CALLOC(sizeof(tdfxTexInfo
)))) {
369 _mesa_problem(NULL
, "tdfx driver: out of memory");
373 ti
->isInTM
= GL_FALSE
;
375 ti
->whichTMU
= TDFX_TMU_NONE
;
377 ti
->tm
[TDFX_TMU0
] = NULL
;
378 ti
->tm
[TDFX_TMU1
] = NULL
;
380 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
381 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
383 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
384 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
386 ti
->mmMode
= GR_MIPMAP_NEAREST
;
387 ti
->LODblend
= FXFALSE
;
394 * Called via glBindTexture.
397 tdfxBindTexture(GLcontext
* ctx
, GLenum target
,
398 struct gl_texture_object
*tObj
)
400 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
403 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
404 fprintf(stderr
, "fxmesa: fxDDTexBind(%d,%p)\n", tObj
->Name
,
408 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
411 if (!tObj
->DriverData
) {
412 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
415 ti
= TDFX_TEXTURE_DATA(tObj
);
416 ti
->lastTimeUsed
= fxMesa
->texBindNumber
++;
418 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
423 * Called via glTexEnv.
426 tdfxTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
427 const GLfloat
* param
)
429 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
431 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
433 fprintf(stderr
, "fxmesa: texenv(%x,%x)\n", pname
,
436 fprintf(stderr
, "fxmesa: texenv(%x)\n", pname
);
439 /* XXX this is a bit of a hack to force the Glide texture
440 * state to be updated.
442 fxMesa
->TexState
.EnvMode
[ctx
->Texture
.CurrentUnit
] = 0;
444 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
449 * Called via glTexParameter.
452 tdfxTexParameter(GLcontext
* ctx
, GLenum target
,
453 struct gl_texture_object
*tObj
,
454 GLenum pname
, const GLfloat
* params
)
456 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
457 GLenum param
= (GLenum
) (GLint
) params
[0];
460 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
461 fprintf(stderr
, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj
->Name
,
462 tObj
->DriverData
, pname
, param
);
465 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
468 if (!tObj
->DriverData
)
469 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
471 ti
= TDFX_TEXTURE_DATA(tObj
);
474 case GL_TEXTURE_MIN_FILTER
:
477 ti
->mmMode
= GR_MIPMAP_DISABLE
;
478 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
479 ti
->LODblend
= FXFALSE
;
482 ti
->mmMode
= GR_MIPMAP_DISABLE
;
483 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
484 ti
->LODblend
= FXFALSE
;
486 case GL_NEAREST_MIPMAP_LINEAR
:
487 if (!fxMesa
->Glide
.HaveCombineExt
) {
488 if (fxMesa
->haveTwoTMUs
) {
489 ti
->mmMode
= GR_MIPMAP_NEAREST
;
490 ti
->LODblend
= FXTRUE
;
493 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
494 ti
->LODblend
= FXFALSE
;
496 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
499 /* XXX Voodoo3/Banshee mipmap blending seems to produce
500 * incorrectly filtered colors for the smallest mipmap levels.
501 * To work-around we fall-through here and use a different filter.
503 case GL_NEAREST_MIPMAP_NEAREST
:
504 ti
->mmMode
= GR_MIPMAP_NEAREST
;
505 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
506 ti
->LODblend
= FXFALSE
;
508 case GL_LINEAR_MIPMAP_LINEAR
:
509 if (!fxMesa
->Glide
.HaveCombineExt
) {
510 if (fxMesa
->haveTwoTMUs
) {
511 ti
->mmMode
= GR_MIPMAP_NEAREST
;
512 ti
->LODblend
= FXTRUE
;
515 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
516 ti
->LODblend
= FXFALSE
;
518 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
521 /* XXX Voodoo3/Banshee mipmap blending seems to produce
522 * incorrectly filtered colors for the smallest mipmap levels.
523 * To work-around we fall-through here and use a different filter.
525 case GL_LINEAR_MIPMAP_NEAREST
:
526 ti
->mmMode
= GR_MIPMAP_NEAREST
;
527 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
528 ti
->LODblend
= FXFALSE
;
533 ti
->reloadImages
= GL_TRUE
;
534 RevalidateTexture(ctx
, tObj
);
535 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
538 case GL_TEXTURE_MAG_FILTER
:
541 ti
->magFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
544 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
549 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
552 case GL_TEXTURE_WRAP_S
:
554 case GL_CLAMP_TO_BORDER
:
555 case GL_CLAMP_TO_EDGE
:
557 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
560 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
562 case GL_MIRRORED_REPEAT
:
563 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
568 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
571 case GL_TEXTURE_WRAP_T
:
573 case GL_CLAMP_TO_BORDER
:
574 case GL_CLAMP_TO_EDGE
:
576 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
579 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
581 case GL_MIRRORED_REPEAT
:
582 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
587 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
590 case GL_TEXTURE_BORDER_COLOR
:
593 case GL_TEXTURE_MIN_LOD
:
596 case GL_TEXTURE_MAX_LOD
:
599 case GL_TEXTURE_BASE_LEVEL
:
600 RevalidateTexture(ctx
, tObj
);
602 case GL_TEXTURE_MAX_LEVEL
:
603 RevalidateTexture(ctx
, tObj
);
613 * Called via glDeleteTextures to delete a texture object.
614 * Here, we delete the Glide data associated with the texture.
617 tdfxDeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
619 if (ctx
&& ctx
->DriverCtx
) {
620 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
621 tdfxTMFreeTexture(fxMesa
, tObj
);
622 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
623 /* Free mipmap images and the texture object itself */
624 _mesa_delete_texture_object(ctx
, tObj
);
630 * Return true if texture is resident, false otherwise.
633 tdfxIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
635 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
636 return (GLboolean
) (ti
&& ti
->isInTM
);
642 * Convert a gl_color_table texture palette to Glide's format.
645 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
647 const GLubyte
*tableUB
= table
->TableUB
;
648 GLint width
= table
->Size
;
652 switch (table
->_BaseFormat
) {
654 for (i
= 0; i
< width
; i
++) {
659 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
661 return GR_TEXTABLE_PALETTE_6666_EXT
;
663 for (i
= 0; i
< width
; i
++) {
668 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
670 return GR_TEXTABLE_PALETTE
;
672 for (i
= 0; i
< width
; i
++) {
675 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
677 return GR_TEXTABLE_PALETTE_6666_EXT
;
678 case GL_LUMINANCE_ALPHA
:
679 for (i
= 0; i
< width
; i
++) {
680 r
= g
= b
= tableUB
[i
* 2 + 0];
681 a
= tableUB
[i
* 2 + 1];
682 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
684 return GR_TEXTABLE_PALETTE_6666_EXT
;
686 for (i
= 0; i
< width
; i
++) {
687 r
= tableUB
[i
* 3 + 0];
688 g
= tableUB
[i
* 3 + 1];
689 b
= tableUB
[i
* 3 + 2];
691 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
693 return GR_TEXTABLE_PALETTE
;
695 for (i
= 0; i
< width
; i
++) {
696 r
= tableUB
[i
* 4 + 0];
697 g
= tableUB
[i
* 4 + 1];
698 b
= tableUB
[i
* 4 + 2];
699 a
= tableUB
[i
* 4 + 3];
700 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
702 return GR_TEXTABLE_PALETTE_6666_EXT
;
704 /* XXX fixme: how can this happen? */
705 _mesa_error(NULL
, GL_INVALID_ENUM
, "convertPalette: table->Format == %s",
706 _mesa_lookup_enum_by_nr(table
->Format
));
707 return GR_TEXTABLE_PALETTE
;
714 tdfxUpdateTexturePalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
716 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
719 /* per-texture palette */
722 /* This might be a proxy texture. */
723 if (!tObj
->Palette
.TableUB
)
726 if (!tObj
->DriverData
)
727 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
728 ti
= TDFX_TEXTURE_DATA(tObj
);
730 ti
->paltype
= convertPalette(ti
->palette
.data
, &tObj
->Palette
);
731 /*tdfxTexInvalidate(ctx, tObj);*/
734 /* global texture palette */
735 fxMesa
->TexPalette
.Type
= convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
736 fxMesa
->TexPalette
.Data
= &(fxMesa
->glbPalette
.data
);
737 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
739 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX too heavy-handed */
743 /**********************************************************************/
744 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
745 /**********************************************************************/
748 static FxBool TexusFatalError
= FXFALSE
;
749 static FxBool TexusError
= FXFALSE
;
751 #define TX_DITHER_NONE 0x00000000
754 fxTexusError(const char *string
, FxBool fatal
)
756 _mesa_problem(NULL
, string
);
758 * Just propagate the fatal value up.
761 TexusFatalError
= fatal
;
766 static const struct gl_texture_format
*
767 tdfxChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
768 GLenum srcFormat
, GLenum srcType
)
770 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
771 const GLboolean allow32bpt
= TDFX_IS_NAPALM(fxMesa
);
773 switch (internalFormat
) {
779 case GL_COMPRESSED_ALPHA
:
780 return &_mesa_texformat_a8
;
787 case GL_COMPRESSED_LUMINANCE
:
788 return &_mesa_texformat_l8
;
790 case GL_LUMINANCE_ALPHA
:
791 case GL_LUMINANCE4_ALPHA4
:
792 case GL_LUMINANCE6_ALPHA2
:
793 case GL_LUMINANCE8_ALPHA8
:
794 case GL_LUMINANCE12_ALPHA4
:
795 case GL_LUMINANCE12_ALPHA12
:
796 case GL_LUMINANCE16_ALPHA16
:
797 case GL_COMPRESSED_LUMINANCE_ALPHA
:
798 return &_mesa_texformat_al88
;
804 case GL_COMPRESSED_INTENSITY
:
805 return &_mesa_texformat_i8
;
809 return &_mesa_texformat_rgb565
;
810 case GL_COMPRESSED_RGB
:
811 /* intentional fall-through */
814 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
815 return &_mesa_texformat_rgb565
;
817 /* intentional fall through */
822 return (allow32bpt
) ? &_mesa_texformat_argb8888
823 : &_mesa_texformat_rgb565
;
826 return &_mesa_texformat_argb4444
;
827 case GL_COMPRESSED_RGBA
:
828 /* intentional fall-through */
831 if ( srcFormat
== GL_BGRA
) {
832 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
833 return &_mesa_texformat_argb8888
;
835 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
836 return &_mesa_texformat_argb4444
;
838 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
839 return &_mesa_texformat_argb1555
;
842 /* intentional fall through */
847 return allow32bpt
? &_mesa_texformat_argb8888
848 : &_mesa_texformat_argb4444
;
850 return &_mesa_texformat_argb1555
;
852 case GL_COLOR_INDEX1_EXT
:
853 case GL_COLOR_INDEX2_EXT
:
854 case GL_COLOR_INDEX4_EXT
:
855 case GL_COLOR_INDEX8_EXT
:
856 case GL_COLOR_INDEX12_EXT
:
857 case GL_COLOR_INDEX16_EXT
:
858 return &_mesa_texformat_ci8
;
859 /* GL_EXT_texture_compression_s3tc */
861 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
864 return &_mesa_texformat_rgb_dxt1
;
865 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
866 return &_mesa_texformat_rgba_dxt1
;
867 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
870 return &_mesa_texformat_rgba_dxt3
;
871 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
872 return &_mesa_texformat_rgba_dxt5
;
873 /* GL_3DFX_texture_compression_FXT1 */
874 case GL_COMPRESSED_RGB_FXT1_3DFX
:
875 return &_mesa_texformat_rgb_fxt1
;
876 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
877 return &_mesa_texformat_rgba_fxt1
;
879 _mesa_problem(ctx
, "unexpected format in tdfxChooseTextureFormat");
886 * Return the Glide format for the given mesa texture format.
888 static GrTextureFormat_t
889 fxGlideFormat(GLint mesaFormat
)
891 switch (mesaFormat
) {
893 return GR_TEXFMT_ALPHA_8
;
895 return GR_TEXFMT_ALPHA_8
;
897 return GR_TEXFMT_INTENSITY_8
;
898 case MESA_FORMAT_CI8
:
899 return GR_TEXFMT_P_8
;
900 case MESA_FORMAT_AL88
:
901 return GR_TEXFMT_ALPHA_INTENSITY_88
;
902 case MESA_FORMAT_RGB565
:
903 return GR_TEXFMT_RGB_565
;
904 case MESA_FORMAT_ARGB4444
:
905 return GR_TEXFMT_ARGB_4444
;
906 case MESA_FORMAT_ARGB1555
:
907 return GR_TEXFMT_ARGB_1555
;
908 case MESA_FORMAT_ARGB8888
:
909 return GR_TEXFMT_ARGB_8888
;
910 case MESA_FORMAT_RGB_FXT1
:
911 case MESA_FORMAT_RGBA_FXT1
:
912 return GR_TEXFMT_ARGB_CMP_FXT1
;
913 case MESA_FORMAT_RGB_DXT1
:
914 case MESA_FORMAT_RGBA_DXT1
:
915 return GR_TEXFMT_ARGB_CMP_DXT1
;
916 case MESA_FORMAT_RGBA_DXT3
:
917 return GR_TEXFMT_ARGB_CMP_DXT3
;
918 case MESA_FORMAT_RGBA_DXT5
:
919 return GR_TEXFMT_ARGB_CMP_DXT5
;
921 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
927 /* Texel-fetch functions for software texturing and glGetTexImage().
928 * We should have been able to use some "standard" fetch functions (which
929 * may get defined in texutil.c) but we have to account for scaled texture
930 * images on tdfx hardware (the 8:1 aspect ratio limit).
931 * Hence, we need special functions here.
934 fxt1_decode_1 (const void *texture
, int width
,
935 int i
, int j
, unsigned char *rgba
);
938 fetch_intensity8(const struct gl_texture_image
*texImage
,
939 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
941 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
942 const GLubyte
*texel
;
947 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
948 rgba
[RCOMP
] = *texel
;
949 rgba
[GCOMP
] = *texel
;
950 rgba
[BCOMP
] = *texel
;
951 rgba
[ACOMP
] = *texel
;
956 fetch_luminance8(const struct gl_texture_image
*texImage
,
957 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
959 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
960 const GLubyte
*texel
;
965 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
966 rgba
[RCOMP
] = *texel
;
967 rgba
[GCOMP
] = *texel
;
968 rgba
[BCOMP
] = *texel
;
974 fetch_alpha8(const struct gl_texture_image
*texImage
,
975 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
977 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
978 const GLubyte
*texel
;
983 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
987 rgba
[ACOMP
] = *texel
;
992 fetch_index8(const struct gl_texture_image
*texImage
,
993 GLint i
, GLint j
, GLint k
, GLchan
* indexOut
)
995 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
996 const GLubyte
*texel
;
1001 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
1007 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
1008 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1010 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1011 const GLubyte
*texel
;
1013 i
= i
* mml
->wScale
;
1014 j
= j
* mml
->hScale
;
1016 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
1017 rgba
[RCOMP
] = texel
[0];
1018 rgba
[GCOMP
] = texel
[0];
1019 rgba
[BCOMP
] = texel
[0];
1020 rgba
[ACOMP
] = texel
[1];
1025 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
1026 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1028 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1029 const GLushort
*texel
;
1031 i
= i
* mml
->wScale
;
1032 j
= j
* mml
->hScale
;
1034 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1035 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
1036 rgba
[GCOMP
] = (((*texel
) >> 5) & 0x3f) * 255 / 63;
1037 rgba
[BCOMP
] = (((*texel
) >> 0) & 0x1f) * 255 / 31;
1043 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
1044 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1046 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1047 const GLushort
*texel
;
1049 i
= i
* mml
->wScale
;
1050 j
= j
* mml
->hScale
;
1052 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1053 rgba
[RCOMP
] = (((*texel
) >> 12) & 0xf) * 255 / 15;
1054 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xf) * 255 / 15;
1055 rgba
[BCOMP
] = (((*texel
) >> 4) & 0xf) * 255 / 15;
1056 rgba
[ACOMP
] = (((*texel
) >> 0) & 0xf) * 255 / 15;
1061 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
1062 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1064 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1065 const GLushort
*texel
;
1067 i
= i
* mml
->wScale
;
1068 j
= j
* mml
->hScale
;
1070 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1071 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
1072 rgba
[GCOMP
] = (((*texel
) >> 6) & 0x1f) * 255 / 31;
1073 rgba
[BCOMP
] = (((*texel
) >> 1) & 0x1f) * 255 / 31;
1074 rgba
[ACOMP
] = (((*texel
) >> 0) & 0x01) * 255;
1079 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
1080 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
1082 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1083 const GLuint
*texel
;
1085 i
= i
* mml
->wScale
;
1086 j
= j
* mml
->hScale
;
1088 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
1089 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
1090 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
1091 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
1092 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
1097 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
1098 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1100 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1102 i
= i
* mml
->wScale
;
1103 j
= j
* mml
->hScale
;
1105 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1111 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
1112 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1114 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1116 i
= i
* mml
->wScale
;
1117 j
= j
* mml
->hScale
;
1119 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1124 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
1125 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1127 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1129 i
= i
* mml
->wScale
;
1130 j
= j
* mml
->hScale
;
1132 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1137 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
1138 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1140 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1142 i
= i
* mml
->wScale
;
1143 j
= j
* mml
->hScale
;
1145 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1150 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
1151 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1153 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1155 i
= i
* mml
->wScale
;
1156 j
= j
* mml
->hScale
;
1158 _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 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1175 static FetchTexelFuncC
1176 fxFetchFunction(GLint mesaFormat
)
1178 switch (mesaFormat
) {
1179 case MESA_FORMAT_I8
:
1180 return &fetch_intensity8
;
1181 case MESA_FORMAT_A8
:
1182 return &fetch_alpha8
;
1183 case MESA_FORMAT_L8
:
1184 return &fetch_luminance8
;
1185 case MESA_FORMAT_CI8
:
1186 return &fetch_index8
;
1187 case MESA_FORMAT_AL88
:
1188 return &fetch_luminance8_alpha8
;
1189 case MESA_FORMAT_RGB565
:
1190 return &fetch_r5g6b5
;
1191 case MESA_FORMAT_ARGB4444
:
1192 return &fetch_r4g4b4a4
;
1193 case MESA_FORMAT_ARGB1555
:
1194 return &fetch_r5g5b5a1
;
1195 case MESA_FORMAT_ARGB8888
:
1196 return &fetch_a8r8g8b8
;
1197 case MESA_FORMAT_RGB_FXT1
:
1198 return &fetch_rgb_fxt1
;
1199 case MESA_FORMAT_RGBA_FXT1
:
1200 return &fetch_rgba_fxt1
;
1201 case MESA_FORMAT_RGB_DXT1
:
1202 return &fetch_rgb_dxt1
;
1203 case MESA_FORMAT_RGBA_DXT1
:
1204 return &fetch_rgba_dxt1
;
1205 case MESA_FORMAT_RGBA_DXT3
:
1206 return &fetch_rgba_dxt3
;
1207 case MESA_FORMAT_RGBA_DXT5
:
1208 return &fetch_rgba_dxt5
;
1210 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1217 adjust2DRatio (GLcontext
*ctx
,
1218 GLint xoffset
, GLint yoffset
,
1219 GLint width
, GLint height
,
1220 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1221 const struct gl_pixelstore_attrib
*packing
,
1222 tdfxMipMapLevel
*mml
,
1223 struct gl_texture_image
*texImage
,
1227 const GLint newWidth
= width
* mml
->wScale
;
1228 const GLint newHeight
= height
* mml
->hScale
;
1230 GLuint dstImageOffsets
= 0;
1232 if (!texImage
->IsCompressed
) {
1234 StoreTexImageFunc storeImage
=
1235 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1237 tempImage
= MALLOC(width
* height
* texelBytes
);
1242 storeImage(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
);
1265 StoreTexImageFunc storeImage
=
1266 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1271 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1276 /* unpack image, apply transfer ops and store in rawImage */
1277 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
1278 &_mesa_texformat_rgba8888_rev
, rawImage
,
1279 0, 0, 0, /* dstX/Y/Zoffset */
1280 width
* rawBytes
, /* dstRowStride */
1283 format
, type
, pixels
, packing
);
1284 _mesa_rescale_teximage2d(rawBytes
,
1286 newWidth
* rawBytes
, /* dst stride */
1287 width
, height
, /* src */
1288 newWidth
, newHeight
, /* dst */
1289 rawImage
/*src*/, tempImage
/*dst*/ );
1290 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1291 texImage
->TexFormat
, texImage
->Data
,
1292 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1295 newWidth
, newHeight
, 1,
1296 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1307 tdfxTexImage2D(GLcontext
*ctx
, GLenum target
, GLint level
,
1308 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1309 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1310 const struct gl_pixelstore_attrib
*packing
,
1311 struct gl_texture_object
*texObj
,
1312 struct gl_texture_image
*texImage
)
1314 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1316 tdfxMipMapLevel
*mml
;
1317 GLint texelBytes
, dstRowStride
;
1321 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1322 texObj->Name, texImage->InternalFormat, format, type,
1323 texImage->Width, texImage->Height);
1326 ti
= TDFX_TEXTURE_DATA(texObj
);
1328 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1329 if (!texObj
->DriverData
) {
1330 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1333 ti
= TDFX_TEXTURE_DATA(texObj
);
1337 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1339 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1340 if (!texImage
->DriverData
) {
1341 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1344 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1347 /* Determine width and height scale factors for texture.
1348 * Remember, Glide is limited to 8:1 aspect ratios.
1351 texImage
->Width
, texImage
->Height
,
1352 NULL
, /* lod level */
1353 NULL
, /* aspect ratio */
1354 NULL
, NULL
, /* sscale, tscale */
1355 &mml
->wScale
, &mml
->hScale
);
1357 /* rescaled size: */
1358 mml
->width
= width
* mml
->wScale
;
1359 mml
->height
= height
* mml
->hScale
;
1361 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1362 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1363 /* [dBorca] we should update texture's attribute, then,
1364 * because if the application asks us to decompress, we
1365 * have to know the REAL format! Also, DXT3/5 might not
1366 * be correct, since it would mess with "compressedSize".
1367 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1369 if (texImage
->IsCompressed
) {
1370 switch (internalFormat
) {
1371 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1374 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1376 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1377 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1378 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1381 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1383 texImage
->InternalFormat
= internalFormat
;
1387 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1388 GLenum texNapalm
= 0;
1389 if (internalFormat
== GL_COMPRESSED_RGB
) {
1390 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1391 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1392 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1395 texImage
->InternalFormat
= internalFormat
= texNapalm
;
1396 texImage
->IsCompressed
= GL_TRUE
;
1401 /* choose the texture format */
1402 assert(ctx
->Driver
.ChooseTextureFormat
);
1403 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1404 internalFormat
, format
, type
);
1405 assert(texImage
->TexFormat
);
1406 mesaFormat
= texImage
->TexFormat
->MesaFormat
;
1407 mml
->glideFormat
= fxGlideFormat(mesaFormat
);
1408 ti
->info
.format
= mml
->glideFormat
;
1409 texImage
->FetchTexelc
= fxFetchFunction(mesaFormat
);
1410 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1412 if (texImage
->IsCompressed
) {
1413 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1418 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, mml
->width
);
1419 texImage
->Data
= _mesa_alloc_texmemory(texImage
->CompressedSize
);
1421 dstRowStride
= mml
->width
* texelBytes
;
1422 texImage
->Data
= _mesa_alloc_texmemory(mml
->width
* mml
->height
* texelBytes
);
1424 if (!texImage
->Data
) {
1425 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1429 if (pixels
!= NULL
) {
1430 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1431 /* rescale image to overcome 1:8 aspect limitation */
1432 if (!adjust2DRatio(ctx
,
1435 format
, type
, pixels
,
1442 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1447 /* no rescaling needed */
1448 /* unpack image, apply transfer ops and store in texImage->Data */
1449 StoreTexImageFunc storeImage
=
1450 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1452 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1453 texImage
->TexFormat
, texImage
->Data
,
1454 0, 0, 0, /* dstX/Y/Zoffset */
1456 texImage
->ImageOffsets
,
1458 format
, type
, pixels
, packing
);
1462 RevalidateTexture(ctx
, texObj
);
1464 ti
->reloadImages
= GL_TRUE
;
1465 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1470 tdfxTexSubImage2D(GLcontext
*ctx
, GLenum target
, GLint level
,
1471 GLint xoffset
, GLint yoffset
,
1472 GLsizei width
, GLsizei height
,
1473 GLenum format
, GLenum type
,
1474 const GLvoid
*pixels
,
1475 const struct gl_pixelstore_attrib
*packing
,
1476 struct gl_texture_object
*texObj
,
1477 struct gl_texture_image
*texImage
)
1479 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1481 tdfxMipMapLevel
*mml
;
1482 GLint texelBytes
, dstRowStride
;
1484 if (!texObj
->DriverData
) {
1485 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1489 ti
= TDFX_TEXTURE_DATA(texObj
);
1491 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1494 assert(texImage
->Data
); /* must have an existing texture image! */
1495 assert(texImage
->_BaseFormat
);
1497 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1498 if (texImage
->IsCompressed
) {
1499 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, mml
->width
);
1501 dstRowStride
= mml
->width
* texelBytes
;
1504 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1505 /* need to rescale subimage to match mipmap level's rescale factors */
1506 if (!adjust2DRatio(ctx
,
1509 format
, type
, pixels
,
1516 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1521 /* no rescaling needed */
1522 StoreTexImageFunc storeImage
=
1523 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1525 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1526 texImage
->TexFormat
, texImage
->Data
,
1527 xoffset
, yoffset
, 0,
1529 texImage
->ImageOffsets
,
1531 format
, type
, pixels
, packing
);
1534 ti
->reloadImages
= GL_TRUE
; /* signal the image needs to be reloaded */
1535 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX this might be a bit much */
1540 tdfxTexImage1D(GLcontext
*ctx
, GLenum target
, GLint level
,
1541 GLint internalFormat
, GLint width
, GLint border
,
1542 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1543 const struct gl_pixelstore_attrib
*packing
,
1544 struct gl_texture_object
*texObj
,
1545 struct gl_texture_image
*texImage
)
1547 tdfxTexImage2D(ctx
, target
, level
,
1548 internalFormat
, width
, 1, border
,
1549 format
, type
, pixels
,
1556 tdfxTexSubImage1D(GLcontext
*ctx
, GLenum target
, GLint level
,
1559 GLenum format
, GLenum type
,
1560 const GLvoid
*pixels
,
1561 const struct gl_pixelstore_attrib
*packing
,
1562 struct gl_texture_object
*texObj
,
1563 struct gl_texture_image
*texImage
)
1565 tdfxTexSubImage2D(ctx
, target
, level
,
1575 /**********************************************************************/
1576 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1577 /**********************************************************************/
1580 tdfxCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1581 GLint level
, GLint internalFormat
,
1582 GLsizei width
, GLsizei height
, GLint border
,
1583 GLsizei imageSize
, const GLvoid
*data
,
1584 struct gl_texture_object
*texObj
,
1585 struct gl_texture_image
*texImage
)
1587 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1589 tdfxMipMapLevel
*mml
;
1592 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1593 fprintf(stderr
, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1594 texObj
->Name
, internalFormat
,
1598 if ((target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
) || texImage
->Border
> 0) {
1599 _mesa_problem(NULL
, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
1603 assert(texImage
->IsCompressed
);
1605 ti
= TDFX_TEXTURE_DATA(texObj
);
1607 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1608 if (!texObj
->DriverData
) {
1609 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1612 ti
= TDFX_TEXTURE_DATA(texObj
);
1616 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1618 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1619 if (!texImage
->DriverData
) {
1620 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1623 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1626 tdfxTexGetInfo(ctx
, width
, height
, NULL
, NULL
, NULL
, NULL
,
1627 &mml
->wScale
, &mml
->hScale
);
1629 mml
->width
= width
* mml
->wScale
;
1630 mml
->height
= height
* mml
->hScale
;
1633 /* choose the texture format */
1634 assert(ctx
->Driver
.ChooseTextureFormat
);
1635 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1636 internalFormat
, -1/*format*/, -1/*type*/);
1637 assert(texImage
->TexFormat
);
1639 /* Determine the appropriate Glide texel format,
1640 * given the user's internal texture format hint.
1642 mesaFormat
= texImage
->TexFormat
->MesaFormat
;
1643 mml
->glideFormat
= fxGlideFormat(mesaFormat
);
1644 ti
->info
.format
= mml
->glideFormat
;
1645 texImage
->FetchTexelc
= fxFetchFunction(mesaFormat
);
1647 /* allocate new storage for texture image, if needed */
1648 if (!texImage
->Data
) {
1649 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1654 texImage
->Data
= _mesa_alloc_texmemory(texImage
->CompressedSize
);
1655 if (!texImage
->Data
) {
1656 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1661 /* save the texture data */
1662 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1663 /* [dBorca] Hack alert:
1664 * now we're screwed. We can't decompress,
1665 * unless we do it in HW (via textureBuffer).
1666 * We still have some chances:
1667 * 1) we got FXT1 textures - we CAN decompress, rescale for
1668 * aspectratio, then compress back.
1669 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1670 * Thus, we don't care about textureclamp and we could lower
1671 * MIN("uscale", "vscale") below 32. We still have to have
1672 * our data aligned inside a 8:1 rectangle.
1673 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1674 * we replicate the data over the padded area.
1675 * For now, we take 2) + 3) but texelfetchers will be wrong!
1677 const GLuint mesaFormat
= texImage
->TexFormat
->MesaFormat
;
1678 GLuint srcRowStride
= _mesa_compressed_row_stride(mesaFormat
, width
);
1680 GLuint destRowStride
= _mesa_compressed_row_stride(mesaFormat
,
1683 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1684 destRowStride
, (mml
->height
+3) / 4,
1685 1, data
, srcRowStride
,
1687 ti
->padded
= GL_TRUE
;
1689 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1692 RevalidateTexture(ctx
, texObj
);
1694 ti
->reloadImages
= GL_TRUE
;
1695 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1700 tdfxCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1701 GLint level
, GLint xoffset
,
1702 GLint yoffset
, GLsizei width
,
1703 GLint height
, GLenum format
,
1704 GLsizei imageSize
, const GLvoid
*data
,
1705 struct gl_texture_object
*texObj
,
1706 struct gl_texture_image
*texImage
)
1708 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1710 tdfxMipMapLevel
*mml
;
1711 GLint destRowStride
, srcRowStride
;
1714 const GLuint mesaFormat
= texImage
->TexFormat
->MesaFormat
;
1716 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1717 fprintf(stderr
, "tdfxCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1720 ti
= TDFX_TEXTURE_DATA(texObj
);
1722 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1725 srcRowStride
= _mesa_compressed_row_stride(mesaFormat
, width
);
1727 destRowStride
= _mesa_compressed_row_stride(mesaFormat
, mml
->width
);
1728 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1731 (GLubyte
*) texImage
->Data
);
1733 rows
= height
/ 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1735 for (i
= 0; i
< rows
; i
++) {
1736 MEMCPY(dest
, data
, srcRowStride
);
1737 dest
+= destRowStride
;
1738 data
= (GLvoid
*)((intptr_t)data
+ (intptr_t)srcRowStride
);
1741 /* [dBorca] Hack alert:
1742 * see fxDDCompressedTexImage2D for caveats
1744 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1745 srcRowStride
= _mesa_compressed_row_stride(mesaFormat
, texImage
->Width
);
1747 destRowStride
= _mesa_compressed_row_stride(mesaFormat
, mml
->width
);
1748 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1749 destRowStride
, mml
->height
/ 4,
1750 1, texImage
->Data
, destRowStride
,
1754 RevalidateTexture(ctx
, texObj
);
1756 ti
->reloadImages
= GL_TRUE
;
1757 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1763 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1766 for (i
= 0; i
< h
; i
++) {
1767 for (j
= 0; j
< w
; j
++) {
1769 printf("%02x %02x ", data
[0], data
[1]);
1771 printf("%02x %02x %02x ", data
[0], data
[1], data
[2]);
1781 tdfxTestProxyTexImage(GLcontext
*ctx
, GLenum target
,
1782 GLint level
, GLint internalFormat
,
1783 GLenum format
, GLenum type
,
1784 GLint width
, GLint height
,
1785 GLint depth
, GLint border
)
1787 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1788 struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1789 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1792 case GL_PROXY_TEXTURE_1D
:
1794 case GL_PROXY_TEXTURE_2D
:
1796 struct gl_texture_object
*tObj
;
1800 tObj
= ctx
->Texture
.ProxyTex
[TEXTURE_2D_INDEX
];
1801 if (!tObj
->DriverData
)
1802 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1803 ti
= TDFX_TEXTURE_DATA(tObj
);
1806 /* assign the parameters to test against */
1807 tObj
->Image
[0][level
]->Width
= width
;
1808 tObj
->Image
[0][level
]->Height
= height
;
1809 tObj
->Image
[0][level
]->Border
= border
;
1811 tObj
->Image
[0][level
]->InternalFormat
= internalFormat
;
1814 /* don't use mipmap levels > 0 */
1815 tObj
->MinFilter
= tObj
->MagFilter
= GL_NEAREST
;
1818 /* test with all mipmap levels */
1819 tObj
->MinFilter
= GL_LINEAR_MIPMAP_LINEAR
;
1820 tObj
->MagFilter
= GL_NEAREST
;
1822 RevalidateTexture(ctx
, tObj
);
1825 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1826 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1827 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1828 printf("glide format 0x%x\n", ti->info.format);
1829 printf("data %p\n", ti->info.data);
1830 printf("lodblend %d\n", (int) ti->LODblend);
1833 /* determine where texture will reside */
1834 if (ti
->LODblend
&& !shared
->umaTexMemory
) {
1835 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1836 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1837 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1840 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1841 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1842 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1845 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1847 if (memNeeded
> shared
->totalTexMem
[0])
1852 case GL_PROXY_TEXTURE_3D
:
1853 return GL_TRUE
; /* software rendering */
1855 return GL_TRUE
; /* never happens, silence compiler */
1861 * Allocate a new texture object.
1862 * Called via ctx->Driver.NewTextureObject.
1863 * Note: this function will be called during context creation to
1864 * allocate the default texture objects.
1865 * Note: we could use containment here to 'derive' the driver-specific
1866 * texture object from the core mesa gl_texture_object. Not done at this time.
1868 static struct gl_texture_object
*
1869 tdfxNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
1871 struct gl_texture_object
*obj
;
1872 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1877 void tdfxInitTextureFuncs( struct dd_function_table
*functions
)
1879 functions
->BindTexture
= tdfxBindTexture
;
1880 functions
->NewTextureObject
= tdfxNewTextureObject
;
1881 functions
->DeleteTexture
= tdfxDeleteTexture
;
1882 functions
->TexEnv
= tdfxTexEnv
;
1883 functions
->TexParameter
= tdfxTexParameter
;
1884 functions
->ChooseTextureFormat
= tdfxChooseTextureFormat
;
1885 functions
->TexImage1D
= tdfxTexImage1D
;
1886 functions
->TexSubImage1D
= tdfxTexSubImage1D
;
1887 functions
->TexImage2D
= tdfxTexImage2D
;
1888 functions
->TexSubImage2D
= tdfxTexSubImage2D
;
1889 functions
->IsTextureResident
= tdfxIsTextureResident
;
1890 functions
->CompressedTexImage2D
= tdfxCompressedTexImage2D
;
1891 functions
->CompressedTexSubImage2D
= tdfxCompressedTexSubImage2D
;
1892 functions
->UpdateTexturePalette
= tdfxUpdateTexturePalette
;
1893 functions
->GenerateMipmap
= tdfxGenerateMipmap
;