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
, "fxAllocTexObjData: ERROR: out of memory !\n");
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
, "fxDDTexBind(%d, %x)\n", tObj
->Name
, (GLuint
)tObj
->DriverData
);
143 if (target
!= GL_TEXTURE_2D
)
146 if (!tObj
->DriverData
) {
147 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
150 ti
= fxTMGetTexInfo(tObj
);
152 fxMesa
->texBindNumber
++;
153 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
155 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
159 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
160 const GLfloat
* param
)
162 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
164 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
166 fprintf(stderr
, "fxDDTexEnv(%x, %x)\n", pname
, (GLint
) (*param
));
168 fprintf(stderr
, "fxDDTexEnv(%x)\n", pname
);
171 /* apply any lod biasing right now */
172 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
173 grTexLodBiasValue(GR_TMU0
, *param
);
175 if (fxMesa
->haveTwoTMUs
) {
176 grTexLodBiasValue(GR_TMU1
, *param
);
181 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
185 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
186 GLenum pname
, const GLfloat
* params
)
188 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
189 GLenum param
= (GLenum
) (GLint
) params
[0];
192 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
193 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
194 tObj
->Name
, (GLuint
) tObj
->DriverData
,
195 _mesa_lookup_enum_by_nr(pname
),
196 _mesa_lookup_enum_by_nr(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 /* ZZZ: HACK ALERT! disable LODBlend, because we can't implement
223 on Napalm. Ohwell, until at least I decide what to do...
224 trilinear is bugged! mipmap blending produce
225 incorrect filtered colors for the smallest mipmap levels. */
227 if (fxMesa
->haveTwoTMUs
) {
228 ti
->mmMode
= GR_MIPMAP_NEAREST
;
229 ti
->LODblend
= FXTRUE
;
232 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
233 ti
->LODblend
= FXFALSE
;
235 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
236 break; /* ZZZ: we may have to fall through here for V3 */
238 case GL_NEAREST_MIPMAP_NEAREST
:
239 ti
->mmMode
= GR_MIPMAP_NEAREST
;
240 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
241 ti
->LODblend
= FXFALSE
;
243 case GL_LINEAR_MIPMAP_LINEAR
:
244 /* ZZZ: HACK ALERT! trilinear is bugged! mipmap blending produce
245 incorrect filtered colors for the smallest mipmap levels. */
247 if (fxMesa
->haveTwoTMUs
) {
248 ti
->mmMode
= GR_MIPMAP_NEAREST
;
249 ti
->LODblend
= FXTRUE
;
252 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
253 ti
->LODblend
= FXFALSE
;
255 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
256 break; /* ZZZ: we may have to fall through here for V3 */
258 case GL_LINEAR_MIPMAP_NEAREST
:
259 ti
->mmMode
= GR_MIPMAP_NEAREST
;
260 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
261 ti
->LODblend
= FXFALSE
;
266 fxTexInvalidate(ctx
, tObj
);
269 case GL_TEXTURE_MAG_FILTER
:
272 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
275 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
280 fxTexInvalidate(ctx
, tObj
);
283 case GL_TEXTURE_WRAP_S
:
285 case GL_MIRRORED_REPEAT
:
286 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
288 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
290 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
293 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
298 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
301 case GL_TEXTURE_WRAP_T
:
303 case GL_MIRRORED_REPEAT
:
304 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
306 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
308 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
311 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
316 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
319 case GL_TEXTURE_BORDER_COLOR
:
323 case GL_TEXTURE_MIN_LOD
:
326 case GL_TEXTURE_MAX_LOD
:
329 case GL_TEXTURE_BASE_LEVEL
:
330 fxTexInvalidate(ctx
, tObj
);
332 case GL_TEXTURE_MAX_LEVEL
:
333 fxTexInvalidate(ctx
, tObj
);
342 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
344 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
345 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
347 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
348 fprintf(stderr
, "fxDDTexDel(%d, %p)\n", tObj
->Name
, (void *) ti
);
354 fxTMFreeTexture(fxMesa
, tObj
);
357 tObj
->DriverData
= NULL
;
361 * Return true if texture is resident, false otherwise.
364 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
366 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
367 return (ti
&& ti
->isInTM
);
373 * Convert a gl_color_table texture palette to Glide's format.
376 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
378 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
379 GLint width
= table
->Size
;
383 ASSERT(!table
->FloatTable
);
385 switch (table
->Format
) {
387 for (i
= 0; i
< width
; i
++) {
392 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
394 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
396 for (i
= 0; i
< width
; i
++) {
401 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
403 return GR_TEXTABLE_PALETTE
;
405 for (i
= 0; i
< width
; i
++) {
408 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
410 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
411 case GL_LUMINANCE_ALPHA
:
412 for (i
= 0; i
< width
; i
++) {
413 r
= g
= b
= tableUB
[i
* 2 + 0];
414 a
= tableUB
[i
* 2 + 1];
415 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
417 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
420 for (i
= 0; i
< width
; i
++) {
421 r
= tableUB
[i
* 3 + 0];
422 g
= tableUB
[i
* 3 + 1];
423 b
= tableUB
[i
* 3 + 2];
425 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
427 return GR_TEXTABLE_PALETTE
;
429 for (i
= 0; i
< width
; i
++) {
430 r
= tableUB
[i
* 4 + 0];
431 g
= tableUB
[i
* 4 + 1];
432 b
= tableUB
[i
* 4 + 2];
433 a
= tableUB
[i
* 4 + 3];
434 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
436 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
442 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
444 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
447 /* per-texture palette */
449 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
450 fprintf(stderr
, "fxDDTexPalette(%d, %x)\n",
451 tObj
->Name
, (GLuint
) tObj
->DriverData
);
453 if (!tObj
->DriverData
)
454 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
455 ti
= fxTMGetTexInfo(tObj
);
456 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
457 fxTexInvalidate(ctx
, tObj
);
460 /* global texture palette */
461 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
462 fprintf(stderr
, "fxDDTexPalette(global)\n");
464 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
465 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
467 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
473 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
475 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
477 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
478 fprintf(stderr
, "fxDDTexUseGlbPalette(%d)\n", state
);
482 fxMesa
->haveGlobalPaletteTexture
= 1;
485 fxMesa
->haveGlobalPaletteTexture
= 0;
487 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
488 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
489 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
491 if (!tObj
->DriverData
)
492 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
494 fxTexInvalidate(ctx
, tObj
);
524 * w, h - source texture width and height
525 * lodlevel - Glide lod level token for the larger texture dimension
526 * ar - Glide aspect ratio token
527 * sscale - S scale factor used during triangle setup
528 * tscale - T scale factor used during triangle setup
529 * wscale - OpenGL -> Glide image width scale factor
530 * hscale - OpenGL -> Glide image height scale factor
533 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
534 float *sscale
, float *tscale
,
535 int *wscale
, int *hscale
)
537 int logw
, logh
, ws
, hs
;
539 GrAspectRatio_t aspectratio
;
545 l
= MAX2(logw
, logh
);
546 aspectratio
= logw
- logh
;
549 /* hardware only allows a maximum aspect ratio of 8x1, so handle
550 * |aspectratio| > 3 by scaling the image and using an 8x1 aspect
553 switch (aspectratio
) {
583 if (aspectratio
> 3) {
587 hs
= 1 << (aspectratio
- 3);
588 aspectratio
= GR_ASPECT_LOG2_8x1
;
589 } else /*if (aspectratio < -3)*/ {
592 ws
= 1 << (-aspectratio
- 3);
594 aspectratio
= GR_ASPECT_LOG2_1x8
;
621 fxIsTexSupported(GLenum target
, GLint internalFormat
,
622 const struct gl_texture_image
*image
)
624 if (target
!= GL_TEXTURE_2D
)
628 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
632 if (image
->Border
> 0)
639 /**********************************************************************/
640 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
641 /**********************************************************************/
643 /* Texel-fetch functions for software texturing and glGetTexImage().
644 * We should have been able to use some "standard" fetch functions (which
645 * may get defined in texutil.c) but we have to account for scaled texture
646 * images on tdfx hardware (the 8:1 aspect ratio limit).
647 * Hence, we need special functions here.
651 fetch_intensity8(const struct gl_texture_image
*texImage
,
652 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
654 GLchan
*rgba
= (GLchan
*) texelOut
;
655 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
656 const GLubyte
*texel
;
661 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
662 rgba
[RCOMP
] = *texel
;
663 rgba
[GCOMP
] = *texel
;
664 rgba
[BCOMP
] = *texel
;
665 rgba
[ACOMP
] = *texel
;
670 fetch_luminance8(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
;
689 fetch_alpha8(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
;
703 rgba
[ACOMP
] = *texel
;
708 fetch_index8(const struct gl_texture_image
*texImage
,
709 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
711 GLchan
*indexOut
= (GLchan
*) texelOut
;
712 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
713 const GLubyte
*texel
;
718 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
724 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
725 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
727 GLchan
*rgba
= (GLchan
*) texelOut
;
728 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
729 const GLubyte
*texel
;
734 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
735 rgba
[RCOMP
] = texel
[0];
736 rgba
[GCOMP
] = texel
[0];
737 rgba
[BCOMP
] = texel
[0];
738 rgba
[ACOMP
] = texel
[1];
743 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
744 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
746 GLchan
*rgba
= (GLchan
*) texelOut
;
747 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
748 const GLushort
*texel
;
753 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
754 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
755 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
756 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
762 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
763 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
765 GLchan
*rgba
= (GLchan
*) texelOut
;
766 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
767 const GLushort
*texel
;
772 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
773 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
774 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
775 rgba
[BCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
776 rgba
[ACOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
781 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
782 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
784 GLchan
*rgba
= (GLchan
*) texelOut
;
785 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
786 const GLushort
*texel
;
791 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
792 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
793 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 6) & 0x1F];
794 rgba
[BCOMP
] = FX_rgb_scale_5
[(*texel
>> 1) & 0x1F];
795 rgba
[ACOMP
] = ((*texel
) & 0x01) * 255;
800 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
801 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
803 GLchan
*rgba
= (GLchan
*) texelOut
;
804 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
810 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
811 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
812 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
813 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
814 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
819 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
822 for (i
= 0; i
< h
; i
++) {
823 for (j
= 0; j
< w
; j
++) {
825 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
827 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
830 fprintf(stderr
, "\n");
835 GLboolean
fxDDIsCompressedFormat ( GLcontext
*ctx
, GLenum internalFormat
)
837 if ((internalFormat
== GL_COMPRESSED_RGB_FXT1_3DFX
) ||
838 (internalFormat
== GL_COMPRESSED_RGBA_FXT1_3DFX
) ||
839 (internalFormat
== GL_COMPRESSED_RGB_S3TC_DXT1_EXT
) ||
840 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
) ||
841 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
) ||
842 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
) ||
843 (internalFormat
== GL_RGB_S3TC
) ||
844 (internalFormat
== GL_RGB4_S3TC
) ||
845 (internalFormat
== GL_RGBA_S3TC
) ||
846 (internalFormat
== GL_RGBA4_S3TC
)) {
851 * we are handling differently the above formats from the generic
852 * GL_COMPRESSED_RGB[A]. For this, we will always have to separately
853 * check for the ones below!
856 #if FX_TC_NCC || FX_TC_NAPALM
857 if ((internalFormat
== GL_COMPRESSED_RGB
) || (internalFormat
== GL_COMPRESSED_RGBA
)) {
866 GLuint
fxDDCompressedTextureSize (GLcontext
*ctx
,
867 GLsizei width
, GLsizei height
, GLsizei depth
,
875 /* Determine width and height scale factors for texture.
876 * Remember, Glide is limited to 8:1 aspect ratios.
878 fxTexGetInfo(width
, height
,
879 NULL
, /* lod level */
880 NULL
, /* aspect ratio */
881 NULL
, NULL
, /* sscale, tscale */
888 case GL_COMPRESSED_RGB_FXT1_3DFX
:
889 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
890 /* round up width to next multiple of 8, height to next multiple of 4 */
891 width
= (width
+ 7) & ~7;
892 height
= (height
+ 3) & ~3;
893 /* 16 bytes per 8x4 tile of RGB[A] texels */
894 size
= width
* height
/ 2;
895 /* Textures smaller than 8x4 will effectively be made into 8x4 and
901 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
902 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
905 /* round up width, height to next multiple of 4 */
906 width
= (width
+ 3) & ~3;
907 height
= (height
+ 3) & ~3;
908 /* 8 bytes per 4x4 tile of RGB[A] texels */
909 size
= width
* height
/ 2;
910 /* Textures smaller than 4x4 will effectively be made into 4x4 and
916 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
917 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
920 /* round up width, height to next multiple of 4 */
921 width
= (width
+ 3) & ~3;
922 height
= (height
+ 3) & ~3;
923 /* 16 bytes per 4x4 tile of RGBA texels */
924 size
= width
* height
; /* simple! */
925 /* Textures smaller than 4x4 will effectively be made into 4x4 and
931 case GL_COMPRESSED_RGB
:
934 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
935 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
936 return fxDDCompressedTextureSize(ctx
, width
, height
, 1, GL_COMPRESSED_RGB_FXT1_3DFX
);
941 return (width
* height
* 8 >> 3) + 12 * 4;
943 case GL_COMPRESSED_RGBA
:
946 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
947 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
948 return fxDDCompressedTextureSize(ctx
, width
, height
, 1, GL_COMPRESSED_RGBA_FXT1_3DFX
);
953 return (width
* height
* 16 >> 3) + 12 * 4;
956 _mesa_problem(ctx
, "bad texformat in fxDDCompressedTextureSize");
962 const struct gl_texture_format
*
963 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
964 GLenum srcFormat
, GLenum srcType
)
966 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
967 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
969 /* [dBorca] Hack alert:
970 * There is something wrong with this!!! Take an example:
971 * 1) start HW rendering
972 * 2) create a texture like this:
973 * glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
974 * GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
975 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
976 * 3) we get here with internalFormat==3 and return either
977 * _mesa_texformat_rgb565 or _mesa_texformat_argb8888
978 * 4) at some point, we encounter total rasterization fallback
979 * 5) displaying a polygon with the above textures yield garbage on areas
980 * where pixel is larger than a texel, because our already set texel
981 * function doesn't match the real _mesa_texformat_argb888
984 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
985 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
988 switch (internalFormat
) {
989 case GL_COMPRESSED_RGB
:
990 #if 0 && FX_TC_NAPALM /* [koolsmoky] */
991 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
) {
992 return &_mesa_texformat_rgb_fxt1
;
993 } else if (ctx
->Extensions
.EXT_texture_compression_s3tc
) {
994 return &_mesa_texformat_rgb_dxt1
;
997 /* intentional fall through */
1000 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1001 return &_mesa_texformat_rgb565
;
1003 /* intentional fall through */
1008 return (allow32bpt
) ? &_mesa_texformat_argb8888
1009 : &_mesa_texformat_rgb565
;
1012 return &_mesa_texformat_argb4444
;
1013 case GL_COMPRESSED_RGBA
:
1014 #if 0 && FX_TC_NAPALM /* [koolsmoky] */
1015 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
) {
1016 return &_mesa_texformat_rgba_fxt1
;
1017 } else if (ctx
->Extensions
.EXT_texture_compression_s3tc
) {
1018 return &_mesa_texformat_rgba_dxt3
;
1021 /* intentional fall through */
1024 if ( srcFormat
== GL_BGRA
) {
1025 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1026 return &_mesa_texformat_argb8888
;
1028 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1029 return &_mesa_texformat_argb4444
;
1031 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1032 return &_mesa_texformat_argb1555
;
1035 /* intentional fall through */
1040 return (allow32bpt
) ? &_mesa_texformat_argb8888
1041 : &_mesa_texformat_argb4444
;
1045 case GL_INTENSITY12
:
1046 case GL_INTENSITY16
:
1047 case GL_COMPRESSED_INTENSITY
:
1048 return &_mesa_texformat_i8
;
1053 case GL_LUMINANCE12
:
1054 case GL_LUMINANCE16
:
1055 case GL_COMPRESSED_LUMINANCE
:
1056 return &_mesa_texformat_l8
;
1062 case GL_COMPRESSED_ALPHA
:
1063 return &_mesa_texformat_a8
;
1064 case GL_COLOR_INDEX
:
1065 case GL_COLOR_INDEX1_EXT
:
1066 case GL_COLOR_INDEX2_EXT
:
1067 case GL_COLOR_INDEX4_EXT
:
1068 case GL_COLOR_INDEX8_EXT
:
1069 case GL_COLOR_INDEX12_EXT
:
1070 case GL_COLOR_INDEX16_EXT
:
1071 return &_mesa_texformat_ci8
;
1073 case GL_LUMINANCE_ALPHA
:
1074 case GL_LUMINANCE4_ALPHA4
:
1075 case GL_LUMINANCE6_ALPHA2
:
1076 case GL_LUMINANCE8_ALPHA8
:
1077 case GL_LUMINANCE12_ALPHA4
:
1078 case GL_LUMINANCE12_ALPHA12
:
1079 case GL_LUMINANCE16_ALPHA16
:
1080 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1081 return &_mesa_texformat_al88
;
1085 return &_mesa_texformat_rgb565
;
1087 return &_mesa_texformat_argb1555
;
1088 /* GL_EXT_texture_compression_s3tc */
1090 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1093 return &_mesa_texformat_rgb_dxt1
;
1094 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1095 return &_mesa_texformat_rgba_dxt1
;
1096 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1099 return &_mesa_texformat_rgba_dxt3
;
1100 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1101 return &_mesa_texformat_rgba_dxt5
;
1102 /* GL_3DFX_texture_compression_FXT1 */
1103 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1104 return &_mesa_texformat_rgb_fxt1
;
1105 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1106 return &_mesa_texformat_rgba_fxt1
;
1108 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1114 static GrTextureFormat_t
1115 fxGlideFormat(GLint mesaFormat
)
1117 switch (mesaFormat
) {
1118 case MESA_FORMAT_I8
:
1119 return GR_TEXFMT_ALPHA_8
;
1120 case MESA_FORMAT_A8
:
1121 return GR_TEXFMT_ALPHA_8
;
1122 case MESA_FORMAT_L8
:
1123 return GR_TEXFMT_INTENSITY_8
;
1124 case MESA_FORMAT_CI8
:
1125 return GR_TEXFMT_P_8
;
1126 case MESA_FORMAT_AL88
:
1127 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1128 case MESA_FORMAT_RGB565
:
1129 return GR_TEXFMT_RGB_565
;
1130 case MESA_FORMAT_ARGB4444
:
1131 return GR_TEXFMT_ARGB_4444
;
1132 case MESA_FORMAT_ARGB1555
:
1133 return GR_TEXFMT_ARGB_1555
;
1134 case MESA_FORMAT_ARGB8888
:
1135 return GR_TEXFMT_ARGB_8888
;
1136 case MESA_FORMAT_RGB_FXT1
:
1137 case MESA_FORMAT_RGBA_FXT1
:
1138 return GR_TEXFMT_ARGB_CMP_FXT1
;
1139 case MESA_FORMAT_RGB_DXT1
:
1140 case MESA_FORMAT_RGBA_DXT1
:
1141 return GR_TEXFMT_ARGB_CMP_DXT1
;
1142 case MESA_FORMAT_RGBA_DXT3
:
1143 return GR_TEXFMT_ARGB_CMP_DXT3
;
1144 case MESA_FORMAT_RGBA_DXT5
:
1145 return GR_TEXFMT_ARGB_CMP_DXT5
;
1147 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1153 static FetchTexelFunc
1154 fxFetchFunction(GLint mesaFormat
)
1156 switch (mesaFormat
) {
1157 case MESA_FORMAT_I8
:
1158 return &fetch_intensity8
;
1159 case MESA_FORMAT_A8
:
1160 return &fetch_alpha8
;
1161 case MESA_FORMAT_L8
:
1162 return &fetch_luminance8
;
1163 case MESA_FORMAT_CI8
:
1164 return &fetch_index8
;
1165 case MESA_FORMAT_AL88
:
1166 return &fetch_luminance8_alpha8
;
1167 case MESA_FORMAT_RGB565
:
1168 return &fetch_r5g6b5
;
1169 case MESA_FORMAT_ARGB4444
:
1170 return &fetch_r4g4b4a4
;
1171 case MESA_FORMAT_ARGB1555
:
1172 return &fetch_r5g5b5a1
;
1173 case MESA_FORMAT_ARGB8888
:
1174 return &fetch_a8r8g8b8
;
1175 case MESA_FORMAT_RGB_FXT1
:
1176 case MESA_FORMAT_RGBA_FXT1
:
1177 case MESA_FORMAT_RGB_DXT1
:
1178 case MESA_FORMAT_RGBA_DXT1
:
1179 case MESA_FORMAT_RGBA_DXT3
:
1180 case MESA_FORMAT_RGBA_DXT5
:
1181 return &fetch_r4g4b4a4
;
1183 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1189 fxDDTexImage2D(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 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1198 tfxMipMapLevel
*mml
;
1201 GLvoid
*_final_texImage_Data
;
1202 const struct gl_texture_format
*_final_texImage_TexFormat
;
1204 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1205 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1206 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1207 texImage
->Width
, texImage
->Height
);
1210 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1211 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1215 if (!texObj
->DriverData
) {
1216 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1217 if (!texObj
->DriverData
) {
1218 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1222 ti
= fxTMGetTexInfo(texObj
);
1224 if (!texImage
->DriverData
) {
1225 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1226 if (!texImage
->DriverData
) {
1227 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1231 mml
= FX_MIPMAP_DATA(texImage
);
1233 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1234 &mml
->wScale
, &mml
->hScale
);
1236 mml
->width
= width
* mml
->wScale
;
1237 mml
->height
= height
* mml
->hScale
;
1239 #if 0 && FX_COMPRESS_S3TC_AS_FXT1_HACK
1240 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1241 /* [dBorca] we should update texture's attribute, then,
1242 * because if the application asks us to decompress, we
1243 * have to know the REAL format! Also, DXT3/5 might not
1244 * be correct, since it would mess with "compressedSize".
1245 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1247 if (texImage
->IsCompressed
) {
1248 switch (internalFormat
) {
1249 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1252 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1254 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1255 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1256 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1259 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1263 #if 1 || FX_COMPRESS_DXT5_AS_DXT3_HACK
1264 /* [dBorca] either VSA is stupid at DXT5,
1265 * or our compression tool is broken. See
1266 * above for caveats.
1268 if ((texImage
->IsCompressed
) &&
1269 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)) {
1270 internalFormat
= GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
;
1274 /* choose the texture format */
1275 assert(ctx
->Driver
.ChooseTextureFormat
);
1276 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1277 internalFormat
, format
, type
);
1278 assert(texImage
->TexFormat
);
1279 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1280 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1282 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1283 /* dirty trick: will thrash CopyTex[Sub]Image */
1284 #if FX_TC_NCC || FX_TC_NAPALM
1285 if (internalFormat
== GL_COMPRESSED_RGB
) {
1287 mml
->glideFormat
= GR_TEXFMT_YIQ_422
;
1290 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1291 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1294 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1296 mml
->glideFormat
= GR_TEXFMT_AYIQ_8422
;
1299 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1300 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1306 /* allocate mipmap buffer */
1307 assert(!texImage
->Data
);
1308 if (texImage
->IsCompressed
) {
1309 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1311 _final_texImage_TexFormat
= &_mesa_texformat_argb8888
;
1312 _final_texImage_Data
= MALLOC(mml
->width
* mml
->height
* 4);
1313 if (!_final_texImage_Data
) {
1314 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1318 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1319 _final_texImage_TexFormat
= texImage
->TexFormat
;
1320 _final_texImage_Data
= texImage
->Data
;
1322 if (!texImage
->Data
) {
1323 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1327 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1328 /* rescale image to overcome 1:8 aspect limitation */
1330 tempImage
= MALLOC(width
* height
* texelBytes
);
1332 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1335 /* unpack image, apply transfer ops and store in tempImage */
1336 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1337 _final_texImage_TexFormat
,
1339 width
, height
, 1, 0, 0, 0, /* src */
1340 width
* texelBytes
, /* dstRowStride */
1341 0, /* dstImageStride */
1342 format
, type
, pixels
, packing
);
1343 _mesa_rescale_teximage2d(texelBytes
,
1344 mml
->width
* texelBytes
, /* dst stride */
1345 width
, height
, /* src */
1346 mml
->width
, mml
->height
, /* dst */
1347 tempImage
/*src*/, _final_texImage_Data
/*dst*/ );
1351 /* no rescaling needed */
1352 /* unpack image, apply transfer ops and store in texImage->Data */
1353 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1354 _final_texImage_TexFormat
, _final_texImage_Data
,
1355 width
, height
, 1, 0, 0, 0,
1356 mml
->width
* texelBytes
,
1357 0, /* dstImageStride */
1358 format
, type
, pixels
, packing
);
1362 if (texImage
->IsCompressed
) {
1364 if ((mml
->glideFormat
== GR_TEXFMT_AYIQ_8422
) ||
1365 (mml
->glideFormat
== GR_TEXFMT_YIQ_422
)) {
1367 txMip
.width
= mml
->width
;
1368 txMip
.height
= mml
->height
;
1370 txMip
.data
[0] = _final_texImage_Data
;
1371 pxMip
.data
[0] = texImage
->Data
;
1372 fxMesa
->Glide
.txMipQuantize(&pxMip
, &txMip
, mml
->glideFormat
, TX_DITHER_ERR
, TX_COMPRESSION_STATISTICAL
);
1373 fxMesa
->Glide
.txPalToNcc((GuNccTable
*)(&(ti
->palette
)), pxMip
.pal
);
1374 MEMCPY((char *)texImage
->Data
+ texImage
->CompressedSize
- 12 * 4, &(ti
->palette
.data
[16]), 12 * 4);
1377 fxMesa
->Glide
.txImgQuantize(texImage
->Data
, _final_texImage_Data
, mml
->width
, mml
->height
, mml
->glideFormat
, TX_DITHER_NONE
);
1378 FREE(_final_texImage_Data
);
1381 ti
->info
.format
= mml
->glideFormat
;
1382 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1385 * Hack alert: unsure...
1387 if (0 && ti
->validated
&& ti
->isInTM
) {
1388 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1389 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1392 /*fprintf(stderr, "invalidate2\n"); */
1393 fxTexInvalidate(ctx
, texObj
);
1399 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1400 GLint xoffset
, GLint yoffset
,
1401 GLsizei width
, GLsizei height
,
1402 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1403 const struct gl_pixelstore_attrib
*packing
,
1404 struct gl_texture_object
*texObj
,
1405 struct gl_texture_image
*texImage
)
1407 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1409 tfxMipMapLevel
*mml
;
1412 /* [dBorca] Hack alert:
1413 * fix the goddamn texture compression here
1416 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1417 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1420 if (!texObj
->DriverData
) {
1421 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1425 ti
= fxTMGetTexInfo(texObj
);
1427 mml
= FX_MIPMAP_DATA(texImage
);
1430 assert(texImage
->Data
); /* must have an existing texture image! */
1431 assert(texImage
->Format
);
1433 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1435 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1436 /* need to rescale subimage to match mipmap level's rescale factors */
1437 const GLint newWidth
= width
* mml
->wScale
;
1438 const GLint newHeight
= height
* mml
->hScale
;
1441 tempImage
= MALLOC(width
* height
* texelBytes
);
1443 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1447 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,/* Tex int format */
1448 texImage
->TexFormat
, /* dest format */
1449 (GLubyte
*) tempImage
, /* dest */
1450 width
, height
, 1, /* subimage size */
1451 0, 0, 0, /* subimage pos */
1452 width
* texelBytes
, /* dest row stride */
1453 0, /* dst image stride */
1454 format
, type
, pixels
, packing
);
1457 /* compute address of dest subimage within the overal tex image */
1458 destAddr
= (GLubyte
*) texImage
->Data
1459 + (yoffset
* mml
->hScale
* mml
->width
1460 + xoffset
* mml
->wScale
) * texelBytes
;
1462 _mesa_rescale_teximage2d(texelBytes
,
1463 mml
->width
* texelBytes
, /* dst stride */
1465 newWidth
, newHeight
,
1466 tempImage
, destAddr
);
1471 /* no rescaling needed */
1472 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
, /* Tex int format */
1473 texImage
->TexFormat
, /* dest format */
1474 (GLubyte
*) texImage
->Data
,/* dest */
1475 width
, height
, 1, /* subimage size */
1476 xoffset
, yoffset
, 0, /* subimage pos */
1477 mml
->width
* texelBytes
, /* dest row stride */
1478 0, /* dst image stride */
1479 format
, type
, pixels
, packing
);
1483 * Hack alert: unsure...
1485 if (0 && ti
->validated
&& ti
->isInTM
)
1486 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1488 fxTexInvalidate(ctx
, texObj
);
1493 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1494 GLint level
, GLint internalFormat
,
1495 GLsizei width
, GLsizei height
, GLint border
,
1496 GLsizei imageSize
, const GLvoid
*data
,
1497 struct gl_texture_object
*texObj
,
1498 struct gl_texture_image
*texImage
)
1500 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1502 tfxMipMapLevel
*mml
;
1504 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1505 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1506 texObj
->Name
, internalFormat
,
1510 assert(texImage
->IsCompressed
);
1512 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1513 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1517 if (!texObj
->DriverData
) {
1518 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1519 if (!texObj
->DriverData
) {
1520 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1524 ti
= fxTMGetTexInfo(texObj
);
1526 if (!texImage
->DriverData
) {
1527 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1528 if (!texImage
->DriverData
) {
1529 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1533 mml
= FX_MIPMAP_DATA(texImage
);
1535 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1536 &mml
->wScale
, &mml
->hScale
);
1538 mml
->width
= width
* mml
->wScale
;
1539 mml
->height
= height
* mml
->hScale
;
1542 /* choose the texture format */
1543 assert(ctx
->Driver
.ChooseTextureFormat
);
1544 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1545 internalFormat
, -1/*format*/, -1/*type*/);
1546 assert(texImage
->TexFormat
);
1548 /* Determine the appropriate Glide texel format,
1549 * given the user's internal texture format hint.
1551 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1552 #if FX_TC_NCC || FX_TC_NAPALM
1553 if (internalFormat
== GL_COMPRESSED_RGB
) {
1555 mml
->glideFormat
= GR_TEXFMT_YIQ_422
;
1558 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1559 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1562 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1564 mml
->glideFormat
= GR_TEXFMT_AYIQ_8422
;
1567 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1568 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1574 /* allocate new storage for texture image, if needed */
1575 if (!texImage
->Data
) {
1576 texImage
->Data
= MESA_PBUFFER_ALLOC(imageSize
);
1577 if (!texImage
->Data
) {
1578 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1583 /* save the texture data */
1584 MEMCPY(texImage
->Data
, data
, imageSize
);
1586 if ((mml
->glideFormat
== GR_TEXFMT_AYIQ_8422
) ||
1587 (mml
->glideFormat
== GR_TEXFMT_YIQ_422
)) {
1588 MEMCPY(&(ti
->palette
.data
[16]), (char *)data
+ imageSize
- 12 * 4, 12 * 4);
1592 ti
->info
.format
= mml
->glideFormat
;
1593 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1595 /* [dBorca] Hack alert:
1596 * what about different size/texel? other anomalies? SW rescaling?
1600 * Hack alert: unsure...
1602 if (0 && ti
->validated
&& ti
->isInTM
) {
1603 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1604 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1607 /*fprintf(stderr, "invalidate2\n"); */
1608 fxTexInvalidate(ctx
, texObj
);
1614 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1615 GLint level
, GLint xoffset
,
1616 GLint yoffset
, GLsizei width
,
1617 GLint height
, GLenum format
,
1618 GLsizei imageSize
, const GLvoid
*data
,
1619 struct gl_texture_object
*texObj
,
1620 struct gl_texture_image
*texImage
)
1622 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1624 tfxMipMapLevel
*mml
;
1626 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1627 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1630 ti
= fxTMGetTexInfo(texObj
);
1632 mml
= FX_MIPMAP_DATA(texImage
);
1636 * We punt if we are not replacing the entire image. This
1637 * is allowed by the spec.
1639 * [dBorca] Hack alert:
1640 * ohwell, we should NOT! Look into _mesa_store_compressed_texsubimage2d
1641 * on how to calculate the sub-image.
1643 if ((xoffset
!= 0) && (yoffset
!= 0)
1644 && (width
!= texImage
->Width
)
1645 && (height
!= texImage
->Height
)) {
1646 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage2D(CHICKEN)");
1650 /* [dBorca] Hack alert:
1651 * what about different size/texel? other anomalies? SW rescaling?
1653 MEMCPY(texImage
->Data
, data
, imageSize
);
1656 * Hack alert: unsure...
1658 if (0 && ti
->validated
&& ti
->isInTM
)
1659 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1661 fxTexInvalidate(ctx
, texObj
);
1668 * Need this to provide at least one external definition.
1671 extern int gl_fx_dummy_function_ddtex(void);
1673 gl_fx_dummy_function_ddtex(void)