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"
53 _mesa_halve2x2_teximage2d ( GLuint bytesPerPixel
,
54 GLint srcWidth
, GLint srcHeight
,
55 const GLvoid
*srcImage
, GLvoid
*dstImage
)
58 const GLint dstWidth
= srcWidth
/ 2;
59 const GLint dstHeight
= srcHeight
/ 2;
60 const GLint srcRowStride
= srcWidth
* bytesPerPixel
;
61 const GLubyte
*src
= srcImage
;
62 GLubyte
*dst
= dstImage
;
64 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
66 for (i
= 0; i
< dstWidth
; i
++) {
67 for (k
= 0; k
< bytesPerPixel
; k
++) {
68 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
74 } else if (srcWidth
== 1) {
75 for (j
= 0; j
< dstHeight
; j
++) {
76 for (k
= 0; k
< bytesPerPixel
; k
++) {
77 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
84 for (j
= 0; j
< dstHeight
; j
++) {
85 for (i
= 0; i
< dstWidth
; i
++) {
86 for (k
= 0; k
< bytesPerPixel
; k
++) {
90 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
126 * Compute various texture image parameters.
127 * Input: w, h - source texture width and height
128 * Output: lodlevel - Glide lod level token for the larger texture dimension
129 * aspectratio - Glide aspect ratio token
130 * sscale - S scale factor used during triangle setup
131 * tscale - T scale factor used during triangle setup
132 * wscale - OpenGL -> Glide image width scale factor
133 * hscale - OpenGL -> Glide image height scale factor
136 * w h lodlevel aspectRatio
137 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
138 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
139 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
140 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
141 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
144 tdfxTexGetInfo(const GLcontext
*ctx
, int w
, int h
,
145 GrLOD_t
*lodlevel
, GrAspectRatio_t
*aspectratio
,
146 float *sscale
, float *tscale
,
147 int *wscale
, int *hscale
)
149 int logw
, logh
, ar
, lod
, ws
, hs
;
157 ar
= logw
- logh
; /* aspect ratio = difference in log dimensions */
161 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
162 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
164 ASSERT(width
>= height
);
166 if (ar
<= GR_ASPECT_LOG2_8x1
) {
170 /* have to stretch image height */
173 ar
= GR_ASPECT_LOG2_8x1
;
177 ASSERT(width
< height
);
179 if (ar
>= GR_ASPECT_LOG2_1x8
) {
183 /* have to stretch image width */
186 ar
= GR_ASPECT_LOG2_1x8
;
191 *lodlevel
= (GrLOD_t
) lod
;
193 *aspectratio
= (GrAspectRatio_t
) ar
;
206 * We need to call this when a texture object's minification filter
207 * or texture image sizes change.
209 static void RevalidateTexture(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
211 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
217 minl
= maxl
= tObj
->BaseLevel
;
219 if (tObj
->Image
[0][minl
]) {
220 maxl
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0][minl
]->MaxLog2
);
222 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
223 tdfxTexGetInfo(ctx
, tObj
->Image
[0][minl
]->Width
, tObj
->Image
[0][minl
]->Height
,
224 &ti
->info
.largeLodLog2
,
225 &ti
->info
.aspectRatioLog2
,
226 &(ti
->sScale
), &(ti
->tScale
), NULL
, NULL
);
229 if (tObj
->Image
[0][maxl
] && (tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
)) {
230 /* mipmapping: need to compute smallLodLog2 */
231 tdfxTexGetInfo(ctx
, tObj
->Image
[0][maxl
]->Width
,
232 tObj
->Image
[0][maxl
]->Height
,
233 &ti
->info
.smallLodLog2
, NULL
,
234 NULL
, NULL
, NULL
, NULL
);
237 /* not mipmapping: smallLodLog2 = largeLodLog2 */
238 ti
->info
.smallLodLog2
= ti
->info
.largeLodLog2
;
244 ti
->info
.data
= NULL
;
246 /* this is necessary because of fxDDCompressedTexImage2D */
248 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
249 tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
250 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
251 ti
->sScale
/= mml
->wScale
;
252 ti
->tScale
/= mml
->hScale
;
259 fxAllocTexObjData(tdfxContextPtr fxMesa
)
263 if (!(ti
= CALLOC(sizeof(tdfxTexInfo
)))) {
264 _mesa_problem(NULL
, "tdfx driver: out of memory");
268 ti
->isInTM
= GL_FALSE
;
270 ti
->whichTMU
= TDFX_TMU_NONE
;
272 ti
->tm
[TDFX_TMU0
] = NULL
;
273 ti
->tm
[TDFX_TMU1
] = NULL
;
275 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
276 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
278 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
279 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
281 ti
->mmMode
= GR_MIPMAP_NEAREST
;
282 ti
->LODblend
= FXFALSE
;
289 * Called via glBindTexture.
292 tdfxBindTexture(GLcontext
* ctx
, GLenum target
,
293 struct gl_texture_object
*tObj
)
295 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
298 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
299 fprintf(stderr
, "fxmesa: fxDDTexBind(%d,%p)\n", tObj
->Name
,
303 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
306 if (!tObj
->DriverData
) {
307 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
310 ti
= TDFX_TEXTURE_DATA(tObj
);
311 ti
->lastTimeUsed
= fxMesa
->texBindNumber
++;
313 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
318 * Called via glTexEnv.
321 tdfxTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
322 const GLfloat
* param
)
324 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
326 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
328 fprintf(stderr
, "fxmesa: texenv(%x,%x)\n", pname
,
331 fprintf(stderr
, "fxmesa: texenv(%x)\n", pname
);
334 /* XXX this is a bit of a hack to force the Glide texture
335 * state to be updated.
337 fxMesa
->TexState
.EnvMode
[ctx
->Texture
.CurrentUnit
] = 0;
339 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
344 * Called via glTexParameter.
347 tdfxTexParameter(GLcontext
* ctx
, GLenum target
,
348 struct gl_texture_object
*tObj
,
349 GLenum pname
, const GLfloat
* params
)
351 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
352 GLenum param
= (GLenum
) (GLint
) params
[0];
355 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
356 fprintf(stderr
, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj
->Name
,
357 tObj
->DriverData
, pname
, param
);
360 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
363 if (!tObj
->DriverData
)
364 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
366 ti
= TDFX_TEXTURE_DATA(tObj
);
369 case GL_TEXTURE_MIN_FILTER
:
372 ti
->mmMode
= GR_MIPMAP_DISABLE
;
373 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
374 ti
->LODblend
= FXFALSE
;
377 ti
->mmMode
= GR_MIPMAP_DISABLE
;
378 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
379 ti
->LODblend
= FXFALSE
;
381 case GL_NEAREST_MIPMAP_LINEAR
:
382 if (!fxMesa
->Glide
.HaveCombineExt
) {
383 if (fxMesa
->haveTwoTMUs
) {
384 ti
->mmMode
= GR_MIPMAP_NEAREST
;
385 ti
->LODblend
= FXTRUE
;
388 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
389 ti
->LODblend
= FXFALSE
;
391 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
394 /* XXX Voodoo3/Banshee mipmap blending seems to produce
395 * incorrectly filtered colors for the smallest mipmap levels.
396 * To work-around we fall-through here and use a different filter.
398 case GL_NEAREST_MIPMAP_NEAREST
:
399 ti
->mmMode
= GR_MIPMAP_NEAREST
;
400 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
401 ti
->LODblend
= FXFALSE
;
403 case GL_LINEAR_MIPMAP_LINEAR
:
404 if (!fxMesa
->Glide
.HaveCombineExt
) {
405 if (fxMesa
->haveTwoTMUs
) {
406 ti
->mmMode
= GR_MIPMAP_NEAREST
;
407 ti
->LODblend
= FXTRUE
;
410 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
411 ti
->LODblend
= FXFALSE
;
413 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
416 /* XXX Voodoo3/Banshee mipmap blending seems to produce
417 * incorrectly filtered colors for the smallest mipmap levels.
418 * To work-around we fall-through here and use a different filter.
420 case GL_LINEAR_MIPMAP_NEAREST
:
421 ti
->mmMode
= GR_MIPMAP_NEAREST
;
422 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
423 ti
->LODblend
= FXFALSE
;
428 ti
->reloadImages
= GL_TRUE
;
429 RevalidateTexture(ctx
, tObj
);
430 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
433 case GL_TEXTURE_MAG_FILTER
:
436 ti
->magFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
439 ti
->magFilt
= GR_TEXTUREFILTER_BILINEAR
;
444 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
447 case GL_TEXTURE_WRAP_S
:
449 case GL_CLAMP_TO_BORDER
:
450 case GL_CLAMP_TO_EDGE
:
452 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
455 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
457 case GL_MIRRORED_REPEAT
:
458 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
463 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
466 case GL_TEXTURE_WRAP_T
:
468 case GL_CLAMP_TO_BORDER
:
469 case GL_CLAMP_TO_EDGE
:
471 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
474 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
476 case GL_MIRRORED_REPEAT
:
477 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
482 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
485 case GL_TEXTURE_BORDER_COLOR
:
488 case GL_TEXTURE_MIN_LOD
:
491 case GL_TEXTURE_MAX_LOD
:
494 case GL_TEXTURE_BASE_LEVEL
:
495 RevalidateTexture(ctx
, tObj
);
497 case GL_TEXTURE_MAX_LEVEL
:
498 RevalidateTexture(ctx
, tObj
);
508 * Called via glDeleteTextures to delete a texture object.
509 * Here, we delete the Glide data associated with the texture.
512 tdfxDeleteTexture(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
514 if (ctx
&& ctx
->DriverCtx
) {
515 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
516 tdfxTMFreeTexture(fxMesa
, tObj
);
517 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
518 /* Free mipmap images and the texture object itself */
519 _mesa_delete_texture_object(ctx
, tObj
);
525 * Return true if texture is resident, false otherwise.
528 tdfxIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
530 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
531 return (GLboolean
) (ti
&& ti
->isInTM
);
537 * Convert a gl_color_table texture palette to Glide's format.
540 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
542 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
543 GLint width
= table
->Size
;
547 ASSERT(table
->TableType
== GL_UNSIGNED_BYTE
);
549 switch (table
->Format
) {
551 for (i
= 0; i
< width
; i
++) {
556 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
558 return GR_TEXTABLE_PALETTE_6666_EXT
;
560 for (i
= 0; i
< width
; i
++) {
565 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
567 return GR_TEXTABLE_PALETTE
;
569 for (i
= 0; i
< width
; i
++) {
572 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
574 return GR_TEXTABLE_PALETTE_6666_EXT
;
575 case GL_LUMINANCE_ALPHA
:
576 for (i
= 0; i
< width
; i
++) {
577 r
= g
= b
= tableUB
[i
* 2 + 0];
578 a
= tableUB
[i
* 2 + 1];
579 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
581 return GR_TEXTABLE_PALETTE_6666_EXT
;
583 for (i
= 0; i
< width
; i
++) {
584 r
= tableUB
[i
* 3 + 0];
585 g
= tableUB
[i
* 3 + 1];
586 b
= tableUB
[i
* 3 + 2];
588 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
590 return GR_TEXTABLE_PALETTE
;
592 for (i
= 0; i
< width
; i
++) {
593 r
= tableUB
[i
* 4 + 0];
594 g
= tableUB
[i
* 4 + 1];
595 b
= tableUB
[i
* 4 + 2];
596 a
= tableUB
[i
* 4 + 3];
597 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
599 return GR_TEXTABLE_PALETTE_6666_EXT
;
606 tdfxUpdateTexturePalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
608 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
611 /* per-texture palette */
614 /* This might be a proxy texture. */
615 if (!tObj
->Palette
.Table
)
618 if (!tObj
->DriverData
)
619 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
620 ti
= TDFX_TEXTURE_DATA(tObj
);
622 ti
->paltype
= convertPalette(ti
->palette
.data
, &tObj
->Palette
);
623 /*tdfxTexInvalidate(ctx, tObj);*/
626 /* global texture palette */
627 fxMesa
->TexPalette
.Type
= convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
628 fxMesa
->TexPalette
.Data
= &(fxMesa
->glbPalette
.data
);
629 fxMesa
->dirty
|= TDFX_UPLOAD_TEXTURE_PALETTE
;
631 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX too heavy-handed */
635 /**********************************************************************/
636 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
637 /**********************************************************************/
640 static FxBool TexusFatalError
= FXFALSE
;
641 static FxBool TexusError
= FXFALSE
;
643 #define TX_DITHER_NONE 0x00000000
646 fxTexusError(const char *string
, FxBool fatal
)
648 _mesa_problem(NULL
, string
);
650 * Just propagate the fatal value up.
653 TexusFatalError
= fatal
;
658 static const struct gl_texture_format
*
659 tdfxChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
660 GLenum srcFormat
, GLenum srcType
)
662 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
663 const GLboolean allow32bpt
= TDFX_IS_NAPALM(fxMesa
);
665 switch (internalFormat
) {
671 case GL_COMPRESSED_ALPHA
:
672 return &_mesa_texformat_a8
;
679 case GL_COMPRESSED_LUMINANCE
:
680 return &_mesa_texformat_l8
;
682 case GL_LUMINANCE_ALPHA
:
683 case GL_LUMINANCE4_ALPHA4
:
684 case GL_LUMINANCE6_ALPHA2
:
685 case GL_LUMINANCE8_ALPHA8
:
686 case GL_LUMINANCE12_ALPHA4
:
687 case GL_LUMINANCE12_ALPHA12
:
688 case GL_LUMINANCE16_ALPHA16
:
689 case GL_COMPRESSED_LUMINANCE_ALPHA
:
690 return &_mesa_texformat_al88
;
696 case GL_COMPRESSED_INTENSITY
:
697 return &_mesa_texformat_i8
;
701 return &_mesa_texformat_rgb565
;
702 case GL_COMPRESSED_RGB
:
703 /* intentional fall-through */
706 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
707 return &_mesa_texformat_rgb565
;
709 /* intentional fall through */
714 return (allow32bpt
) ? &_mesa_texformat_argb8888
715 : &_mesa_texformat_rgb565
;
718 return &_mesa_texformat_argb4444
;
719 case GL_COMPRESSED_RGBA
:
720 /* intentional fall-through */
723 if ( srcFormat
== GL_BGRA
) {
724 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
725 return &_mesa_texformat_argb8888
;
727 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
728 return &_mesa_texformat_argb4444
;
730 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
731 return &_mesa_texformat_argb1555
;
734 /* intentional fall through */
739 return allow32bpt
? &_mesa_texformat_argb8888
740 : &_mesa_texformat_argb4444
;
742 return &_mesa_texformat_argb1555
;
744 case GL_COLOR_INDEX1_EXT
:
745 case GL_COLOR_INDEX2_EXT
:
746 case GL_COLOR_INDEX4_EXT
:
747 case GL_COLOR_INDEX8_EXT
:
748 case GL_COLOR_INDEX12_EXT
:
749 case GL_COLOR_INDEX16_EXT
:
750 return &_mesa_texformat_ci8
;
751 /* GL_EXT_texture_compression_s3tc */
753 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
756 return &_mesa_texformat_rgb_dxt1
;
757 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
758 return &_mesa_texformat_rgba_dxt1
;
759 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
762 return &_mesa_texformat_rgba_dxt3
;
763 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
764 return &_mesa_texformat_rgba_dxt5
;
765 /* GL_3DFX_texture_compression_FXT1 */
766 case GL_COMPRESSED_RGB_FXT1_3DFX
:
767 return &_mesa_texformat_rgb_fxt1
;
768 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
769 return &_mesa_texformat_rgba_fxt1
;
771 _mesa_problem(ctx
, "unexpected format in tdfxChooseTextureFormat");
778 * Return the Glide format for the given mesa texture format.
780 static GrTextureFormat_t
781 fxGlideFormat(GLint mesaFormat
)
783 switch (mesaFormat
) {
785 return GR_TEXFMT_ALPHA_8
;
787 return GR_TEXFMT_ALPHA_8
;
789 return GR_TEXFMT_INTENSITY_8
;
790 case MESA_FORMAT_CI8
:
791 return GR_TEXFMT_P_8
;
792 case MESA_FORMAT_AL88
:
793 return GR_TEXFMT_ALPHA_INTENSITY_88
;
794 case MESA_FORMAT_RGB565
:
795 return GR_TEXFMT_RGB_565
;
796 case MESA_FORMAT_ARGB4444
:
797 return GR_TEXFMT_ARGB_4444
;
798 case MESA_FORMAT_ARGB1555
:
799 return GR_TEXFMT_ARGB_1555
;
800 case MESA_FORMAT_ARGB8888
:
801 return GR_TEXFMT_ARGB_8888
;
802 case MESA_FORMAT_RGB_FXT1
:
803 case MESA_FORMAT_RGBA_FXT1
:
804 return GR_TEXFMT_ARGB_CMP_FXT1
;
805 case MESA_FORMAT_RGB_DXT1
:
806 case MESA_FORMAT_RGBA_DXT1
:
807 return GR_TEXFMT_ARGB_CMP_DXT1
;
808 case MESA_FORMAT_RGBA_DXT3
:
809 return GR_TEXFMT_ARGB_CMP_DXT3
;
810 case MESA_FORMAT_RGBA_DXT5
:
811 return GR_TEXFMT_ARGB_CMP_DXT5
;
813 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
819 /* Texel-fetch functions for software texturing and glGetTexImage().
820 * We should have been able to use some "standard" fetch functions (which
821 * may get defined in texutil.c) but we have to account for scaled texture
822 * images on tdfx hardware (the 8:1 aspect ratio limit).
823 * Hence, we need special functions here.
826 fxt1_decode_1 (const void *texture
, int width
,
827 int i
, int j
, unsigned char *rgba
);
830 fetch_intensity8(const struct gl_texture_image
*texImage
,
831 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
833 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
834 const GLubyte
*texel
;
839 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
840 rgba
[RCOMP
] = *texel
;
841 rgba
[GCOMP
] = *texel
;
842 rgba
[BCOMP
] = *texel
;
843 rgba
[ACOMP
] = *texel
;
848 fetch_luminance8(const struct gl_texture_image
*texImage
,
849 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
851 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
852 const GLubyte
*texel
;
857 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
858 rgba
[RCOMP
] = *texel
;
859 rgba
[GCOMP
] = *texel
;
860 rgba
[BCOMP
] = *texel
;
866 fetch_alpha8(const struct gl_texture_image
*texImage
,
867 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
869 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
870 const GLubyte
*texel
;
875 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
879 rgba
[ACOMP
] = *texel
;
884 fetch_index8(const struct gl_texture_image
*texImage
,
885 GLint i
, GLint j
, GLint k
, GLchan
* indexOut
)
887 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
888 const GLubyte
*texel
;
893 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
899 fetch_luminance8_alpha8(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
) * 2;
909 rgba
[RCOMP
] = texel
[0];
910 rgba
[GCOMP
] = texel
[0];
911 rgba
[BCOMP
] = texel
[0];
912 rgba
[ACOMP
] = texel
[1];
917 fetch_r5g6b5(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 GLushort
*texel
;
926 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
927 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
928 rgba
[GCOMP
] = (((*texel
) >> 5) & 0x3f) * 255 / 63;
929 rgba
[BCOMP
] = (((*texel
) >> 0) & 0x1f) * 255 / 31;
935 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
936 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
938 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
939 const GLushort
*texel
;
944 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
945 rgba
[RCOMP
] = (((*texel
) >> 12) & 0xf) * 255 / 15;
946 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xf) * 255 / 15;
947 rgba
[BCOMP
] = (((*texel
) >> 4) & 0xf) * 255 / 15;
948 rgba
[ACOMP
] = (((*texel
) >> 0) & 0xf) * 255 / 15;
953 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
954 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
956 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
957 const GLushort
*texel
;
962 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
963 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
964 rgba
[GCOMP
] = (((*texel
) >> 6) & 0x1f) * 255 / 31;
965 rgba
[BCOMP
] = (((*texel
) >> 1) & 0x1f) * 255 / 31;
966 rgba
[ACOMP
] = (((*texel
) >> 0) & 0x01) * 255;
971 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
972 GLint i
, GLint j
, GLint k
, GLchan
* rgba
)
974 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
980 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
981 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
982 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
983 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
984 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
989 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
990 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
992 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
997 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1003 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
1004 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1006 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1008 i
= i
* mml
->wScale
;
1009 j
= j
* mml
->hScale
;
1011 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
1016 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
1017 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1019 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1021 i
= i
* mml
->wScale
;
1022 j
= j
* mml
->hScale
;
1024 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1029 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
1030 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1032 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1034 i
= i
* mml
->wScale
;
1035 j
= j
* mml
->hScale
;
1037 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1042 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
1043 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1045 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1047 i
= i
* mml
->wScale
;
1048 j
= j
* mml
->hScale
;
1050 _mesa_texformat_rgba_dxt3
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1055 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
1056 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
1058 const tdfxMipMapLevel
*mml
= TDFX_TEXIMAGE_DATA(texImage
);
1060 i
= i
* mml
->wScale
;
1061 j
= j
* mml
->hScale
;
1063 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1067 static FetchTexelFuncC
1068 fxFetchFunction(GLint mesaFormat
)
1070 switch (mesaFormat
) {
1071 case MESA_FORMAT_I8
:
1072 return &fetch_intensity8
;
1073 case MESA_FORMAT_A8
:
1074 return &fetch_alpha8
;
1075 case MESA_FORMAT_L8
:
1076 return &fetch_luminance8
;
1077 case MESA_FORMAT_CI8
:
1078 return &fetch_index8
;
1079 case MESA_FORMAT_AL88
:
1080 return &fetch_luminance8_alpha8
;
1081 case MESA_FORMAT_RGB565
:
1082 return &fetch_r5g6b5
;
1083 case MESA_FORMAT_ARGB4444
:
1084 return &fetch_r4g4b4a4
;
1085 case MESA_FORMAT_ARGB1555
:
1086 return &fetch_r5g5b5a1
;
1087 case MESA_FORMAT_ARGB8888
:
1088 return &fetch_a8r8g8b8
;
1089 case MESA_FORMAT_RGB_FXT1
:
1090 return &fetch_rgb_fxt1
;
1091 case MESA_FORMAT_RGBA_FXT1
:
1092 return &fetch_rgba_fxt1
;
1093 case MESA_FORMAT_RGB_DXT1
:
1094 return &fetch_rgb_dxt1
;
1095 case MESA_FORMAT_RGBA_DXT1
:
1096 return &fetch_rgba_dxt1
;
1097 case MESA_FORMAT_RGBA_DXT3
:
1098 return &fetch_rgba_dxt3
;
1099 case MESA_FORMAT_RGBA_DXT5
:
1100 return &fetch_rgba_dxt5
;
1102 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1109 adjust2DRatio (GLcontext
*ctx
,
1110 GLint xoffset
, GLint yoffset
,
1111 GLint width
, GLint height
,
1112 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1113 const struct gl_pixelstore_attrib
*packing
,
1114 tdfxMipMapLevel
*mml
,
1115 struct gl_texture_image
*texImage
,
1119 const GLint newWidth
= width
* mml
->wScale
;
1120 const GLint newHeight
= height
* mml
->hScale
;
1123 if (!texImage
->IsCompressed
) {
1125 tempImage
= MALLOC(width
* height
* texelBytes
);
1130 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1131 texImage
->TexFormat
, tempImage
,
1132 0, 0, 0, /* dstX/Y/Zoffset */
1133 width
* texelBytes
, /* dstRowStride */
1134 0, /* dstImageStride */
1136 format
, type
, pixels
, packing
);
1139 /* compute address of dest subimage within the overal tex image */
1140 destAddr
= (GLubyte
*) texImage
->Data
1141 + (yoffset
* mml
->hScale
* mml
->width
1142 + xoffset
* mml
->wScale
) * texelBytes
;
1144 _mesa_rescale_teximage2d(texelBytes
,
1145 dstRowStride
, /* dst stride */
1147 newWidth
, newHeight
,
1148 tempImage
, destAddr
);
1150 const GLint rawBytes
= 4;
1151 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1155 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1159 /* unpack image, apply transfer ops and store in rawImage */
1160 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
1161 &_mesa_texformat_rgba8888_rev
, rawImage
,
1162 0, 0, 0, /* dstX/Y/Zoffset */
1163 width
* rawBytes
, /* dstRowStride */
1164 0, /* dstImageStride */
1166 format
, type
, pixels
, packing
);
1167 _mesa_rescale_teximage2d(rawBytes
,
1168 newWidth
* rawBytes
, /* dst stride */
1169 width
, height
, /* src */
1170 newWidth
, newHeight
, /* dst */
1171 rawImage
/*src*/, tempImage
/*dst*/ );
1172 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1173 texImage
->TexFormat
, texImage
->Data
,
1174 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1176 0, /* dstImageStride */
1177 newWidth
, newHeight
, 1,
1178 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1189 tdfxTexImage2D(GLcontext
*ctx
, GLenum target
, GLint level
,
1190 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1191 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1192 const struct gl_pixelstore_attrib
*packing
,
1193 struct gl_texture_object
*texObj
,
1194 struct gl_texture_image
*texImage
)
1196 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1198 tdfxMipMapLevel
*mml
;
1199 GLint texelBytes
, dstRowStride
;
1202 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1203 texObj->Name, texImage->IntFormat, format, type,
1204 texImage->Width, texImage->Height);
1207 ti
= TDFX_TEXTURE_DATA(texObj
);
1209 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1210 if (!texObj
->DriverData
) {
1211 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1214 ti
= TDFX_TEXTURE_DATA(texObj
);
1218 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1220 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1221 if (!texImage
->DriverData
) {
1222 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1225 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1228 /* Determine width and height scale factors for texture.
1229 * Remember, Glide is limited to 8:1 aspect ratios.
1232 texImage
->Width
, texImage
->Height
,
1233 NULL
, /* lod level */
1234 NULL
, /* aspect ratio */
1235 NULL
, NULL
, /* sscale, tscale */
1236 &mml
->wScale
, &mml
->hScale
);
1238 /* rescaled size: */
1239 mml
->width
= width
* mml
->wScale
;
1240 mml
->height
= height
* mml
->hScale
;
1242 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1243 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1244 /* [dBorca] we should update texture's attribute, then,
1245 * because if the application asks us to decompress, we
1246 * have to know the REAL format! Also, DXT3/5 might not
1247 * be correct, since it would mess with "compressedSize".
1248 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1250 if (texImage
->IsCompressed
) {
1251 switch (internalFormat
) {
1252 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1255 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1257 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1258 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1259 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1262 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1264 texImage
->IntFormat
= internalFormat
;
1268 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1269 GLenum texNapalm
= 0;
1270 if (internalFormat
== GL_COMPRESSED_RGB
) {
1271 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1272 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1273 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1276 texImage
->IntFormat
= internalFormat
= texNapalm
;
1277 texImage
->IsCompressed
= GL_TRUE
;
1282 /* choose the texture format */
1283 assert(ctx
->Driver
.ChooseTextureFormat
);
1284 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1285 internalFormat
, format
, type
);
1286 assert(texImage
->TexFormat
);
1287 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1288 ti
->info
.format
= mml
->glideFormat
;
1289 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1290 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1292 if (texImage
->IsCompressed
) {
1293 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1298 dstRowStride
= _mesa_compressed_row_stride(internalFormat
, mml
->width
);
1299 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1301 dstRowStride
= mml
->width
* texelBytes
;
1302 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1304 if (!texImage
->Data
) {
1305 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1309 if (pixels
!= NULL
) {
1310 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1311 /* rescale image to overcome 1:8 aspect limitation */
1312 if (!adjust2DRatio(ctx
,
1315 format
, type
, pixels
,
1322 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1327 /* no rescaling needed */
1328 /* unpack image, apply transfer ops and store in texImage->Data */
1329 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1330 texImage
->TexFormat
, texImage
->Data
,
1331 0, 0, 0, /* dstX/Y/Zoffset */
1333 0, /* dstImageStride */
1335 format
, type
, pixels
, packing
);
1338 /* GL_SGIS_generate_mipmap */
1339 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1340 GLint mipWidth
, mipHeight
;
1341 tdfxMipMapLevel
*mip
;
1342 struct gl_texture_image
*mipImage
;
1343 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1344 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1346 assert(!texImage
->IsCompressed
);
1348 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1349 mipWidth
= width
/ 2;
1353 mipHeight
= height
/ 2;
1357 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1360 _mesa_TexImage2D(target
, ++level
, internalFormat
,
1361 mipWidth
, mipHeight
, border
,
1364 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1365 mip
= TDFX_TEXIMAGE_DATA(mipImage
);
1366 _mesa_halve2x2_teximage2d(texelBytes
,
1367 mml
->width
, mml
->height
,
1368 texImage
->Data
, mipImage
->Data
);
1369 texImage
= mipImage
;
1377 RevalidateTexture(ctx
, texObj
);
1379 ti
->reloadImages
= GL_TRUE
;
1380 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1385 tdfxTexSubImage2D(GLcontext
*ctx
, GLenum target
, GLint level
,
1386 GLint xoffset
, GLint yoffset
,
1387 GLsizei width
, GLsizei height
,
1388 GLenum format
, GLenum type
,
1389 const GLvoid
*pixels
,
1390 const struct gl_pixelstore_attrib
*packing
,
1391 struct gl_texture_object
*texObj
,
1392 struct gl_texture_image
*texImage
)
1394 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1396 tdfxMipMapLevel
*mml
;
1397 GLint texelBytes
, dstRowStride
;
1399 if (!texObj
->DriverData
) {
1400 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1404 ti
= TDFX_TEXTURE_DATA(texObj
);
1406 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1409 assert(texImage
->Data
); /* must have an existing texture image! */
1410 assert(texImage
->Format
);
1412 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1413 if (texImage
->IsCompressed
) {
1414 dstRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, mml
->width
);
1416 dstRowStride
= mml
->width
* texelBytes
;
1419 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1420 /* need to rescale subimage to match mipmap level's rescale factors */
1421 if (!adjust2DRatio(ctx
,
1424 format
, type
, pixels
,
1431 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1436 /* no rescaling needed */
1437 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1438 texImage
->TexFormat
, texImage
->Data
,
1439 xoffset
, yoffset
, 0,
1441 0, /* dstImageStride */
1443 format
, type
, pixels
, packing
);
1446 /* GL_SGIS_generate_mipmap */
1447 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1448 GLint mipWidth
, mipHeight
;
1449 tdfxMipMapLevel
*mip
;
1450 struct gl_texture_image
*mipImage
;
1451 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1452 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1454 assert(!texImage
->IsCompressed
);
1456 width
= texImage
->Width
;
1457 height
= texImage
->Height
;
1458 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1459 mipWidth
= width
/ 2;
1463 mipHeight
= height
/ 2;
1467 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1471 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1472 mip
= TDFX_TEXIMAGE_DATA(mipImage
);
1473 _mesa_halve2x2_teximage2d(texelBytes
,
1474 mml
->width
, mml
->height
,
1475 texImage
->Data
, mipImage
->Data
);
1476 texImage
= mipImage
;
1483 ti
->reloadImages
= GL_TRUE
; /* signal the image needs to be reloaded */
1484 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
; /* XXX this might be a bit much */
1489 tdfxTexImage1D(GLcontext
*ctx
, GLenum target
, GLint level
,
1490 GLint internalFormat
, GLint width
, GLint border
,
1491 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1492 const struct gl_pixelstore_attrib
*packing
,
1493 struct gl_texture_object
*texObj
,
1494 struct gl_texture_image
*texImage
)
1496 tdfxTexImage2D(ctx
, target
, level
,
1497 internalFormat
, width
, 1, border
,
1498 format
, type
, pixels
,
1505 tdfxTexSubImage1D(GLcontext
*ctx
, GLenum target
, GLint level
,
1508 GLenum format
, GLenum type
,
1509 const GLvoid
*pixels
,
1510 const struct gl_pixelstore_attrib
*packing
,
1511 struct gl_texture_object
*texObj
,
1512 struct gl_texture_image
*texImage
)
1514 tdfxTexSubImage2D(ctx
, target
, level
,
1524 /**********************************************************************/
1525 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1526 /**********************************************************************/
1529 tdfxCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1530 GLint level
, GLint internalFormat
,
1531 GLsizei width
, GLsizei height
, GLint border
,
1532 GLsizei imageSize
, const GLvoid
*data
,
1533 struct gl_texture_object
*texObj
,
1534 struct gl_texture_image
*texImage
)
1536 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1538 tdfxMipMapLevel
*mml
;
1540 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1541 fprintf(stderr
, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1542 texObj
->Name
, internalFormat
,
1546 if ((target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
) || texImage
->Border
> 0) {
1547 _mesa_problem(NULL
, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
1551 assert(texImage
->IsCompressed
);
1553 ti
= TDFX_TEXTURE_DATA(texObj
);
1555 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1556 if (!texObj
->DriverData
) {
1557 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1560 ti
= TDFX_TEXTURE_DATA(texObj
);
1564 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1566 texImage
->DriverData
= CALLOC(sizeof(tdfxMipMapLevel
));
1567 if (!texImage
->DriverData
) {
1568 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1571 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1574 tdfxTexGetInfo(ctx
, width
, height
, NULL
, NULL
, NULL
, NULL
,
1575 &mml
->wScale
, &mml
->hScale
);
1577 mml
->width
= width
* mml
->wScale
;
1578 mml
->height
= height
* mml
->hScale
;
1581 /* choose the texture format */
1582 assert(ctx
->Driver
.ChooseTextureFormat
);
1583 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1584 internalFormat
, -1/*format*/, -1/*type*/);
1585 assert(texImage
->TexFormat
);
1587 /* Determine the appropriate Glide texel format,
1588 * given the user's internal texture format hint.
1590 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1591 ti
->info
.format
= mml
->glideFormat
;
1592 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1594 /* allocate new storage for texture image, if needed */
1595 if (!texImage
->Data
) {
1596 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1601 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1602 if (!texImage
->Data
) {
1603 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1608 /* save the texture data */
1609 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1610 /* [dBorca] Hack alert:
1611 * now we're screwed. We can't decompress,
1612 * unless we do it in HW (via textureBuffer).
1613 * We still have some chances:
1614 * 1) we got FXT1 textures - we CAN decompress, rescale for
1615 * aspectratio, then compress back.
1616 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1617 * Thus, we don't care about textureclamp and we could lower
1618 * MIN("uscale", "vscale") below 32. We still have to have
1619 * our data aligned inside a 8:1 rectangle.
1620 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1621 * we replicate the data over the padded area.
1622 * For now, we take 2) + 3) but texelfetchers will be wrong!
1624 GLuint srcRowStride
= _mesa_compressed_row_stride(internalFormat
, width
);
1626 GLuint destRowStride
= _mesa_compressed_row_stride(internalFormat
,
1629 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1630 destRowStride
, (mml
->height
+3) / 4,
1631 1, data
, srcRowStride
,
1633 ti
->padded
= GL_TRUE
;
1635 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1638 /* GL_SGIS_generate_mipmap */
1639 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1640 assert(!texImage
->IsCompressed
);
1643 RevalidateTexture(ctx
, texObj
);
1645 ti
->reloadImages
= GL_TRUE
;
1646 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1651 tdfxCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1652 GLint level
, GLint xoffset
,
1653 GLint yoffset
, GLsizei width
,
1654 GLint height
, GLenum format
,
1655 GLsizei imageSize
, const GLvoid
*data
,
1656 struct gl_texture_object
*texObj
,
1657 struct gl_texture_image
*texImage
)
1659 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1661 tdfxMipMapLevel
*mml
;
1662 GLint destRowStride
, srcRowStride
;
1666 if (TDFX_DEBUG
& DEBUG_VERBOSE_DRI
) {
1667 fprintf(stderr
, "tdfxCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1670 ti
= TDFX_TEXTURE_DATA(texObj
);
1672 mml
= TDFX_TEXIMAGE_DATA(texImage
);
1675 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, width
);
1677 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1679 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1680 texImage
->IntFormat
,
1682 (GLubyte
*) texImage
->Data
);
1684 rows
= height
/ 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1686 for (i
= 0; i
< rows
; i
++) {
1687 MEMCPY(dest
, data
, srcRowStride
);
1688 dest
+= destRowStride
;
1689 data
= (GLvoid
*)((GLuint
)data
+ (GLuint
)srcRowStride
);
1692 /* [dBorca] Hack alert:
1693 * see fxDDCompressedTexImage2D for caveats
1695 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1696 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, texImage
->Width
);
1698 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1700 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1701 destRowStride
, mml
->height
/ 4,
1702 1, texImage
->Data
, destRowStride
,
1706 /* GL_SGIS_generate_mipmap */
1707 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1708 assert(!texImage
->IsCompressed
);
1711 RevalidateTexture(ctx
, texObj
);
1713 ti
->reloadImages
= GL_TRUE
;
1714 fxMesa
->new_state
|= TDFX_NEW_TEXTURE
;
1720 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1723 for (i
= 0; i
< h
; i
++) {
1724 for (j
= 0; j
< w
; j
++) {
1726 printf("%02x %02x ", data
[0], data
[1]);
1728 printf("%02x %02x %02x ", data
[0], data
[1], data
[2]);
1738 tdfxTestProxyTexImage(GLcontext
*ctx
, GLenum target
,
1739 GLint level
, GLint internalFormat
,
1740 GLenum format
, GLenum type
,
1741 GLint width
, GLint height
,
1742 GLint depth
, GLint border
)
1744 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1745 struct gl_shared_state
*mesaShared
= fxMesa
->glCtx
->Shared
;
1746 struct tdfxSharedState
*shared
= (struct tdfxSharedState
*) mesaShared
->DriverData
;
1749 case GL_PROXY_TEXTURE_1D
:
1751 case GL_PROXY_TEXTURE_2D
:
1753 struct gl_texture_object
*tObj
;
1757 tObj
= ctx
->Texture
.Proxy2D
;
1758 if (!tObj
->DriverData
)
1759 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1760 ti
= TDFX_TEXTURE_DATA(tObj
);
1763 /* assign the parameters to test against */
1764 tObj
->Image
[0][level
]->Width
= width
;
1765 tObj
->Image
[0][level
]->Height
= height
;
1766 tObj
->Image
[0][level
]->Border
= border
;
1768 tObj
->Image
[0][level
]->IntFormat
= internalFormat
;
1771 /* don't use mipmap levels > 0 */
1772 tObj
->MinFilter
= tObj
->MagFilter
= GL_NEAREST
;
1775 /* test with all mipmap levels */
1776 tObj
->MinFilter
= GL_LINEAR_MIPMAP_LINEAR
;
1777 tObj
->MagFilter
= GL_NEAREST
;
1779 RevalidateTexture(ctx
, tObj
);
1782 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1783 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1784 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1785 printf("glide format 0x%x\n", ti->info.format);
1786 printf("data %p\n", ti->info.data);
1787 printf("lodblend %d\n", (int) ti->LODblend);
1790 /* determine where texture will reside */
1791 if (ti
->LODblend
&& !shared
->umaTexMemory
) {
1792 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1793 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1794 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1797 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1798 memNeeded
= fxMesa
->Glide
.grTexTextureMemRequired(
1799 GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
1802 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1804 if (memNeeded
> shared
->totalTexMem
[0])
1809 case GL_PROXY_TEXTURE_3D
:
1810 return GL_TRUE
; /* software rendering */
1812 return GL_TRUE
; /* never happens, silence compiler */
1818 * Allocate a new texture object.
1819 * Called via ctx->Driver.NewTextureObject.
1820 * Note: this function will be called during context creation to
1821 * allocate the default texture objects.
1822 * Note: we could use containment here to 'derive' the driver-specific
1823 * texture object from the core mesa gl_texture_object. Not done at this time.
1825 static struct gl_texture_object
*
1826 tdfxNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
1828 struct gl_texture_object
*obj
;
1829 obj
= _mesa_new_texture_object(ctx
, name
, target
);
1834 void tdfxInitTextureFuncs( struct dd_function_table
*functions
)
1836 functions
->BindTexture
= tdfxBindTexture
;
1837 functions
->NewTextureObject
= tdfxNewTextureObject
;
1838 functions
->DeleteTexture
= tdfxDeleteTexture
;
1839 functions
->TexEnv
= tdfxTexEnv
;
1840 functions
->TexParameter
= tdfxTexParameter
;
1841 functions
->ChooseTextureFormat
= tdfxChooseTextureFormat
;
1842 functions
->TexImage1D
= tdfxTexImage1D
;
1843 functions
->TexSubImage1D
= tdfxTexSubImage1D
;
1844 functions
->TexImage2D
= tdfxTexImage2D
;
1845 functions
->TexSubImage2D
= tdfxTexSubImage2D
;
1846 functions
->IsTextureResident
= tdfxIsTextureResident
;
1847 functions
->CompressedTexImage2D
= tdfxCompressedTexImage2D
;
1848 functions
->CompressedTexSubImage2D
= tdfxCompressedTexSubImage2D
;
1849 functions
->UpdateTexturePalette
= tdfxUpdateTexturePalette
;