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"
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 max %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
, "fxAllocTexObjData: ERROR: out of memory !\n");
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
, "fxDDTexBind(%d, %x)\n", tObj
->Name
, (GLuint
)tObj
->DriverData
);
144 if (target
!= GL_TEXTURE_2D
)
147 if (!tObj
->DriverData
) {
148 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
150 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
, "fxDDTexEnv(%x, %x)\n", pname
, (GLint
) (*param
));
169 fprintf(stderr
, "fxDDTexEnv(%x)\n", 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
);
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
:
223 * trilinear is bugged! mipmap blending produce
224 * incorrect filtered colors for the smallest mipmap levels.
226 * currently Napalm can't do single-pass trilinear,
227 * because the way its combiners are set. So we fall back
228 * to GL_NEAREST_MIPMAP_NEAREST. We'll let true trilinear
229 * enabled for V2, V3. If user shoots foot, not our problem!
231 if (!fxMesa
->HaveCmbExt
) {
232 if (fxMesa
->haveTwoTMUs
) {
233 ti
->mmMode
= GR_MIPMAP_NEAREST
;
234 ti
->LODblend
= FXTRUE
;
236 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
237 ti
->LODblend
= FXFALSE
;
239 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
242 case GL_NEAREST_MIPMAP_NEAREST
:
243 ti
->mmMode
= GR_MIPMAP_NEAREST
;
244 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
245 ti
->LODblend
= FXFALSE
;
247 case GL_LINEAR_MIPMAP_LINEAR
:
249 * trilinear is bugged! mipmap blending produce
250 * incorrect filtered colors for the smallest mipmap levels.
252 * currently Napalm can't do single-pass trilinear,
253 * because the way its combiners are set. So we fall back
254 * to GL_LINEAR_MIPMAP_NEAREST. We'll let true trilinear
255 * enabled for V2, V3. If user shoots foot, not our problem!
257 if (!fxMesa
->HaveCmbExt
) {
258 if (fxMesa
->haveTwoTMUs
) {
259 ti
->mmMode
= GR_MIPMAP_NEAREST
;
260 ti
->LODblend
= FXTRUE
;
262 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
263 ti
->LODblend
= FXFALSE
;
265 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
268 case GL_LINEAR_MIPMAP_NEAREST
:
269 ti
->mmMode
= GR_MIPMAP_NEAREST
;
270 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
271 ti
->LODblend
= FXFALSE
;
276 fxTexInvalidate(ctx
, tObj
);
279 case GL_TEXTURE_MAG_FILTER
:
282 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
285 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
290 fxTexInvalidate(ctx
, tObj
);
293 case GL_TEXTURE_WRAP_S
:
295 case GL_MIRRORED_REPEAT
:
296 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
298 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
300 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
303 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
308 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
311 case GL_TEXTURE_WRAP_T
:
313 case GL_MIRRORED_REPEAT
:
314 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
316 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
318 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
321 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
326 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
329 case GL_TEXTURE_BORDER_COLOR
:
333 case GL_TEXTURE_MIN_LOD
:
336 case GL_TEXTURE_MAX_LOD
:
339 case GL_TEXTURE_BASE_LEVEL
:
340 fxTexInvalidate(ctx
, tObj
);
342 case GL_TEXTURE_MAX_LEVEL
:
343 fxTexInvalidate(ctx
, tObj
);
352 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
354 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
355 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
357 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
358 fprintf(stderr
, "fxDDTexDel(%d, %p)\n", tObj
->Name
, (void *) ti
);
364 fxTMFreeTexture(fxMesa
, tObj
);
367 tObj
->DriverData
= NULL
;
369 /* Free mipmap images and the texture object itself */
370 _mesa_delete_texture_object(ctx
, tObj
);
375 * Allocate a new texture object.
376 * Called via ctx->Driver.NewTextureObject.
377 * Note: this function will be called during context creation to
378 * allocate the default texture objects.
380 struct gl_texture_object
*
381 fxDDNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
383 struct gl_texture_object
*obj
;
384 obj
= _mesa_new_texture_object(ctx
, name
, target
);
390 * Return true if texture is resident, false otherwise.
393 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
395 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
396 return (ti
&& ti
->isInTM
);
402 * Convert a gl_color_table texture palette to Glide's format.
405 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
407 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
408 GLint width
= table
->Size
;
412 ASSERT(!table
->FloatTable
);
414 switch (table
->Format
) {
416 for (i
= 0; i
< width
; i
++) {
421 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
423 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
425 for (i
= 0; i
< width
; i
++) {
430 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
432 return GR_TEXTABLE_PALETTE
;
434 for (i
= 0; i
< width
; i
++) {
437 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
439 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
440 case GL_LUMINANCE_ALPHA
:
441 for (i
= 0; i
< width
; i
++) {
442 r
= g
= b
= tableUB
[i
* 2 + 0];
443 a
= tableUB
[i
* 2 + 1];
444 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
446 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
449 for (i
= 0; i
< width
; i
++) {
450 r
= tableUB
[i
* 3 + 0];
451 g
= tableUB
[i
* 3 + 1];
452 b
= tableUB
[i
* 3 + 2];
454 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
456 return GR_TEXTABLE_PALETTE
;
458 for (i
= 0; i
< width
; i
++) {
459 r
= tableUB
[i
* 4 + 0];
460 g
= tableUB
[i
* 4 + 1];
461 b
= tableUB
[i
* 4 + 2];
462 a
= tableUB
[i
* 4 + 3];
463 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
465 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
471 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
473 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
476 /* per-texture palette */
478 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
479 fprintf(stderr
, "fxDDTexPalette(%d, %x)\n",
480 tObj
->Name
, (GLuint
) tObj
->DriverData
);
482 if (!tObj
->DriverData
)
483 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
484 ti
= fxTMGetTexInfo(tObj
);
486 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
487 fxTexInvalidate(ctx
, tObj
);
490 /* global texture palette */
491 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
492 fprintf(stderr
, "fxDDTexPalette(global)\n");
494 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
495 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
497 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
503 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
505 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
507 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
508 fprintf(stderr
, "fxDDTexUseGlbPalette(%d)\n", state
);
512 fxMesa
->haveGlobalPaletteTexture
= 1;
515 fxMesa
->haveGlobalPaletteTexture
= 0;
517 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
518 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
519 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
520 if (!tObj
->DriverData
)
521 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
522 assert(tObj
->DriverData
);
523 fxTexInvalidate(ctx
, tObj
);
553 * w, h - source texture width and height
554 * lodlevel - Glide lod level token for the larger texture dimension
555 * ar - Glide aspect ratio token
556 * sscale - S scale factor used during triangle setup
557 * tscale - T scale factor used during triangle setup
558 * wscale - OpenGL -> Glide image width scale factor
559 * hscale - OpenGL -> Glide image height scale factor
562 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
563 float *sscale
, float *tscale
,
564 int *wscale
, int *hscale
)
566 int logw
, logh
, ws
, hs
;
568 GrAspectRatio_t aspectratio
;
574 l
= MAX2(logw
, logh
);
575 aspectratio
= logw
- logh
;
579 /* hardware only allows a maximum aspect ratio of 8x1, so handle
580 * |aspectratio| > 3 by scaling the image and using an 8x1 aspect
583 switch (aspectratio
) {
605 if (aspectratio
> 3) {
607 hs
= 1 << (aspectratio
- 3);
608 aspectratio
= GR_ASPECT_LOG2_8x1
;
609 } else /*if (aspectratio < -3)*/ {
611 ws
= 1 << (-aspectratio
- 3);
612 aspectratio
= GR_ASPECT_LOG2_1x8
;
639 fxIsTexSupported(GLenum target
, GLint internalFormat
,
640 const struct gl_texture_image
*image
)
642 if (target
!= GL_TEXTURE_2D
)
646 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
650 if (image
->Border
> 0)
657 /**********************************************************************/
658 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
659 /**********************************************************************/
661 /* Texel-fetch functions for software texturing and glGetTexImage().
662 * We should have been able to use some "standard" fetch functions (which
663 * may get defined in texutil.c) but we have to account for scaled texture
664 * images on tdfx hardware (the 8:1 aspect ratio limit).
665 * Hence, we need special functions here.
668 * this better be right, if we will advertise GL_SGIS_generate_mipmap!
672 fetch_intensity8(const struct gl_texture_image
*texImage
,
673 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
675 GLchan
*rgba
= (GLchan
*) texelOut
;
676 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
677 const GLubyte
*texel
;
682 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
683 rgba
[RCOMP
] = *texel
;
684 rgba
[GCOMP
] = *texel
;
685 rgba
[BCOMP
] = *texel
;
686 rgba
[ACOMP
] = *texel
;
691 fetch_luminance8(const struct gl_texture_image
*texImage
,
692 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
694 GLchan
*rgba
= (GLchan
*) texelOut
;
695 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
696 const GLubyte
*texel
;
701 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
702 rgba
[RCOMP
] = *texel
;
703 rgba
[GCOMP
] = *texel
;
704 rgba
[BCOMP
] = *texel
;
710 fetch_alpha8(const struct gl_texture_image
*texImage
,
711 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
713 GLchan
*rgba
= (GLchan
*) texelOut
;
714 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
715 const GLubyte
*texel
;
720 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
724 rgba
[ACOMP
] = *texel
;
729 fetch_index8(const struct gl_texture_image
*texImage
,
730 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
732 GLchan
*indexOut
= (GLchan
*) texelOut
;
733 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
734 const GLubyte
*texel
;
739 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
745 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
746 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
748 GLchan
*rgba
= (GLchan
*) texelOut
;
749 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
750 const GLubyte
*texel
;
755 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
756 rgba
[RCOMP
] = texel
[0];
757 rgba
[GCOMP
] = texel
[0];
758 rgba
[BCOMP
] = texel
[0];
759 rgba
[ACOMP
] = texel
[1];
764 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
765 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
767 GLchan
*rgba
= (GLchan
*) texelOut
;
768 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
769 const GLushort
*texel
;
774 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
775 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
776 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
777 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
783 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
784 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
786 GLchan
*rgba
= (GLchan
*) texelOut
;
787 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
788 const GLushort
*texel
;
793 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
794 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
795 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
796 rgba
[BCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
797 rgba
[ACOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
802 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
803 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
805 GLchan
*rgba
= (GLchan
*) texelOut
;
806 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
807 const GLushort
*texel
;
812 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
813 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
814 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 6) & 0x1F];
815 rgba
[BCOMP
] = FX_rgb_scale_5
[(*texel
>> 1) & 0x1F];
816 rgba
[ACOMP
] = ((*texel
) & 0x01) * 255;
821 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
822 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
824 GLchan
*rgba
= (GLchan
*) texelOut
;
825 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
831 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
832 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
833 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
834 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
835 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
840 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
843 for (i
= 0; i
< h
; i
++) {
844 for (j
= 0; j
< w
; j
++) {
846 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
848 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
851 fprintf(stderr
, "\n");
856 GLboolean
fxDDIsCompressedFormat ( GLcontext
*ctx
, GLenum internalFormat
)
858 if ((internalFormat
== GL_COMPRESSED_RGB_FXT1_3DFX
) ||
859 (internalFormat
== GL_COMPRESSED_RGBA_FXT1_3DFX
) ||
860 (internalFormat
== GL_COMPRESSED_RGB_S3TC_DXT1_EXT
) ||
861 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
) ||
862 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
) ||
863 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
) ||
864 (internalFormat
== GL_RGB_S3TC
) ||
865 (internalFormat
== GL_RGB4_S3TC
) ||
866 (internalFormat
== GL_RGBA_S3TC
) ||
867 (internalFormat
== GL_RGBA4_S3TC
)) {
872 * we are handling differently the above formats from the generic
873 * GL_COMPRESSED_RGB[A]. For this, we will always have to 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 width to next multiple of 8, height to next multiple of 4 */
912 width
= (width
+ 7) & ~7;
913 height
= (height
+ 3) & ~3;
914 /* 16 bytes per 8x4 tile of RGB[A] texels */
915 size
= width
* height
/ 2;
916 /* Textures smaller than 8x4 will effectively be made into 8x4 and
922 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
923 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
926 /* round up width, height to next multiple of 4 */
927 width
= (width
+ 3) & ~3;
928 height
= (height
+ 3) & ~3;
929 /* 8 bytes per 4x4 tile of RGB[A] texels */
930 size
= width
* height
/ 2;
931 /* Textures smaller than 4x4 will effectively be made into 4x4 and
937 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
938 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
941 /* round up width, height to next multiple of 4 */
942 width
= (width
+ 3) & ~3;
943 height
= (height
+ 3) & ~3;
944 /* 16 bytes per 4x4 tile of RGBA texels */
945 size
= width
* height
; /* simple! */
946 /* Textures smaller than 4x4 will effectively be made into 4x4 and
952 case GL_COMPRESSED_RGB
:
955 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
956 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
957 return fxDDCompressedTextureSize(ctx
, width
, height
, 1, GL_COMPRESSED_RGB_FXT1_3DFX
);
962 return (width
* height
* 8 >> 3) + 12 * 4;
964 case GL_COMPRESSED_RGBA
:
967 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
968 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
969 return fxDDCompressedTextureSize(ctx
, width
, height
, 1, GL_COMPRESSED_RGBA_FXT1_3DFX
);
974 return (width
* height
* 16 >> 3) + 12 * 4;
977 _mesa_problem(ctx
, "bad texformat in fxDDCompressedTextureSize");
983 const struct gl_texture_format
*
984 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
985 GLenum srcFormat
, GLenum srcType
)
987 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
988 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
990 /* [dBorca] Hack alert:
991 * There is something wrong with this!!! Take an example:
992 * 1) start HW rendering
993 * 2) create a texture like this:
994 * glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
995 * GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
996 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
997 * 3) we get here with internalFormat==3 and return either
998 * _mesa_texformat_rgb565 or _mesa_texformat_argb8888
999 * 4) at some point, we encounter total rasterization fallback
1000 * 5) displaying a polygon with the above textures yield garbage on areas
1001 * where pixel is larger than a texel, because our already set texel
1002 * function doesn't match the real _mesa_texformat_argb888
1005 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1006 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
1009 switch (internalFormat
) {
1010 case GL_COMPRESSED_RGB
:
1011 #if 0 && FX_TC_NAPALM /* [koolsmoky] */
1012 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
) {
1013 return &_mesa_texformat_rgb_fxt1
;
1014 } else if (ctx
->Extensions
.EXT_texture_compression_s3tc
) {
1015 return &_mesa_texformat_rgb_dxt1
;
1018 /* intentional fall through */
1021 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1022 return &_mesa_texformat_rgb565
;
1024 /* intentional fall through */
1029 return (allow32bpt
) ? &_mesa_texformat_argb8888
1030 : &_mesa_texformat_rgb565
;
1033 return &_mesa_texformat_argb4444
;
1034 case GL_COMPRESSED_RGBA
:
1035 #if 0 && FX_TC_NAPALM /* [koolsmoky] */
1036 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
) {
1037 return &_mesa_texformat_rgba_fxt1
;
1038 } else if (ctx
->Extensions
.EXT_texture_compression_s3tc
) {
1039 return &_mesa_texformat_rgba_dxt3
;
1042 /* intentional fall through */
1045 if ( srcFormat
== GL_BGRA
) {
1046 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1047 return &_mesa_texformat_argb8888
;
1049 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1050 return &_mesa_texformat_argb4444
;
1052 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1053 return &_mesa_texformat_argb1555
;
1056 /* intentional fall through */
1061 return (allow32bpt
) ? &_mesa_texformat_argb8888
1062 : &_mesa_texformat_argb4444
;
1066 case GL_INTENSITY12
:
1067 case GL_INTENSITY16
:
1068 case GL_COMPRESSED_INTENSITY
:
1069 return &_mesa_texformat_i8
;
1074 case GL_LUMINANCE12
:
1075 case GL_LUMINANCE16
:
1076 case GL_COMPRESSED_LUMINANCE
:
1077 return &_mesa_texformat_l8
;
1083 case GL_COMPRESSED_ALPHA
:
1084 return &_mesa_texformat_a8
;
1085 case GL_COLOR_INDEX
:
1086 case GL_COLOR_INDEX1_EXT
:
1087 case GL_COLOR_INDEX2_EXT
:
1088 case GL_COLOR_INDEX4_EXT
:
1089 case GL_COLOR_INDEX8_EXT
:
1090 case GL_COLOR_INDEX12_EXT
:
1091 case GL_COLOR_INDEX16_EXT
:
1092 return &_mesa_texformat_ci8
;
1094 case GL_LUMINANCE_ALPHA
:
1095 case GL_LUMINANCE4_ALPHA4
:
1096 case GL_LUMINANCE6_ALPHA2
:
1097 case GL_LUMINANCE8_ALPHA8
:
1098 case GL_LUMINANCE12_ALPHA4
:
1099 case GL_LUMINANCE12_ALPHA12
:
1100 case GL_LUMINANCE16_ALPHA16
:
1101 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1102 return &_mesa_texformat_al88
;
1106 return &_mesa_texformat_rgb565
;
1108 return &_mesa_texformat_argb1555
;
1109 /* GL_EXT_texture_compression_s3tc */
1111 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1114 return &_mesa_texformat_rgb_dxt1
;
1115 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1116 return &_mesa_texformat_rgba_dxt1
;
1117 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1120 return &_mesa_texformat_rgba_dxt3
;
1121 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1122 return &_mesa_texformat_rgba_dxt5
;
1123 /* GL_3DFX_texture_compression_FXT1 */
1124 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1125 return &_mesa_texformat_rgb_fxt1
;
1126 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1127 return &_mesa_texformat_rgba_fxt1
;
1129 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1135 static GrTextureFormat_t
1136 fxGlideFormat(GLint mesaFormat
)
1138 switch (mesaFormat
) {
1139 case MESA_FORMAT_I8
:
1140 return GR_TEXFMT_ALPHA_8
;
1141 case MESA_FORMAT_A8
:
1142 return GR_TEXFMT_ALPHA_8
;
1143 case MESA_FORMAT_L8
:
1144 return GR_TEXFMT_INTENSITY_8
;
1145 case MESA_FORMAT_CI8
:
1146 return GR_TEXFMT_P_8
;
1147 case MESA_FORMAT_AL88
:
1148 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1149 case MESA_FORMAT_RGB565
:
1150 return GR_TEXFMT_RGB_565
;
1151 case MESA_FORMAT_ARGB4444
:
1152 return GR_TEXFMT_ARGB_4444
;
1153 case MESA_FORMAT_ARGB1555
:
1154 return GR_TEXFMT_ARGB_1555
;
1155 case MESA_FORMAT_ARGB8888
:
1156 return GR_TEXFMT_ARGB_8888
;
1157 case MESA_FORMAT_RGB_FXT1
:
1158 case MESA_FORMAT_RGBA_FXT1
:
1159 return GR_TEXFMT_ARGB_CMP_FXT1
;
1160 case MESA_FORMAT_RGB_DXT1
:
1161 case MESA_FORMAT_RGBA_DXT1
:
1162 return GR_TEXFMT_ARGB_CMP_DXT1
;
1163 case MESA_FORMAT_RGBA_DXT3
:
1164 return GR_TEXFMT_ARGB_CMP_DXT3
;
1165 case MESA_FORMAT_RGBA_DXT5
:
1166 return GR_TEXFMT_ARGB_CMP_DXT5
;
1168 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1174 static FetchTexelFunc
1175 fxFetchFunction(GLint mesaFormat
)
1177 switch (mesaFormat
) {
1178 case MESA_FORMAT_I8
:
1179 return &fetch_intensity8
;
1180 case MESA_FORMAT_A8
:
1181 return &fetch_alpha8
;
1182 case MESA_FORMAT_L8
:
1183 return &fetch_luminance8
;
1184 case MESA_FORMAT_CI8
:
1185 return &fetch_index8
;
1186 case MESA_FORMAT_AL88
:
1187 return &fetch_luminance8_alpha8
;
1188 case MESA_FORMAT_RGB565
:
1189 return &fetch_r5g6b5
;
1190 case MESA_FORMAT_ARGB4444
:
1191 return &fetch_r4g4b4a4
;
1192 case MESA_FORMAT_ARGB1555
:
1193 return &fetch_r5g5b5a1
;
1194 case MESA_FORMAT_ARGB8888
:
1195 return &fetch_a8r8g8b8
;
1196 case MESA_FORMAT_RGB_FXT1
:
1197 case MESA_FORMAT_RGBA_FXT1
:
1198 case MESA_FORMAT_RGB_DXT1
:
1199 case MESA_FORMAT_RGBA_DXT1
:
1200 case MESA_FORMAT_RGBA_DXT3
:
1201 case MESA_FORMAT_RGBA_DXT5
:
1202 return &fetch_r4g4b4a4
;
1204 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1210 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1211 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1212 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1213 const struct gl_pixelstore_attrib
*packing
,
1214 struct gl_texture_object
*texObj
,
1215 struct gl_texture_image
*texImage
)
1217 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1219 tfxMipMapLevel
*mml
;
1222 GLvoid
*_final_texImage_Data
;
1223 const struct gl_texture_format
*_final_texImage_TexFormat
;
1225 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1226 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1227 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1228 texImage
->Width
, texImage
->Height
);
1231 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1232 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1236 if (!texObj
->DriverData
) {
1237 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1238 if (!texObj
->DriverData
) {
1239 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1244 if (!texImage
->DriverData
) {
1245 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1246 if (!texImage
->DriverData
) {
1247 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1251 ti
= fxTMGetTexInfo(texObj
);
1253 mml
= FX_MIPMAP_DATA(texImage
);
1255 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1256 &mml
->wScale
, &mml
->hScale
);
1258 mml
->width
= width
* mml
->wScale
;
1259 mml
->height
= height
* mml
->hScale
;
1261 #if 0 && FX_COMPRESS_S3TC_AS_FXT1_HACK
1262 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1263 /* [dBorca] we should update texture's attribute, then,
1264 * because if the application asks us to decompress, we
1265 * have to know the REAL format! Also, DXT3/5 might not
1266 * be correct, since it would mess with "compressedSize".
1267 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1269 if (texImage
->IsCompressed
) {
1270 switch (internalFormat
) {
1271 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1274 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1276 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1277 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1278 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1281 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1285 #if 1 || FX_COMPRESS_DXT5_AS_DXT3_HACK
1286 /* [dBorca] either VSA is stupid at DXT5,
1287 * or our compression tool is broken. See
1288 * above for caveats.
1290 if ((texImage
->IsCompressed
) &&
1291 (internalFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)) {
1292 internalFormat
= GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
;
1296 /* choose the texture format */
1297 assert(ctx
->Driver
.ChooseTextureFormat
);
1298 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1299 internalFormat
, format
, type
);
1300 assert(texImage
->TexFormat
);
1301 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1302 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1304 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1305 /* dirty trick: will thrash CopyTex[Sub]Image */
1306 #if FX_TC_NCC || FX_TC_NAPALM
1307 if (internalFormat
== GL_COMPRESSED_RGB
) {
1309 mml
->glideFormat
= GR_TEXFMT_YIQ_422
;
1312 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1313 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1316 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1318 mml
->glideFormat
= GR_TEXFMT_AYIQ_8422
;
1321 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1322 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1328 /* allocate mipmap buffer */
1329 assert(!texImage
->Data
);
1330 if (texImage
->IsCompressed
) {
1331 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1333 _final_texImage_TexFormat
= &_mesa_texformat_argb8888
;
1334 _final_texImage_Data
= MALLOC(mml
->width
* mml
->height
* 4);
1335 if (!_final_texImage_Data
) {
1336 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1340 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1341 _final_texImage_TexFormat
= texImage
->TexFormat
;
1342 _final_texImage_Data
= texImage
->Data
;
1344 if (!texImage
->Data
) {
1345 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1349 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1350 /* rescale image to overcome 1:8 aspect limitation */
1352 tempImage
= MALLOC(width
* height
* texelBytes
);
1354 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1357 /* unpack image, apply transfer ops and store in tempImage */
1358 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1359 _final_texImage_TexFormat
,
1361 width
, height
, 1, 0, 0, 0, /* src */
1362 width
* texelBytes
, /* dstRowStride */
1363 0, /* dstImageStride */
1364 format
, type
, pixels
, packing
);
1365 _mesa_rescale_teximage2d(texelBytes
,
1366 mml
->width
* texelBytes
, /* dst stride */
1367 width
, height
, /* src */
1368 mml
->width
, mml
->height
, /* dst */
1369 tempImage
/*src*/, _final_texImage_Data
/*dst*/ );
1373 /* no rescaling needed */
1374 /* unpack image, apply transfer ops and store in texImage->Data */
1375 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1376 _final_texImage_TexFormat
, _final_texImage_Data
,
1377 width
, height
, 1, 0, 0, 0,
1378 mml
->width
* texelBytes
,
1379 0, /* dstImageStride */
1380 format
, type
, pixels
, packing
);
1384 if (texImage
->IsCompressed
) {
1386 if ((mml
->glideFormat
== GR_TEXFMT_AYIQ_8422
) ||
1387 (mml
->glideFormat
== GR_TEXFMT_YIQ_422
)) {
1389 txMip
.width
= mml
->width
;
1390 txMip
.height
= mml
->height
;
1392 txMip
.data
[0] = _final_texImage_Data
;
1393 pxMip
.data
[0] = texImage
->Data
;
1394 fxMesa
->Glide
.txMipQuantize(&pxMip
, &txMip
, mml
->glideFormat
, TX_DITHER_ERR
, TX_COMPRESSION_STATISTICAL
);
1395 fxMesa
->Glide
.txPalToNcc((GuNccTable
*)(&(ti
->palette
)), pxMip
.pal
);
1396 MEMCPY((char *)texImage
->Data
+ texImage
->CompressedSize
- 12 * 4, &(ti
->palette
.data
[16]), 12 * 4);
1399 fxMesa
->Glide
.txImgQuantize(texImage
->Data
, _final_texImage_Data
, mml
->width
, mml
->height
, mml
->glideFormat
, TX_DITHER_NONE
);
1400 FREE(_final_texImage_Data
);
1403 ti
->info
.format
= mml
->glideFormat
;
1404 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1407 * Hack alert: unsure...
1409 if (0 && ti
->validated
&& ti
->isInTM
) {
1410 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1411 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1414 /*fprintf(stderr, "invalidate2\n"); */
1415 fxTexInvalidate(ctx
, texObj
);
1421 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1422 GLint xoffset
, GLint yoffset
,
1423 GLsizei width
, GLsizei height
,
1424 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1425 const struct gl_pixelstore_attrib
*packing
,
1426 struct gl_texture_object
*texObj
,
1427 struct gl_texture_image
*texImage
)
1429 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1431 tfxMipMapLevel
*mml
;
1434 /* [dBorca] Hack alert:
1435 * fix the goddamn texture compression here
1438 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1439 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1442 if (!texObj
->DriverData
) {
1443 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1447 ti
= fxTMGetTexInfo(texObj
);
1449 mml
= FX_MIPMAP_DATA(texImage
);
1452 assert(texImage
->Data
); /* must have an existing texture image! */
1453 assert(texImage
->Format
);
1455 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1457 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1458 /* need to rescale subimage to match mipmap level's rescale factors */
1459 const GLint newWidth
= width
* mml
->wScale
;
1460 const GLint newHeight
= height
* mml
->hScale
;
1463 tempImage
= MALLOC(width
* height
* texelBytes
);
1465 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1469 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,/* Tex int format */
1470 texImage
->TexFormat
, /* dest format */
1471 (GLubyte
*) tempImage
, /* dest */
1472 width
, height
, 1, /* subimage size */
1473 0, 0, 0, /* subimage pos */
1474 width
* texelBytes
, /* dest row stride */
1475 0, /* dst image stride */
1476 format
, type
, pixels
, packing
);
1479 /* compute address of dest subimage within the overal tex image */
1480 destAddr
= (GLubyte
*) texImage
->Data
1481 + (yoffset
* mml
->hScale
* mml
->width
1482 + xoffset
* mml
->wScale
) * texelBytes
;
1484 _mesa_rescale_teximage2d(texelBytes
,
1485 mml
->width
* texelBytes
, /* dst stride */
1487 newWidth
, newHeight
,
1488 tempImage
, destAddr
);
1493 /* no rescaling needed */
1494 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
, /* Tex int format */
1495 texImage
->TexFormat
, /* dest format */
1496 (GLubyte
*) texImage
->Data
,/* dest */
1497 width
, height
, 1, /* subimage size */
1498 xoffset
, yoffset
, 0, /* subimage pos */
1499 mml
->width
* texelBytes
, /* dest row stride */
1500 0, /* dst image stride */
1501 format
, type
, pixels
, packing
);
1505 * Hack alert: unsure...
1507 if (0 && ti
->validated
&& ti
->isInTM
)
1508 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1510 fxTexInvalidate(ctx
, texObj
);
1515 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1516 GLint level
, GLint internalFormat
,
1517 GLsizei width
, GLsizei height
, GLint border
,
1518 GLsizei imageSize
, const GLvoid
*data
,
1519 struct gl_texture_object
*texObj
,
1520 struct gl_texture_image
*texImage
)
1522 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1524 tfxMipMapLevel
*mml
;
1526 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1527 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1528 texObj
->Name
, internalFormat
,
1532 assert(texImage
->IsCompressed
);
1534 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1535 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1539 if (!texObj
->DriverData
) {
1540 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1541 if (!texObj
->DriverData
) {
1542 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1547 if (!texImage
->DriverData
) {
1548 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1549 if (!texImage
->DriverData
) {
1550 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1554 ti
= fxTMGetTexInfo(texObj
);
1555 mml
= FX_MIPMAP_DATA(texImage
);
1557 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1558 &mml
->wScale
, &mml
->hScale
);
1560 mml
->width
= width
* mml
->wScale
;
1561 mml
->height
= height
* mml
->hScale
;
1564 /* choose the texture format */
1565 assert(ctx
->Driver
.ChooseTextureFormat
);
1566 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1567 internalFormat
, -1/*format*/, -1/*type*/);
1568 assert(texImage
->TexFormat
);
1570 /* Determine the appropriate Glide texel format,
1571 * given the user's internal texture format hint.
1573 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1574 #if FX_TC_NCC || FX_TC_NAPALM
1575 if (internalFormat
== GL_COMPRESSED_RGB
) {
1577 mml
->glideFormat
= GR_TEXFMT_YIQ_422
;
1580 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1581 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1584 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1586 mml
->glideFormat
= GR_TEXFMT_AYIQ_8422
;
1589 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1590 mml
->glideFormat
= GR_TEXFMT_ARGB_CMP_FXT1
;
1596 /* allocate new storage for texture image, if needed */
1597 if (!texImage
->Data
) {
1598 texImage
->Data
= MESA_PBUFFER_ALLOC(imageSize
);
1599 if (!texImage
->Data
) {
1600 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1605 /* save the texture data */
1606 MEMCPY(texImage
->Data
, data
, imageSize
);
1608 if ((mml
->glideFormat
== GR_TEXFMT_AYIQ_8422
) ||
1609 (mml
->glideFormat
== GR_TEXFMT_YIQ_422
)) {
1610 MEMCPY(&(ti
->palette
.data
[16]), (char *)data
+ imageSize
- 12 * 4, 12 * 4);
1614 ti
->info
.format
= mml
->glideFormat
;
1615 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1617 /* [dBorca] Hack alert:
1618 * what about different size/texel? other anomalies? SW rescaling?
1622 * Hack alert: unsure...
1624 if (0 && ti
->validated
&& ti
->isInTM
) {
1625 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1626 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1629 /*fprintf(stderr, "invalidate2\n"); */
1630 fxTexInvalidate(ctx
, texObj
);
1636 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1637 GLint level
, GLint xoffset
,
1638 GLint yoffset
, GLsizei width
,
1639 GLint height
, GLenum format
,
1640 GLsizei imageSize
, const GLvoid
*data
,
1641 struct gl_texture_object
*texObj
,
1642 struct gl_texture_image
*texImage
)
1644 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1646 tfxMipMapLevel
*mml
;
1648 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1649 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1652 ti
= fxTMGetTexInfo(texObj
);
1654 mml
= FX_MIPMAP_DATA(texImage
);
1658 * We punt if we are not replacing the entire image. This
1659 * is allowed by the spec.
1661 * [dBorca] Hack alert:
1662 * ohwell, we should NOT! Look into _mesa_store_compressed_texsubimage2d
1663 * on how to calculate the sub-image.
1665 if ((xoffset
!= 0) && (yoffset
!= 0)
1666 && (width
!= texImage
->Width
)
1667 && (height
!= texImage
->Height
)) {
1668 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage2D(CHICKEN)");
1672 /* [dBorca] Hack alert:
1673 * what about different size/texel? other anomalies? SW rescaling?
1675 MEMCPY(texImage
->Data
, data
, imageSize
);
1678 * Hack alert: unsure...
1680 if (0 && ti
->validated
&& ti
->isInTM
)
1681 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1683 fxTexInvalidate(ctx
, texObj
);
1690 * Need this to provide at least one external definition.
1693 extern int gl_fx_dummy_function_ddtex(void);
1695 gl_fx_dummy_function_ddtex(void)