1 /* $Id: fxddtex.c,v 1.48 2003/10/02 17:36:44 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46 #include "texformat.h"
52 fxPrintTextureData(tfxTexInfo
* ti
)
54 fprintf(stderr
, "Texture Data:\n");
56 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
57 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
58 fprintf(stderr
, "\tSize: %d x %d\n",
59 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Width
,
60 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Height
);
63 fprintf(stderr
, "\tName: UNNAMED\n");
64 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
65 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
66 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
68 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
69 (unsigned) ti
->tm
[0]->endAddr
);
71 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
72 (unsigned) ti
->tm
[1]->endAddr
);
73 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
74 fprintf(stderr
, "\tFilters: min %d min %d\n",
75 (int) ti
->minFilt
, (int) ti
->maxFilt
);
76 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
78 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
79 fprintf(stderr
, "\t%s\n",
80 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
81 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
85 /************************************************************************/
86 /*************************** Texture Mapping ****************************/
87 /************************************************************************/
90 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
92 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
95 ti
= fxTMGetTexInfo(tObj
);
97 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
99 ti
->validated
= GL_FALSE
;
100 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
104 fxAllocTexObjData(fxMesaContext fxMesa
)
108 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
109 fprintf(stderr
, "%s: ERROR: out of memory !\n", __FUNCTION__
);
114 ti
->validated
= GL_FALSE
;
115 ti
->isInTM
= GL_FALSE
;
117 ti
->whichTMU
= FX_TMU_NONE
;
119 ti
->tm
[FX_TMU0
] = NULL
;
120 ti
->tm
[FX_TMU1
] = NULL
;
122 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
123 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
125 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
126 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
128 ti
->mmMode
= GR_MIPMAP_NEAREST
;
129 ti
->LODblend
= FXFALSE
;
135 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
137 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
140 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
141 fprintf(stderr
, "%s(%d, %x)\n", __FUNCTION__
, tObj
->Name
,
142 (GLuint
) tObj
->DriverData
);
145 if (target
!= GL_TEXTURE_2D
)
148 if (!tObj
->DriverData
) {
149 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
152 ti
= fxTMGetTexInfo(tObj
);
154 fxMesa
->texBindNumber
++;
155 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
157 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
161 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
162 const GLfloat
* param
)
164 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
166 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
168 fprintf(stderr
, "%s(%x, %x)\n", __FUNCTION__
, pname
, (GLint
) (*param
));
170 fprintf(stderr
, "%s(%x)\n", __FUNCTION__
, pname
);
173 /* apply any lod biasing right now */
174 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
175 grTexLodBiasValue(GR_TMU0
, *param
);
177 if (fxMesa
->haveTwoTMUs
) {
178 grTexLodBiasValue(GR_TMU1
, *param
);
183 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
187 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
188 GLenum pname
, const GLfloat
* params
)
190 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
191 GLenum param
= (GLenum
) (GLint
) params
[0];
194 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
195 fprintf(stderr
, "%s(%d, %x, %x, %x)\n", __FUNCTION__
,
196 tObj
->Name
, (GLuint
) tObj
->DriverData
, pname
, param
);
199 if (target
!= GL_TEXTURE_2D
)
202 if (!tObj
->DriverData
)
203 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
205 ti
= fxTMGetTexInfo(tObj
);
209 case GL_TEXTURE_MIN_FILTER
:
212 ti
->mmMode
= GR_MIPMAP_DISABLE
;
213 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
214 ti
->LODblend
= FXFALSE
;
217 ti
->mmMode
= GR_MIPMAP_DISABLE
;
218 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
219 ti
->LODblend
= FXFALSE
;
221 case GL_NEAREST_MIPMAP_LINEAR
:
222 if (fxMesa
->haveTwoTMUs
) {
223 ti
->mmMode
= GR_MIPMAP_NEAREST
;
224 ti
->LODblend
= FXTRUE
;
227 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
228 ti
->LODblend
= FXFALSE
;
230 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
231 break; /* ZZZ: we may have to fall through here for V3 */
232 case GL_NEAREST_MIPMAP_NEAREST
:
233 ti
->mmMode
= GR_MIPMAP_NEAREST
;
234 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
235 ti
->LODblend
= FXFALSE
;
237 case GL_LINEAR_MIPMAP_LINEAR
:
238 /* ZZZ: HACK ALERT! trilinear is bugged! mipmap blending produce
239 incorrect filtered colors for the smallest mipmap levels. */
241 if (fxMesa
->haveTwoTMUs
) {
242 ti
->mmMode
= GR_MIPMAP_NEAREST
;
243 ti
->LODblend
= FXTRUE
;
246 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
247 ti
->LODblend
= FXFALSE
;
249 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
250 break; /* ZZZ: we may have to fall through here for V3 */
252 case GL_LINEAR_MIPMAP_NEAREST
:
253 ti
->mmMode
= GR_MIPMAP_NEAREST
;
254 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
255 ti
->LODblend
= FXFALSE
;
260 fxTexInvalidate(ctx
, tObj
);
263 case GL_TEXTURE_MAG_FILTER
:
266 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
269 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
274 fxTexInvalidate(ctx
, tObj
);
277 case GL_TEXTURE_WRAP_S
:
279 case GL_MIRRORED_REPEAT
:
280 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
283 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
286 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
291 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
294 case GL_TEXTURE_WRAP_T
:
296 case GL_MIRRORED_REPEAT
:
297 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
300 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
303 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
308 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
311 case GL_TEXTURE_BORDER_COLOR
:
315 case GL_TEXTURE_MIN_LOD
:
318 case GL_TEXTURE_MAX_LOD
:
321 case GL_TEXTURE_BASE_LEVEL
:
322 fxTexInvalidate(ctx
, tObj
);
324 case GL_TEXTURE_MAX_LEVEL
:
325 fxTexInvalidate(ctx
, tObj
);
334 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
336 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
337 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
339 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
340 fprintf(stderr
, "%s(%d, %p)\n", __FUNCTION__
, tObj
->Name
, (void *) ti
);
346 fxTMFreeTexture(fxMesa
, tObj
);
349 tObj
->DriverData
= NULL
;
355 * Convert a gl_color_table texture palette to Glide's format.
358 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
360 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
361 GLint width
= table
->Size
;
365 ASSERT(!table
->FloatTable
);
367 switch (table
->Format
) {
369 for (i
= 0; i
< width
; i
++) {
374 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
378 for (i
= 0; i
< width
; i
++) {
383 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
387 for (i
= 0; i
< width
; i
++) {
390 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
393 case GL_LUMINANCE_ALPHA
:
394 for (i
= 0; i
< width
; i
++) {
395 r
= g
= b
= tableUB
[i
* 2 + 0];
396 a
= tableUB
[i
* 2 + 1];
397 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
401 for (i
= 0; i
< width
; i
++) {
402 r
= tableUB
[i
* 3 + 0];
403 g
= tableUB
[i
* 3 + 1];
404 b
= tableUB
[i
* 3 + 2];
406 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
410 for (i
= 0; i
< width
; i
++) {
411 r
= tableUB
[i
* 4 + 0];
412 g
= tableUB
[i
* 4 + 1];
413 b
= tableUB
[i
* 4 + 2];
414 a
= tableUB
[i
* 4 + 3];
415 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
423 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
425 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
428 /* per-texture palette */
430 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
431 fprintf(stderr
, "%s(%d, %x)\n", __FUNCTION__
,
432 tObj
->Name
, (GLuint
) tObj
->DriverData
);
434 if (!tObj
->DriverData
)
435 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
436 ti
= fxTMGetTexInfo(tObj
);
437 convertPalette(ti
->palette
.data
, &tObj
->Palette
);
438 fxTexInvalidate(ctx
, tObj
);
441 /* global texture palette */
442 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
443 fprintf(stderr
, "%s(global)\n", __FUNCTION__
);
445 convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
446 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
452 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
454 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
456 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
457 fprintf(stderr
, "%s(%d)\n", __FUNCTION__
, state
);
461 fxMesa
->haveGlobalPaletteTexture
= 1;
463 grTexDownloadTable(GR_TEXTABLE_PALETTE
, &(fxMesa
->glbPalette
));
466 fxMesa
->haveGlobalPaletteTexture
= 0;
468 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
469 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
470 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
472 if (!tObj
->DriverData
)
473 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
475 fxTexInvalidate(ctx
, tObj
);
505 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
506 float *sscale
, float *tscale
,
507 int *wscale
, int *hscale
)
510 static GrLOD_t lod
[12] = {
525 int logw
, logh
, ws
, hs
;
527 GrAspectRatio_t aspectratio
;
533 switch (logw
- logh
) {
535 aspectratio
= GR_ASPECT_LOG2_1x1
;
541 aspectratio
= GR_ASPECT_LOG2_2x1
;
549 aspectratio
= GR_ASPECT_LOG2_4x1
;
557 aspectratio
= GR_ASPECT_LOG2_8x1
;
565 aspectratio
= GR_ASPECT_LOG2_1x2
;
573 aspectratio
= GR_ASPECT_LOG2_1x4
;
581 aspectratio
= GR_ASPECT_LOG2_1x8
;
589 if ((logw
- logh
) > 3) {
590 aspectratio
= GR_ASPECT_LOG2_8x1
;
595 hs
= 1 << (logw
- logh
- 3);
596 } else /*if ((logw - logh) < -3)*/ {
597 aspectratio
= GR_ASPECT_LOG2_1x8
;
601 ws
= 1 << (logh
- logw
- 3);
629 * Given an OpenGL internal texture format, return the corresponding
630 * Glide internal texture format and base texture format.
633 fxTexGetFormat(GLcontext
*ctx
, GLenum glformat
, GrTextureFormat_t
* tfmt
, GLint
* ifmt
) /* [koolsmoky] */
635 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
636 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
646 (*tfmt
) = GR_TEXFMT_INTENSITY_8
;
648 (*ifmt
) = GL_LUMINANCE
;
651 case GL_LUMINANCE_ALPHA
:
652 case GL_LUMINANCE4_ALPHA4
:
653 case GL_LUMINANCE6_ALPHA2
:
654 case GL_LUMINANCE8_ALPHA8
:
655 case GL_LUMINANCE12_ALPHA4
:
656 case GL_LUMINANCE12_ALPHA12
:
657 case GL_LUMINANCE16_ALPHA16
:
659 (*tfmt
) = GR_TEXFMT_ALPHA_INTENSITY_88
;
661 (*ifmt
) = GL_LUMINANCE_ALPHA
;
669 (*tfmt
) = GR_TEXFMT_ALPHA_8
;
671 (*ifmt
) = GL_INTENSITY
;
679 (*tfmt
) = GR_TEXFMT_ALPHA_8
;
687 (*tfmt
) = GR_TEXFMT_RGB_565
;
698 (*tfmt
) = allow32bpt
? GR_TEXFMT_ARGB_8888
: GR_TEXFMT_RGB_565
;
705 (*tfmt
) = GR_TEXFMT_ARGB_4444
;
716 (*tfmt
) = allow32bpt
? GR_TEXFMT_ARGB_8888
: GR_TEXFMT_ARGB_4444
;
722 (*tfmt
) = GR_TEXFMT_ARGB_1555
;
727 case GL_COLOR_INDEX1_EXT
:
728 case GL_COLOR_INDEX2_EXT
:
729 case GL_COLOR_INDEX4_EXT
:
730 case GL_COLOR_INDEX8_EXT
:
731 case GL_COLOR_INDEX12_EXT
:
732 case GL_COLOR_INDEX16_EXT
:
734 (*tfmt
) = GR_TEXFMT_P_8
;
736 (*ifmt
) = GL_RGBA
; /* XXX why is this RGBA? */
739 fprintf(stderr
, "%s: ERROR: unsupported internalFormat (0x%x)\n",
740 __FUNCTION__
, glformat
);
748 fxIsTexSupported(GLenum target
, GLint internalFormat
,
749 const struct gl_texture_image
*image
)
751 if (target
!= GL_TEXTURE_2D
)
754 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
757 if (image
->Border
> 0)
764 /**********************************************************************/
765 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
766 /**********************************************************************/
768 /* Texel-fetch functions for software texturing and glGetTexImage().
769 * We should have been able to use some "standard" fetch functions (which
770 * may get defined in texutil.c) but we have to account for scaled texture
771 * images on tdfx hardware (the 8:1 aspect ratio limit).
772 * Hence, we need special functions here.
776 fetch_intensity8(const struct gl_texture_image
*texImage
,
777 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
779 GLchan
*rgba
= (GLchan
*) texelOut
;
780 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
781 const GLubyte
*texel
;
786 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
787 rgba
[RCOMP
] = *texel
;
788 rgba
[GCOMP
] = *texel
;
789 rgba
[BCOMP
] = *texel
;
790 rgba
[ACOMP
] = *texel
;
795 fetch_luminance8(const struct gl_texture_image
*texImage
,
796 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
798 GLchan
*rgba
= (GLchan
*) texelOut
;
799 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
800 const GLubyte
*texel
;
805 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
806 rgba
[RCOMP
] = *texel
;
807 rgba
[GCOMP
] = *texel
;
808 rgba
[BCOMP
] = *texel
;
814 fetch_alpha8(const struct gl_texture_image
*texImage
,
815 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
817 GLchan
*rgba
= (GLchan
*) texelOut
;
818 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
819 const GLubyte
*texel
;
823 i
= i
* mml
->width
/ texImage
->Width
;
824 j
= j
* mml
->height
/ texImage
->Height
;
826 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
830 rgba
[ACOMP
] = *texel
;
835 fetch_index8(const struct gl_texture_image
*texImage
,
836 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
838 GLchan
*indexOut
= (GLchan
*) texelOut
;
839 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
840 const GLubyte
*texel
;
844 i
= i
* mml
->width
/ texImage
->Width
;
845 j
= j
* mml
->height
/ texImage
->Height
;
847 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
853 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
854 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
856 GLchan
*rgba
= (GLchan
*) texelOut
;
857 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
858 const GLubyte
*texel
;
863 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
864 rgba
[RCOMP
] = texel
[0];
865 rgba
[GCOMP
] = texel
[0];
866 rgba
[BCOMP
] = texel
[0];
867 rgba
[ACOMP
] = texel
[1];
872 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
873 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
875 GLchan
*rgba
= (GLchan
*) texelOut
;
876 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
877 const GLushort
*texel
;
882 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
883 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
884 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
885 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
891 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
892 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
894 GLchan
*rgba
= (GLchan
*) texelOut
;
895 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
896 const GLushort
*texel
;
901 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
902 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
903 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
904 rgba
[BCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
905 rgba
[ACOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
910 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
911 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
913 GLchan
*rgba
= (GLchan
*) texelOut
;
914 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
915 const GLushort
*texel
;
920 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
921 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
922 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 6) & 0x1F];
923 rgba
[BCOMP
] = FX_rgb_scale_5
[(*texel
>> 1) & 0x1F];
924 rgba
[ACOMP
] = ((*texel
) & 0x01) * 255;
929 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
930 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
932 GLchan
*rgba
= (GLchan
*) texelOut
;
933 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
939 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
940 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
941 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
942 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
943 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
948 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
951 for (i
= 0; i
< h
; i
++) {
952 for (j
= 0; j
< w
; j
++) {
954 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
956 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
959 fprintf(stderr
, "\n");
964 const struct gl_texture_format
*
965 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
966 GLenum srcFormat
, GLenum srcType
)
968 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
969 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
971 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
972 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
975 switch (internalFormat
) {
981 case GL_COMPRESSED_INTENSITY
:
982 return &_mesa_texformat_i8
;
989 case GL_COMPRESSED_LUMINANCE
:
990 return &_mesa_texformat_l8
;
996 case GL_COMPRESSED_ALPHA
:
997 return &_mesa_texformat_a8
;
999 case GL_COLOR_INDEX1_EXT
:
1000 case GL_COLOR_INDEX2_EXT
:
1001 case GL_COLOR_INDEX4_EXT
:
1002 case GL_COLOR_INDEX8_EXT
:
1003 case GL_COLOR_INDEX12_EXT
:
1004 case GL_COLOR_INDEX16_EXT
:
1005 return &_mesa_texformat_ci8
;
1007 case GL_LUMINANCE_ALPHA
:
1008 case GL_LUMINANCE4_ALPHA4
:
1009 case GL_LUMINANCE6_ALPHA2
:
1010 case GL_LUMINANCE8_ALPHA8
:
1011 case GL_LUMINANCE12_ALPHA4
:
1012 case GL_LUMINANCE12_ALPHA12
:
1013 case GL_LUMINANCE16_ALPHA16
:
1014 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1015 return &_mesa_texformat_al88
;
1019 return &_mesa_texformat_rgb565
;
1022 case GL_COMPRESSED_RGB
:
1023 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1024 return &_mesa_texformat_rgb565
;
1026 /* intentional fall through */
1031 return (allow32bpt
) ? &_mesa_texformat_argb8888
1032 : &_mesa_texformat_rgb565
;
1035 return &_mesa_texformat_argb4444
;
1038 case GL_COMPRESSED_RGBA
:
1039 if ( srcFormat
== GL_BGRA
) {
1040 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1041 return &_mesa_texformat_argb8888
;
1043 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1044 return &_mesa_texformat_argb4444
;
1046 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1047 return &_mesa_texformat_argb1555
;
1050 /* intentional fall through */
1055 return (allow32bpt
) ? &_mesa_texformat_argb8888
1056 : &_mesa_texformat_argb4444
;
1058 return &_mesa_texformat_argb1555
;
1060 /* GL_EXT_texture_compression_s3tc */
1061 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1062 return &_mesa_texformat_rgb_dxt1
;
1063 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1064 return &_mesa_texformat_rgba_dxt1
;
1065 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1066 return &_mesa_texformat_rgba_dxt3
;
1067 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1068 return &_mesa_texformat_rgba_dxt5
;
1069 /*case GL_COMPRESSED_RGB_FXT1_3DFX:
1070 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1074 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1080 static GrTextureFormat_t
1081 fxGlideFormat(GLint mesaFormat
)
1083 switch (mesaFormat
) {
1084 case MESA_FORMAT_I8
:
1085 return GR_TEXFMT_ALPHA_8
;
1086 case MESA_FORMAT_A8
:
1087 return GR_TEXFMT_ALPHA_8
;
1088 case MESA_FORMAT_L8
:
1089 return GR_TEXFMT_INTENSITY_8
;
1090 case MESA_FORMAT_CI8
:
1091 return GR_TEXFMT_P_8
;
1092 case MESA_FORMAT_AL88
:
1093 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1094 case MESA_FORMAT_RGB565
:
1095 return GR_TEXFMT_RGB_565
;
1096 case MESA_FORMAT_ARGB4444
:
1097 return GR_TEXFMT_ARGB_4444
;
1098 case MESA_FORMAT_ARGB1555
:
1099 return GR_TEXFMT_ARGB_1555
;
1100 #if 1 /* [koolsmoky] getting ready for 32bpp textures */
1101 case MESA_FORMAT_ARGB8888
:
1102 return GR_TEXFMT_ARGB_8888
;
1105 case MESA_FORMAT_RGB_DXT1
:
1106 case MESA_FORMAT_RGBA_DXT1
:
1107 return GR_TEXFMT_ARGB_CMP_DXT1
;
1108 case MESA_FORMAT_RGBA_DXT3
:
1109 return GR_TEXFMT_ARGB_CMP_DXT3
;
1110 case MESA_FORMAT_RGBA_DXT5
:
1111 return GR_TEXFMT_ARGB_CMP_DXT5
;
1112 /*case MESA_FORMAT_ARGB_CMP_FXT1:
1113 return GR_TEXFMT_ARGB_CMP_FXT1;
1114 case MESA_FORMAT_RGB_CMP_FXT1:
1115 return GL_COMPRESSED_RGBA_FXT1_3DFX;*/
1118 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1124 static FetchTexelFunc
1125 fxFetchFunction(GLint mesaFormat
)
1127 switch (mesaFormat
) {
1128 case MESA_FORMAT_I8
:
1129 return fetch_intensity8
;
1130 case MESA_FORMAT_A8
:
1131 return fetch_alpha8
;
1132 case MESA_FORMAT_L8
:
1133 return fetch_luminance8
;
1134 case MESA_FORMAT_CI8
:
1135 return fetch_index8
;
1136 case MESA_FORMAT_AL88
:
1137 return fetch_luminance8_alpha8
;
1138 case MESA_FORMAT_RGB565
:
1139 return fetch_r5g6b5
;
1140 case MESA_FORMAT_ARGB4444
:
1141 return fetch_r4g4b4a4
;
1142 case MESA_FORMAT_ARGB1555
:
1143 return fetch_r5g5b5a1
;
1144 #if 1 /* [koolsmoky] getting ready for 32bpp textures */
1145 case MESA_FORMAT_ARGB8888
:
1146 return fetch_a8r8g8b8
;
1149 case MESA_FORMAT_RGB_DXT1
:
1150 case MESA_FORMAT_RGBA_DXT1
:
1151 case MESA_FORMAT_RGBA_DXT3
:
1152 case MESA_FORMAT_RGBA_DXT5
:
1153 return fetch_r4g4b4a4
;
1156 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1162 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1163 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1164 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1165 const struct gl_pixelstore_attrib
*packing
,
1166 struct gl_texture_object
*texObj
,
1167 struct gl_texture_image
*texImage
)
1169 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1171 tfxMipMapLevel
*mml
;
1174 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1175 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1176 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1177 texImage
->Width
, texImage
->Height
);
1180 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1181 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1185 if (!texObj
->DriverData
) {
1186 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1187 if (!texObj
->DriverData
) {
1188 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1192 ti
= fxTMGetTexInfo(texObj
);
1194 if (!texImage
->DriverData
) {
1195 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1196 if (!texImage
->DriverData
) {
1197 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1201 mml
= FX_MIPMAP_DATA(texImage
);
1203 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1204 &mml
->wScale
, &mml
->hScale
);
1206 mml
->width
= width
* mml
->wScale
;
1207 mml
->height
= height
* mml
->hScale
;
1210 /* choose the texture format */
1211 assert(ctx
->Driver
.ChooseTextureFormat
);
1212 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1213 internalFormat
, format
, type
);
1214 assert(texImage
->TexFormat
);
1215 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1216 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1218 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1219 /* rescale image to overcome 1:8 aspect limitation */
1221 tempImage
= MALLOC(width
* height
* texelBytes
);
1223 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1226 /* unpack image, apply transfer ops and store in tempImage */
1227 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1228 texImage
->TexFormat
,
1230 width
, height
, 1, 0, 0, 0,
1232 0, /* dstImageStride */
1233 format
, type
, pixels
, packing
);
1234 assert(!texImage
->Data
);
1235 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1236 if (!texImage
->Data
) {
1237 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1241 _mesa_rescale_teximage2d(texelBytes
,
1242 mml
->width
* texelBytes
, /* dst stride */
1244 mml
->width
, mml
->height
,
1245 tempImage
/*src*/, texImage
->Data
/*dst*/ );
1249 /* no rescaling needed */
1250 assert(!texImage
->Data
);
1251 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1252 if (!texImage
->Data
) {
1253 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1256 /* unpack image, apply transfer ops and store in texImage->Data */
1257 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1258 texImage
->TexFormat
, texImage
->Data
,
1259 width
, height
, 1, 0, 0, 0,
1260 texImage
->Width
* texelBytes
,
1261 0, /* dstImageStride */
1262 format
, type
, pixels
, packing
);
1265 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1266 ti
->info
.format
= mml
->glideFormat
;
1267 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1270 * Hack alert: unsure...
1272 if (!(fxMesa
->new_state
& FX_NEW_TEXTURING
) && ti
->validated
&& ti
->isInTM
) {
1273 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1274 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1277 /*fprintf(stderr, "invalidate2\n"); */
1278 fxTexInvalidate(ctx
, texObj
);
1284 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1285 GLint xoffset
, GLint yoffset
,
1286 GLsizei width
, GLsizei height
,
1287 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1288 const struct gl_pixelstore_attrib
*packing
,
1289 struct gl_texture_object
*texObj
,
1290 struct gl_texture_image
*texImage
)
1292 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1294 tfxMipMapLevel
*mml
;
1297 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1298 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1301 if (!texObj
->DriverData
) {
1302 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1306 ti
= fxTMGetTexInfo(texObj
);
1308 mml
= FX_MIPMAP_DATA(texImage
);
1311 assert(texImage
->Data
); /* must have an existing texture image! */
1312 assert(texImage
->Format
);
1314 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1316 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1317 /* need to rescale subimage to match mipmap level's rescale factors */
1318 const GLint newWidth
= width
* mml
->wScale
;
1319 const GLint newHeight
= height
* mml
->hScale
;
1322 tempImage
= MALLOC(width
* height
* texelBytes
);
1324 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1328 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,/* Tex int format */
1329 texImage
->TexFormat
, /* dest format */
1330 (GLubyte
*) tempImage
, /* dest */
1331 width
, height
, 1, /* subimage size */
1332 0, 0, 0, /* subimage pos */
1333 width
* texelBytes
, /* dest row stride */
1334 0, /* dst image stride */
1335 format
, type
, pixels
, packing
);
1338 /* compute address of dest subimage within the overal tex image */
1339 destAddr
= (GLubyte
*) texImage
->Data
1340 + (yoffset
* mml
->hScale
* mml
->width
1341 + xoffset
* mml
->wScale
) * texelBytes
;
1343 _mesa_rescale_teximage2d(texelBytes
,
1344 mml
->width
* texelBytes
, /* dst stride */
1346 newWidth
, newHeight
,
1347 tempImage
, destAddr
);
1352 /* no rescaling needed */
1353 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
, /* Tex int format */
1354 texImage
->TexFormat
, /* dest format */
1355 (GLubyte
*) texImage
->Data
,/* dest */
1356 width
, height
, 1, /* subimage size */
1357 xoffset
, yoffset
, 0, /* subimage pos */
1358 mml
->width
* texelBytes
, /* dest row stride */
1359 0, /* dst image stride */
1360 format
, type
, pixels
, packing
);
1364 * Hack alert: unsure...
1366 if (!(fxMesa
->new_state
& FX_NEW_TEXTURING
) && ti
->validated
&& ti
->isInTM
)
1367 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1369 fxTexInvalidate(ctx
, texObj
);
1376 * Need this to provide at least one external definition.
1379 extern int gl_fx_dummy_function_ddtex(void);
1381 gl_fx_dummy_function_ddtex(void)