2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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 shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45 #include "texformat.h"
51 fxPrintTextureData(tfxTexInfo
* ti
)
53 fprintf(stderr
, "Texture Data:\n");
55 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
56 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
57 fprintf(stderr
, "\tSize: %d x %d\n",
58 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Width
,
59 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Height
);
62 fprintf(stderr
, "\tName: UNNAMED\n");
63 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
64 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
65 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
67 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
68 (unsigned) ti
->tm
[0]->endAddr
);
70 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
71 (unsigned) ti
->tm
[1]->endAddr
);
72 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
73 fprintf(stderr
, "\tFilters: min %d min %d\n",
74 (int) ti
->minFilt
, (int) ti
->maxFilt
);
75 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
77 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
78 fprintf(stderr
, "\t%s\n",
79 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
80 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
84 /************************************************************************/
85 /*************************** Texture Mapping ****************************/
86 /************************************************************************/
89 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
91 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
94 ti
= fxTMGetTexInfo(tObj
);
96 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
98 ti
->validated
= GL_FALSE
;
99 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
103 fxAllocTexObjData(fxMesaContext fxMesa
)
107 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
108 fprintf(stderr
, "%s: ERROR: out of memory !\n", __FUNCTION__
);
113 ti
->validated
= GL_FALSE
;
114 ti
->isInTM
= GL_FALSE
;
116 ti
->whichTMU
= FX_TMU_NONE
;
118 ti
->tm
[FX_TMU0
] = NULL
;
119 ti
->tm
[FX_TMU1
] = NULL
;
121 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
122 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
124 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
125 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
127 ti
->mmMode
= GR_MIPMAP_NEAREST
;
128 ti
->LODblend
= FXFALSE
;
134 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
136 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
139 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
140 fprintf(stderr
, "%s(%d, %x)\n", __FUNCTION__
, tObj
->Name
,
141 (GLuint
) tObj
->DriverData
);
144 if (target
!= GL_TEXTURE_2D
)
147 if (!tObj
->DriverData
) {
148 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
151 ti
= fxTMGetTexInfo(tObj
);
153 fxMesa
->texBindNumber
++;
154 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
156 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
160 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
161 const GLfloat
* param
)
163 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
165 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
167 fprintf(stderr
, "%s(%x, %x)\n", __FUNCTION__
, pname
, (GLint
) (*param
));
169 fprintf(stderr
, "%s(%x)\n", __FUNCTION__
, pname
);
172 /* apply any lod biasing right now */
173 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
174 grTexLodBiasValue(GR_TMU0
, *param
);
176 if (fxMesa
->haveTwoTMUs
) {
177 grTexLodBiasValue(GR_TMU1
, *param
);
182 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
186 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
187 GLenum pname
, const GLfloat
* params
)
189 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
190 GLenum param
= (GLenum
) (GLint
) params
[0];
193 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
194 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
195 tObj
->Name
, (GLuint
) tObj
->DriverData
,
196 _mesa_lookup_enum_by_nr(pname
),
197 _mesa_lookup_enum_by_nr(param
));
200 if (target
!= GL_TEXTURE_2D
)
203 if (!tObj
->DriverData
)
204 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
206 ti
= fxTMGetTexInfo(tObj
);
210 case GL_TEXTURE_MIN_FILTER
:
213 ti
->mmMode
= GR_MIPMAP_DISABLE
;
214 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
215 ti
->LODblend
= FXFALSE
;
218 ti
->mmMode
= GR_MIPMAP_DISABLE
;
219 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
220 ti
->LODblend
= FXFALSE
;
222 case GL_NEAREST_MIPMAP_LINEAR
:
223 if (fxMesa
->haveTwoTMUs
) {
224 ti
->mmMode
= GR_MIPMAP_NEAREST
;
225 ti
->LODblend
= FXTRUE
;
228 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
229 ti
->LODblend
= FXFALSE
;
231 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
232 break; /* ZZZ: we may have to fall through here for V3 */
233 case GL_NEAREST_MIPMAP_NEAREST
:
234 ti
->mmMode
= GR_MIPMAP_NEAREST
;
235 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
236 ti
->LODblend
= FXFALSE
;
238 case GL_LINEAR_MIPMAP_LINEAR
:
239 /* ZZZ: HACK ALERT! trilinear is bugged! mipmap blending produce
240 incorrect filtered colors for the smallest mipmap levels. */
242 if (fxMesa
->haveTwoTMUs
) {
243 ti
->mmMode
= GR_MIPMAP_NEAREST
;
244 ti
->LODblend
= FXTRUE
;
247 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
248 ti
->LODblend
= FXFALSE
;
250 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
251 break; /* ZZZ: we may have to fall through here for V3 */
253 case GL_LINEAR_MIPMAP_NEAREST
:
254 ti
->mmMode
= GR_MIPMAP_NEAREST
;
255 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
256 ti
->LODblend
= FXFALSE
;
261 fxTexInvalidate(ctx
, tObj
);
264 case GL_TEXTURE_MAG_FILTER
:
267 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
270 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
275 fxTexInvalidate(ctx
, tObj
);
278 case GL_TEXTURE_WRAP_S
:
280 case GL_MIRRORED_REPEAT
:
281 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
283 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
285 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
288 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
293 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
296 case GL_TEXTURE_WRAP_T
:
298 case GL_MIRRORED_REPEAT
:
299 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
301 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
303 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
306 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
311 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
314 case GL_TEXTURE_BORDER_COLOR
:
318 case GL_TEXTURE_MIN_LOD
:
321 case GL_TEXTURE_MAX_LOD
:
324 case GL_TEXTURE_BASE_LEVEL
:
325 fxTexInvalidate(ctx
, tObj
);
327 case GL_TEXTURE_MAX_LEVEL
:
328 fxTexInvalidate(ctx
, tObj
);
337 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
339 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
340 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
342 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
343 fprintf(stderr
, "%s(%d, %p)\n", __FUNCTION__
, tObj
->Name
, (void *) ti
);
349 fxTMFreeTexture(fxMesa
, tObj
);
352 tObj
->DriverData
= NULL
;
356 * Return true if texture is resident, false otherwise.
359 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
361 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
362 return (ti
&& ti
->isInTM
);
368 * Convert a gl_color_table texture palette to Glide's format.
371 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
373 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
374 GLint width
= table
->Size
;
378 ASSERT(!table
->FloatTable
);
380 switch (table
->Format
) {
382 for (i
= 0; i
< width
; i
++) {
387 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
389 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
391 for (i
= 0; i
< width
; i
++) {
396 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
398 return GR_TEXTABLE_PALETTE
;
400 for (i
= 0; i
< width
; i
++) {
403 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
405 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
406 case GL_LUMINANCE_ALPHA
:
407 for (i
= 0; i
< width
; i
++) {
408 r
= g
= b
= tableUB
[i
* 2 + 0];
409 a
= tableUB
[i
* 2 + 1];
410 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
412 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
415 for (i
= 0; i
< width
; i
++) {
416 r
= tableUB
[i
* 3 + 0];
417 g
= tableUB
[i
* 3 + 1];
418 b
= tableUB
[i
* 3 + 2];
420 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
422 return GR_TEXTABLE_PALETTE
;
424 for (i
= 0; i
< width
; i
++) {
425 r
= tableUB
[i
* 4 + 0];
426 g
= tableUB
[i
* 4 + 1];
427 b
= tableUB
[i
* 4 + 2];
428 a
= tableUB
[i
* 4 + 3];
429 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
431 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
437 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
439 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
442 /* per-texture palette */
444 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
445 fprintf(stderr
, "%s(%d, %x)\n", __FUNCTION__
,
446 tObj
->Name
, (GLuint
) tObj
->DriverData
);
448 if (!tObj
->DriverData
)
449 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
450 ti
= fxTMGetTexInfo(tObj
);
451 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
452 fxTexInvalidate(ctx
, tObj
);
455 /* global texture palette */
456 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
457 fprintf(stderr
, "%s(global)\n", __FUNCTION__
);
459 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
460 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
466 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
468 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
470 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
471 fprintf(stderr
, "%s(%d)\n", __FUNCTION__
, state
);
475 fxMesa
->haveGlobalPaletteTexture
= 1;
477 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
480 fxMesa
->haveGlobalPaletteTexture
= 0;
482 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
483 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
484 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
486 if (!tObj
->DriverData
)
487 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
489 fxTexInvalidate(ctx
, tObj
);
519 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
520 float *sscale
, float *tscale
,
521 int *wscale
, int *hscale
)
523 static GrLOD_t lod
[12] = {
538 int logw
, logh
, ws
, hs
;
540 GrAspectRatio_t aspectratio
;
546 switch (logw
- logh
) {
548 aspectratio
= GR_ASPECT_LOG2_1x1
;
554 aspectratio
= GR_ASPECT_LOG2_2x1
;
562 aspectratio
= GR_ASPECT_LOG2_4x1
;
570 aspectratio
= GR_ASPECT_LOG2_8x1
;
578 aspectratio
= GR_ASPECT_LOG2_1x2
;
586 aspectratio
= GR_ASPECT_LOG2_1x4
;
594 aspectratio
= GR_ASPECT_LOG2_1x8
;
602 if ((logw
- logh
) > 3) {
603 aspectratio
= GR_ASPECT_LOG2_8x1
;
608 hs
= 1 << (logw
- logh
- 3);
609 } else /*if ((logw - logh) < -3)*/ {
610 aspectratio
= GR_ASPECT_LOG2_1x8
;
614 ws
= 1 << (logh
- logw
- 3);
642 fxIsTexSupported(GLenum target
, GLint internalFormat
,
643 const struct gl_texture_image
*image
)
645 if (target
!= GL_TEXTURE_2D
)
648 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
651 if (image
->Border
> 0)
658 /**********************************************************************/
659 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
660 /**********************************************************************/
662 /* Texel-fetch functions for software texturing and glGetTexImage().
663 * We should have been able to use some "standard" fetch functions (which
664 * may get defined in texutil.c) but we have to account for scaled texture
665 * images on tdfx hardware (the 8:1 aspect ratio limit).
666 * Hence, we need special functions here.
670 fetch_intensity8(const struct gl_texture_image
*texImage
,
671 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
673 GLchan
*rgba
= (GLchan
*) texelOut
;
674 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
675 const GLubyte
*texel
;
680 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
681 rgba
[RCOMP
] = *texel
;
682 rgba
[GCOMP
] = *texel
;
683 rgba
[BCOMP
] = *texel
;
684 rgba
[ACOMP
] = *texel
;
689 fetch_luminance8(const struct gl_texture_image
*texImage
,
690 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
692 GLchan
*rgba
= (GLchan
*) texelOut
;
693 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
694 const GLubyte
*texel
;
699 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
700 rgba
[RCOMP
] = *texel
;
701 rgba
[GCOMP
] = *texel
;
702 rgba
[BCOMP
] = *texel
;
708 fetch_alpha8(const struct gl_texture_image
*texImage
,
709 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
711 GLchan
*rgba
= (GLchan
*) texelOut
;
712 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
713 const GLubyte
*texel
;
717 /* [dBorca] why, oh... why? */
718 i
= i
* mml
->width
/ texImage
->Width
;
719 j
= j
* mml
->height
/ texImage
->Height
;
721 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
725 rgba
[ACOMP
] = *texel
;
730 fetch_index8(const struct gl_texture_image
*texImage
,
731 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
733 GLchan
*indexOut
= (GLchan
*) texelOut
;
734 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
735 const GLubyte
*texel
;
739 /* [dBorca] why, oh... why? */
740 i
= i
* mml
->width
/ texImage
->Width
;
741 j
= j
* mml
->height
/ texImage
->Height
;
743 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
749 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
750 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
752 GLchan
*rgba
= (GLchan
*) texelOut
;
753 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
754 const GLubyte
*texel
;
759 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
760 rgba
[RCOMP
] = texel
[0];
761 rgba
[GCOMP
] = texel
[0];
762 rgba
[BCOMP
] = texel
[0];
763 rgba
[ACOMP
] = texel
[1];
768 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
769 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
771 GLchan
*rgba
= (GLchan
*) texelOut
;
772 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
773 const GLushort
*texel
;
778 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
779 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
780 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
781 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
787 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
788 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
790 GLchan
*rgba
= (GLchan
*) texelOut
;
791 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
792 const GLushort
*texel
;
797 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
798 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
799 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
800 rgba
[BCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
801 rgba
[ACOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
806 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
807 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
809 GLchan
*rgba
= (GLchan
*) texelOut
;
810 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
811 const GLushort
*texel
;
816 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
817 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
818 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 6) & 0x1F];
819 rgba
[BCOMP
] = FX_rgb_scale_5
[(*texel
>> 1) & 0x1F];
820 rgba
[ACOMP
] = ((*texel
) & 0x01) * 255;
825 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
826 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
828 GLchan
*rgba
= (GLchan
*) texelOut
;
829 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
835 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
836 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
837 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
838 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
839 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
844 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
847 for (i
= 0; i
< h
; i
++) {
848 for (j
= 0; j
< w
; j
++) {
850 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
852 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
855 fprintf(stderr
, "\n");
860 GLboolean
fxDDIsCompressedFormat ( GLcontext
*ctx
, GLenum internalFormat
)
862 if ((internalFormat
== GL_COMPRESSED_RGB_FXT1_3DFX
) ||
863 (internalFormat
== GL_COMPRESSED_RGBA_FXT1_3DFX
) ||
864 (internalFormat
== GL_COMPRESSED_RGB_S3TC_DXT1_EXT
) ||
865 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
) ||
866 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
) ||
867 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)) {
872 * we are handling differently the above formats from the generic
873 * GL_COMPRESSED_RGB[A]. For this, we will always separately
874 * check for the ones below!
877 #if FX_TC_NCC || FX_TC_NAPALM
878 if ((internalFormat
== GL_COMPRESSED_RGB
) || (internalFormat
== GL_COMPRESSED_RGBA
)) {
887 GLuint
fxDDCompressedTextureSize (GLcontext
*ctx
,
888 GLsizei width
, GLsizei height
, GLsizei depth
,
896 /* Determine width and height scale factors for texture.
897 * Remember, Glide is limited to 8:1 aspect ratios.
899 fxTexGetInfo(width
, height
,
900 NULL
, /* lod level */
901 NULL
, /* aspect ratio */
902 NULL
, NULL
, /* sscale, tscale */
909 case GL_COMPRESSED_RGB_FXT1_3DFX
:
910 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
911 /* round up to multiple of 4 */
912 size
= ((width
+ 7) / 8) * ((height
+ 3) / 4) * 16;
913 /* Textures smaller than 4x4 will effectively be made into 4x4 and
919 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
920 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
921 /* round up width, height to next multiple of 4 */
922 width
= (width
+ 3) & ~3;
923 height
= (height
+ 3) & ~3;
924 /* 8 bytes per 4x4 tile of RGB[A] texels */
925 size
= (width
* height
* 8) / 16;
926 /* Textures smaller than 4x4 will effectively be made into 4x4 and
932 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
933 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
934 /* round up width, height to next multiple of 4 */
935 width
= (width
+ 3) & ~3;
936 height
= (height
+ 3) & ~3;
937 /* 16 bytes per 4x4 tile of RGBA texels */
938 size
= width
* height
; /* simple! */
939 /* Textures smaller than 4x4 will effectively be made into 4x4 and
945 case GL_COMPRESSED_RGB
:
948 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
949 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
950 return fxDDCompressedTextureSize(ctx
, width
, height
, 1, GL_COMPRESSED_RGB_FXT1_3DFX
);
955 return (width
* height
* 8 >> 3) + 12 * 4;
957 case GL_COMPRESSED_RGBA
:
960 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
961 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
962 return fxDDCompressedTextureSize(ctx
, width
, height
, 1, GL_COMPRESSED_RGBA_FXT1_3DFX
);
967 return (width
* height
* 16 >> 3) + 12 * 4;
970 _mesa_problem(ctx
, "bad texformat in fxDDCompressedTextureSize");
976 const struct gl_texture_format
*
977 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
978 GLenum srcFormat
, GLenum srcType
)
980 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
981 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
983 /* [dBorca] Hack alert:
984 * There is something wrong with this!!! Take an example:
985 * 1) start HW rendering
986 * 2) create a texture like this:
987 * glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
988 * GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
989 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
990 * 3) we get here with internalFormat==3 and return either
991 * _mesa_texformat_rgb565 or _mesa_texformat_argb8888
992 * 4) at some point, we encounter total rasterization fallback
993 * 5) displaying a polygon with the above textures yield garbage on areas
994 * where pixel is larger than a texel, because our already set texel
995 * function doesn't match the real _mesa_texformat_argb888
998 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
999 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
1002 switch (internalFormat
) {
1006 case GL_INTENSITY12
:
1007 case GL_INTENSITY16
:
1008 case GL_COMPRESSED_INTENSITY
:
1009 return &_mesa_texformat_i8
;
1014 case GL_LUMINANCE12
:
1015 case GL_LUMINANCE16
:
1016 case GL_COMPRESSED_LUMINANCE
:
1017 return &_mesa_texformat_l8
;
1023 case GL_COMPRESSED_ALPHA
:
1024 return &_mesa_texformat_a8
;
1025 case GL_COLOR_INDEX
:
1026 case GL_COLOR_INDEX1_EXT
:
1027 case GL_COLOR_INDEX2_EXT
:
1028 case GL_COLOR_INDEX4_EXT
:
1029 case GL_COLOR_INDEX8_EXT
:
1030 case GL_COLOR_INDEX12_EXT
:
1031 case GL_COLOR_INDEX16_EXT
:
1032 return &_mesa_texformat_ci8
;
1034 case GL_LUMINANCE_ALPHA
:
1035 case GL_LUMINANCE4_ALPHA4
:
1036 case GL_LUMINANCE6_ALPHA2
:
1037 case GL_LUMINANCE8_ALPHA8
:
1038 case GL_LUMINANCE12_ALPHA4
:
1039 case GL_LUMINANCE12_ALPHA12
:
1040 case GL_LUMINANCE16_ALPHA16
:
1041 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1042 return &_mesa_texformat_al88
;
1046 return &_mesa_texformat_rgb565
;
1049 case GL_COMPRESSED_RGB
:
1050 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1051 return &_mesa_texformat_rgb565
;
1053 /* intentional fall through */
1058 return (allow32bpt
) ? &_mesa_texformat_argb8888
1059 : &_mesa_texformat_rgb565
;
1062 return &_mesa_texformat_argb4444
;
1065 case GL_COMPRESSED_RGBA
:
1066 if ( srcFormat
== GL_BGRA
) {
1067 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1068 return &_mesa_texformat_argb8888
;
1070 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1071 return &_mesa_texformat_argb4444
;
1073 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1074 return &_mesa_texformat_argb1555
;
1077 /* intentional fall through */
1082 return (allow32bpt
) ? &_mesa_texformat_argb8888
1083 : &_mesa_texformat_argb4444
;
1085 return &_mesa_texformat_argb1555
;
1086 /* GL_EXT_texture_compression_s3tc */
1087 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1088 return &_mesa_texformat_rgb_dxt1
;
1089 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1090 return &_mesa_texformat_rgba_dxt1
;
1091 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1092 return &_mesa_texformat_rgba_dxt3
;
1093 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1094 return &_mesa_texformat_rgba_dxt5
;
1095 /* GL_3DFX_texture_compression_FXT1 */
1096 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1097 return &_mesa_texformat_rgb_fxt1
;
1098 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1099 return &_mesa_texformat_rgba_fxt1
;
1101 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1107 static GrTextureFormat_t
1108 fxGlideFormat(GLint mesaFormat
)
1110 switch (mesaFormat
) {
1111 case MESA_FORMAT_I8
:
1112 return GR_TEXFMT_ALPHA_8
;
1113 case MESA_FORMAT_A8
:
1114 return GR_TEXFMT_ALPHA_8
;
1115 case MESA_FORMAT_L8
:
1116 return GR_TEXFMT_INTENSITY_8
;
1117 case MESA_FORMAT_CI8
:
1118 return GR_TEXFMT_P_8
;
1119 case MESA_FORMAT_AL88
:
1120 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1121 case MESA_FORMAT_RGB565
:
1122 return GR_TEXFMT_RGB_565
;
1123 case MESA_FORMAT_ARGB4444
:
1124 return GR_TEXFMT_ARGB_4444
;
1125 case MESA_FORMAT_ARGB1555
:
1126 return GR_TEXFMT_ARGB_1555
;
1127 case MESA_FORMAT_ARGB8888
:
1128 return GR_TEXFMT_ARGB_8888
;
1129 case MESA_FORMAT_RGB_FXT1
:
1130 case MESA_FORMAT_RGBA_FXT1
:
1131 return GR_TEXFMT_ARGB_CMP_FXT1
;
1132 case MESA_FORMAT_RGB_DXT1
:
1133 case MESA_FORMAT_RGBA_DXT1
:
1134 return GR_TEXFMT_ARGB_CMP_DXT1
;
1135 case MESA_FORMAT_RGBA_DXT3
:
1136 return GR_TEXFMT_ARGB_CMP_DXT3
;
1137 case MESA_FORMAT_RGBA_DXT5
:
1138 return GR_TEXFMT_ARGB_CMP_DXT5
;
1140 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1146 static FetchTexelFunc
1147 fxFetchFunction(GLint mesaFormat
)
1149 switch (mesaFormat
) {
1150 case MESA_FORMAT_I8
:
1151 return fetch_intensity8
;
1152 case MESA_FORMAT_A8
:
1153 return fetch_alpha8
;
1154 case MESA_FORMAT_L8
:
1155 return fetch_luminance8
;
1156 case MESA_FORMAT_CI8
:
1157 return fetch_index8
;
1158 case MESA_FORMAT_AL88
:
1159 return fetch_luminance8_alpha8
;
1160 case MESA_FORMAT_RGB565
:
1161 return fetch_r5g6b5
;
1162 case MESA_FORMAT_ARGB4444
:
1163 return fetch_r4g4b4a4
;
1164 case MESA_FORMAT_ARGB1555
:
1165 return fetch_r5g5b5a1
;
1166 case MESA_FORMAT_ARGB8888
:
1167 return fetch_a8r8g8b8
;
1168 case MESA_FORMAT_RGB_FXT1
:
1169 case MESA_FORMAT_RGBA_FXT1
:
1170 case MESA_FORMAT_RGB_DXT1
:
1171 case MESA_FORMAT_RGBA_DXT1
:
1172 case MESA_FORMAT_RGBA_DXT3
:
1173 case MESA_FORMAT_RGBA_DXT5
:
1174 return fetch_r4g4b4a4
;
1176 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1182 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1183 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1184 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1185 const struct gl_pixelstore_attrib
*packing
,
1186 struct gl_texture_object
*texObj
,
1187 struct gl_texture_image
*texImage
)
1189 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1191 tfxMipMapLevel
*mml
;
1194 GLvoid
*_final_texImage_Data
;
1195 const struct gl_texture_format
*_final_texImage_TexFormat
;
1197 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1198 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1199 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1200 texImage
->Width
, texImage
->Height
);
1203 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1204 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1208 if (!texObj
->DriverData
) {
1209 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1210 if (!texObj
->DriverData
) {
1211 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1215 ti
= fxTMGetTexInfo(texObj
);
1217 if (!texImage
->DriverData
) {
1218 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1219 if (!texImage
->DriverData
) {
1220 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1224 mml
= FX_MIPMAP_DATA(texImage
);
1226 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1227 &mml
->wScale
, &mml
->hScale
);
1229 mml
->width
= width
* mml
->wScale
;
1230 mml
->height
= height
* mml
->hScale
;
1233 /* choose the texture format */
1234 assert(ctx
->Driver
.ChooseTextureFormat
);
1235 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1236 internalFormat
, format
, type
);
1237 assert(texImage
->TexFormat
);
1238 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1239 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1241 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1242 /* dirty trick: will thrash CopyTex[Sub]Image */
1243 #if FX_TC_NCC || FX_TC_NAPALM
1244 if (internalFormat
== GL_COMPRESSED_RGB
) {
1246 mml
->glideFormat
= GR_TEXFMT_YIQ_422
;
1249 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1250 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1253 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1255 mml
->glideFormat
= GR_TEXFMT_AYIQ_8422
;
1258 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1259 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1265 /* allocate mipmap buffer */
1266 assert(!texImage
->Data
);
1267 if (texImage
->IsCompressed
) {
1268 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1270 _final_texImage_TexFormat
= &_mesa_texformat_argb8888
;
1271 _final_texImage_Data
= MALLOC(mml
->width
* mml
->height
* 4);
1272 if (!_final_texImage_Data
) {
1273 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1277 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1278 _final_texImage_TexFormat
= texImage
->TexFormat
;
1279 _final_texImage_Data
= texImage
->Data
;
1281 if (!texImage
->Data
) {
1282 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1286 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1287 /* rescale image to overcome 1:8 aspect limitation */
1289 tempImage
= MALLOC(width
* height
* texelBytes
);
1291 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1294 /* unpack image, apply transfer ops and store in tempImage */
1295 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1296 _final_texImage_TexFormat
,
1298 width
, height
, 1, 0, 0, 0,
1300 0, /* dstImageStride */
1301 format
, type
, pixels
, packing
);
1302 _mesa_rescale_teximage2d(texelBytes
,
1303 mml
->width
* texelBytes
, /* dst stride */
1305 mml
->width
, mml
->height
,
1306 tempImage
/*src*/, _final_texImage_Data
/*dst*/ );
1310 /* no rescaling needed */
1311 /* unpack image, apply transfer ops and store in texImage->Data */
1312 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1313 _final_texImage_TexFormat
, _final_texImage_Data
,
1314 width
, height
, 1, 0, 0, 0,
1315 texImage
->Width
* texelBytes
,
1316 0, /* dstImageStride */
1317 format
, type
, pixels
, packing
);
1321 if (texImage
->IsCompressed
) {
1323 if ((mml
->glideFormat
== GR_TEXFMT_AYIQ_8422
) ||
1324 (mml
->glideFormat
== GR_TEXFMT_YIQ_422
)) {
1326 txMip
.width
= mml
->width
;
1327 txMip
.height
= mml
->height
;
1329 txMip
.data
[0] = _final_texImage_Data
;
1330 pxMip
.data
[0] = texImage
->Data
;
1331 fxMesa
->Glide
.txMipQuantize(&pxMip
, &txMip
, mml
->glideFormat
, TX_DITHER_ERR
, TX_COMPRESSION_STATISTICAL
);
1332 fxMesa
->Glide
.txPalToNcc((GuNccTable
*)(&(ti
->palette
)), pxMip
.pal
);
1333 MEMCPY((char *)texImage
->Data
+ texImage
->CompressedSize
- 12 * 4, &(ti
->palette
), 12 * 4);
1336 fxMesa
->Glide
.txImgQuantize(texImage
->Data
, _final_texImage_Data
, mml
->width
, mml
->height
, mml
->glideFormat
, TX_DITHER_NONE
);
1337 FREE(_final_texImage_Data
);
1340 ti
->info
.format
= mml
->glideFormat
;
1341 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1344 * Hack alert: unsure...
1346 if (0 && ti
->validated
&& ti
->isInTM
) {
1347 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1348 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1351 /*fprintf(stderr, "invalidate2\n"); */
1352 fxTexInvalidate(ctx
, texObj
);
1358 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1359 GLint xoffset
, GLint yoffset
,
1360 GLsizei width
, GLsizei height
,
1361 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1362 const struct gl_pixelstore_attrib
*packing
,
1363 struct gl_texture_object
*texObj
,
1364 struct gl_texture_image
*texImage
)
1366 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1368 tfxMipMapLevel
*mml
;
1371 /* [dBorca] Hack alert:
1372 * fix the goddamn texture compression here
1375 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1376 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1379 if (!texObj
->DriverData
) {
1380 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1384 ti
= fxTMGetTexInfo(texObj
);
1386 mml
= FX_MIPMAP_DATA(texImage
);
1389 assert(texImage
->Data
); /* must have an existing texture image! */
1390 assert(texImage
->Format
);
1392 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1394 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1395 /* need to rescale subimage to match mipmap level's rescale factors */
1396 const GLint newWidth
= width
* mml
->wScale
;
1397 const GLint newHeight
= height
* mml
->hScale
;
1400 tempImage
= MALLOC(width
* height
* texelBytes
);
1402 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1406 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,/* Tex int format */
1407 texImage
->TexFormat
, /* dest format */
1408 (GLubyte
*) tempImage
, /* dest */
1409 width
, height
, 1, /* subimage size */
1410 0, 0, 0, /* subimage pos */
1411 width
* texelBytes
, /* dest row stride */
1412 0, /* dst image stride */
1413 format
, type
, pixels
, packing
);
1416 /* compute address of dest subimage within the overal tex image */
1417 destAddr
= (GLubyte
*) texImage
->Data
1418 + (yoffset
* mml
->hScale
* mml
->width
1419 + xoffset
* mml
->wScale
) * texelBytes
;
1421 _mesa_rescale_teximage2d(texelBytes
,
1422 mml
->width
* texelBytes
, /* dst stride */
1424 newWidth
, newHeight
,
1425 tempImage
, destAddr
);
1430 /* no rescaling needed */
1431 /* [dBorca] Hack alert: compute address of dest subimage within the overal tex image */
1432 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
, /* Tex int format */
1433 texImage
->TexFormat
, /* dest format */
1434 (GLubyte
*) texImage
->Data
,/* dest */
1435 width
, height
, 1, /* subimage size */
1436 xoffset
, yoffset
, 0, /* subimage pos */
1437 mml
->width
* texelBytes
, /* dest row stride */
1438 0, /* dst image stride */
1439 format
, type
, pixels
, packing
);
1443 * Hack alert: unsure...
1445 if (0 && ti
->validated
&& ti
->isInTM
)
1446 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1448 fxTexInvalidate(ctx
, texObj
);
1453 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1454 GLint level
, GLint internalFormat
,
1455 GLsizei width
, GLsizei height
, GLint border
,
1456 GLsizei imageSize
, const GLvoid
*data
,
1457 struct gl_texture_object
*texObj
,
1458 struct gl_texture_image
*texImage
)
1460 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1462 tfxMipMapLevel
*mml
;
1464 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1465 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1466 texObj
->Name
, internalFormat
,
1470 assert(texImage
->IsCompressed
);
1472 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1473 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1477 if (!texObj
->DriverData
) {
1478 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1479 if (!texObj
->DriverData
) {
1480 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1484 ti
= fxTMGetTexInfo(texObj
);
1486 if (!texImage
->DriverData
) {
1487 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1488 if (!texImage
->DriverData
) {
1489 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1493 mml
= FX_MIPMAP_DATA(texImage
);
1495 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1496 &mml
->wScale
, &mml
->hScale
);
1498 mml
->width
= width
* mml
->wScale
;
1499 mml
->height
= height
* mml
->hScale
;
1502 /* choose the texture format */
1503 assert(ctx
->Driver
.ChooseTextureFormat
);
1504 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1505 internalFormat
, format
, type
);
1506 assert(texImage
->TexFormat
);
1508 /* Determine the appropriate Glide texel format,
1509 * given the user's internal texture format hint.
1511 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1512 #if FX_TC_NCC || FX_TC_NAPALM
1513 if (internalFormat
== GL_COMPRESSED_RGB
) {
1515 mml
->glideFormat
= GR_TEXFMT_YIQ_422
;
1518 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1519 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1522 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1524 mml
->glideFormat
= GR_TEXFMT_AYIQ_8422
;
1527 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1528 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1534 /* allocate new storage for texture image, if needed */
1535 if (!texImage
->Data
) {
1536 texImage
->Data
= MESA_PBUFFER_ALLOC(imageSize
);
1537 if (!texImage
->Data
) {
1538 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1543 /* save the texture data */
1544 MEMCPY(texImage
->Data
, data
, imageSize
);
1546 if ((mml
->glideFormat
== GR_TEXFMT_AYIQ_8422
) ||
1547 (mml
->glideFormat
== GR_TEXFMT_YIQ_422
)) {
1548 MEMCPY(&(ti
->palette
), (char *)texImage
->Data
+ imageSize
- 12 * 4, 12 * 4);
1552 /* [dBorca] Hack alert:
1553 * what about different size/texel? other anomalies? SW rescaling?
1555 ti
->info
.format
= mml
->glideFormat
;
1556 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1559 * Hack alert: unsure...
1561 if (0 && ti
->validated
&& ti
->isInTM
) {
1562 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1563 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1566 /*fprintf(stderr, "invalidate2\n"); */
1567 fxTexInvalidate(ctx
, texObj
);
1573 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1574 GLint level
, GLint xoffset
,
1575 GLint yoffset
, GLsizei width
,
1576 GLint height
, GLenum format
,
1577 GLsizei imageSize
, const GLvoid
*data
,
1578 struct gl_texture_object
*texObj
,
1579 struct gl_texture_image
*texImage
)
1581 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1583 tfxMipMapLevel
*mml
;
1585 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1586 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1589 ti
= fxTMGetTexInfo(texObj
);
1591 mml
= FX_MIPMAP_DATA(texImage
);
1595 * We punt if we are not replacing the entire image. This
1596 * is allowed by the spec.
1598 * [dBorca] Hack alert:
1599 * ohwell, we should NOT! Look into _mesa_store_compressed_texsubimage2d
1600 * on how to calculate the sub-image.
1602 if ((xoffset
!= 0) && (yoffset
!= 0)
1603 && (width
!= texImage
->Width
)
1604 && (height
!= texImage
->Height
)) {
1605 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage2D(CHICKEN)");
1609 /* [dBorca] Hack alert:
1610 * what about different size/texel? other anomalies? SW rescaling?
1612 MEMCPY(texImage
->Data
, data
, imageSize
);
1615 * Hack alert: unsure...
1617 if (0 && ti
->validated
&& ti
->isInTM
)
1618 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1620 fxTexInvalidate(ctx
, texObj
);
1627 * Need this to provide at least one external definition.
1630 extern int gl_fx_dummy_function_ddtex(void);
1632 gl_fx_dummy_function_ddtex(void)