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"
46 #include "texcompress.h"
52 _mesa_halve2x2_teximage2d ( GLuint bytesPerPixel
,
53 GLint srcWidth
, GLint srcHeight
,
54 const GLvoid
*srcImage
, GLvoid
*dstImage
)
57 const GLint dstWidth
= srcWidth
/ 2;
58 const GLint dstHeight
= srcHeight
/ 2;
59 const GLint srcRowStride
= srcWidth
* bytesPerPixel
;
60 const GLubyte
*src
= srcImage
;
61 GLubyte
*dst
= dstImage
;
63 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
65 for (i
= 0; i
< dstWidth
; i
++) {
66 for (k
= 0; k
< bytesPerPixel
; k
++) {
67 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
73 } else if (srcWidth
== 1) {
74 for (j
= 0; j
< dstHeight
; j
++) {
75 for (k
= 0; k
< bytesPerPixel
; k
++) {
76 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
83 for (j
= 0; j
< dstHeight
; j
++) {
84 for (i
= 0; i
< dstWidth
; i
++) {
85 for (k
= 0; k
< bytesPerPixel
; k
++) {
89 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
102 fxPrintTextureData(tfxTexInfo
* ti
)
104 fprintf(stderr
, "Texture Data:\n");
106 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
107 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
108 fprintf(stderr
, "\tSize: %d x %d\n",
109 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Width
,
110 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Height
);
113 fprintf(stderr
, "\tName: UNNAMED\n");
114 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
115 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
116 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
118 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
119 (unsigned) ti
->tm
[0]->endAddr
);
121 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
122 (unsigned) ti
->tm
[1]->endAddr
);
123 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
124 fprintf(stderr
, "\tFilters: min %d max %d\n",
125 (int) ti
->minFilt
, (int) ti
->maxFilt
);
126 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
128 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
129 fprintf(stderr
, "\t%s\n",
130 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
131 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
135 /************************************************************************/
136 /*************************** Texture Mapping ****************************/
137 /************************************************************************/
140 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
142 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
145 ti
= fxTMGetTexInfo(tObj
);
147 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
149 ti
->validated
= GL_FALSE
;
150 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
154 fxAllocTexObjData(fxMesaContext fxMesa
)
158 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
159 fprintf(stderr
, "fxAllocTexObjData: ERROR: out of memory !\n");
164 ti
->validated
= GL_FALSE
;
165 ti
->isInTM
= GL_FALSE
;
167 ti
->whichTMU
= FX_TMU_NONE
;
169 ti
->tm
[FX_TMU0
] = NULL
;
170 ti
->tm
[FX_TMU1
] = NULL
;
172 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
173 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
175 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
176 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
178 ti
->mmMode
= GR_MIPMAP_NEAREST
;
179 ti
->LODblend
= FXFALSE
;
185 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
187 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
190 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
191 fprintf(stderr
, "fxDDTexBind(%d, %x)\n", tObj
->Name
, (GLuint
)tObj
->DriverData
);
194 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
197 if (!tObj
->DriverData
) {
198 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
200 ti
= fxTMGetTexInfo(tObj
);
202 fxMesa
->texBindNumber
++;
203 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
205 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
209 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
210 const GLfloat
* param
)
212 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
214 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
216 fprintf(stderr
, "fxDDTexEnv(%x, %x)\n", pname
, (GLint
) (*param
));
218 fprintf(stderr
, "fxDDTexEnv(%x)\n", pname
);
221 /* apply any lod biasing right now */
222 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
223 GLfloat bias
= *param
;
224 CLAMP_SELF(bias
, -ctx
->Const
.MaxTextureLodBias
,
225 ctx
->Const
.MaxTextureLodBias
- 0.25);
227 grTexLodBiasValue(GR_TMU0
, bias
);
229 if (fxMesa
->haveTwoTMUs
) {
230 grTexLodBiasValue(GR_TMU1
, bias
);
235 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
239 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
240 GLenum pname
, const GLfloat
* params
)
242 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
243 GLenum param
= (GLenum
) (GLint
) params
[0];
246 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
247 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
248 tObj
->Name
, (GLuint
) tObj
->DriverData
,
249 _mesa_lookup_enum_by_nr(pname
),
250 _mesa_lookup_enum_by_nr(param
));
253 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
256 if (!tObj
->DriverData
)
257 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
258 ti
= fxTMGetTexInfo(tObj
);
261 case GL_TEXTURE_MIN_FILTER
:
264 ti
->mmMode
= GR_MIPMAP_DISABLE
;
265 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
266 ti
->LODblend
= FXFALSE
;
269 ti
->mmMode
= GR_MIPMAP_DISABLE
;
270 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
271 ti
->LODblend
= FXFALSE
;
273 case GL_NEAREST_MIPMAP_LINEAR
:
275 * trilinear is bugged! mipmap blending produce
276 * incorrect filtered colors for the smallest mipmap levels.
278 * currently Napalm can't do single-pass trilinear,
279 * because the way its combiners are set. So we fall back
280 * to GL_NEAREST_MIPMAP_NEAREST. We'll let true trilinear
281 * enabled for V2, V3. If user shoots foot, not our problem!
283 if (!fxMesa
->HaveCmbExt
) {
284 if (fxMesa
->haveTwoTMUs
) {
285 ti
->mmMode
= GR_MIPMAP_NEAREST
;
286 ti
->LODblend
= FXTRUE
;
288 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
289 ti
->LODblend
= FXFALSE
;
291 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
294 case GL_NEAREST_MIPMAP_NEAREST
:
295 ti
->mmMode
= GR_MIPMAP_NEAREST
;
296 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
297 ti
->LODblend
= FXFALSE
;
299 case GL_LINEAR_MIPMAP_LINEAR
:
301 * trilinear is bugged! mipmap blending produce
302 * incorrect filtered colors for the smallest mipmap levels.
304 * currently Napalm can't do single-pass trilinear,
305 * because the way its combiners are set. So we fall back
306 * to GL_LINEAR_MIPMAP_NEAREST. We'll let true trilinear
307 * enabled for V2, V3. If user shoots foot, not our problem!
309 if (!fxMesa
->HaveCmbExt
) {
310 if (fxMesa
->haveTwoTMUs
) {
311 ti
->mmMode
= GR_MIPMAP_NEAREST
;
312 ti
->LODblend
= FXTRUE
;
314 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
315 ti
->LODblend
= FXFALSE
;
317 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
320 case GL_LINEAR_MIPMAP_NEAREST
:
321 ti
->mmMode
= GR_MIPMAP_NEAREST
;
322 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
323 ti
->LODblend
= FXFALSE
;
328 fxTexInvalidate(ctx
, tObj
);
331 case GL_TEXTURE_MAG_FILTER
:
334 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
337 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
342 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
345 case GL_TEXTURE_WRAP_S
:
347 case GL_MIRRORED_REPEAT
:
348 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
350 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
351 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
353 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
356 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
361 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
364 case GL_TEXTURE_WRAP_T
:
366 case GL_MIRRORED_REPEAT
:
367 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
369 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
370 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
372 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
375 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
380 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
383 case GL_TEXTURE_BORDER_COLOR
:
387 case GL_TEXTURE_MIN_LOD
:
390 case GL_TEXTURE_MAX_LOD
:
393 case GL_TEXTURE_BASE_LEVEL
:
394 fxTexInvalidate(ctx
, tObj
);
396 case GL_TEXTURE_MAX_LEVEL
:
397 fxTexInvalidate(ctx
, tObj
);
406 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
408 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
409 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
411 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
412 fprintf(stderr
, "fxDDTexDel(%d, %p)\n", tObj
->Name
, (void *) ti
);
418 fxTMFreeTexture(fxMesa
, tObj
);
421 tObj
->DriverData
= NULL
;
423 /* Free mipmap images and the texture object itself */
424 _mesa_delete_texture_object(ctx
, tObj
);
429 * Allocate a new texture object.
430 * Called via ctx->Driver.NewTextureObject.
431 * Note: this function will be called during context creation to
432 * allocate the default texture objects.
434 struct gl_texture_object
*
435 fxDDNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
437 struct gl_texture_object
*obj
;
438 obj
= _mesa_new_texture_object(ctx
, name
, target
);
444 * Return true if texture is resident, false otherwise.
447 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
449 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
450 return (ti
&& ti
->isInTM
);
456 * Convert a gl_color_table texture palette to Glide's format.
459 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
461 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
462 GLint width
= table
->Size
;
466 ASSERT(table
->Type
== GL_UNSIGNED_BYTE
);
468 switch (table
->Format
) {
470 for (i
= 0; i
< width
; i
++) {
475 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
477 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
479 for (i
= 0; i
< width
; i
++) {
484 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
486 return GR_TEXTABLE_PALETTE
;
488 for (i
= 0; i
< width
; i
++) {
491 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
493 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
494 case GL_LUMINANCE_ALPHA
:
495 for (i
= 0; i
< width
; i
++) {
496 r
= g
= b
= tableUB
[i
* 2 + 0];
497 a
= tableUB
[i
* 2 + 1];
498 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
500 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
503 for (i
= 0; i
< width
; i
++) {
504 r
= tableUB
[i
* 3 + 0];
505 g
= tableUB
[i
* 3 + 1];
506 b
= tableUB
[i
* 3 + 2];
508 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
510 return GR_TEXTABLE_PALETTE
;
512 for (i
= 0; i
< width
; i
++) {
513 r
= tableUB
[i
* 4 + 0];
514 g
= tableUB
[i
* 4 + 1];
515 b
= tableUB
[i
* 4 + 2];
516 a
= tableUB
[i
* 4 + 3];
517 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
519 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
525 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
527 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
530 /* per-texture palette */
532 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
533 fprintf(stderr
, "fxDDTexPalette(%d, %x)\n",
534 tObj
->Name
, (GLuint
) tObj
->DriverData
);
536 /* This might be a proxy texture. */
537 if (!tObj
->Palette
.Table
)
539 if (!tObj
->DriverData
)
540 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
541 ti
= fxTMGetTexInfo(tObj
);
542 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
543 fxTexInvalidate(ctx
, tObj
);
546 /* global texture palette */
547 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
548 fprintf(stderr
, "fxDDTexPalette(global)\n");
550 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
551 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
553 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
559 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
561 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
563 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
564 fprintf(stderr
, "fxDDTexUseGlbPalette(%d)\n", state
);
568 fxMesa
->haveGlobalPaletteTexture
= 1;
571 fxMesa
->haveGlobalPaletteTexture
= 0;
573 /* [dBorca] tis beyond my comprehension */
574 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
575 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
576 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
577 if (!tObj
->DriverData
)
578 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
579 fxTexInvalidate(ctx
, tObj
);
609 * w, h - source texture width and height
610 * lodlevel - Glide lod level token for the larger texture dimension
611 * ar - Glide aspect ratio token
612 * sscale - S scale factor used during triangle setup
613 * tscale - T scale factor used during triangle setup
614 * wscale - OpenGL -> Glide image width scale factor
615 * hscale - OpenGL -> Glide image height scale factor
618 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
619 float *sscale
, float *tscale
,
620 int *wscale
, int *hscale
)
622 int logw
, logh
, ws
, hs
;
624 GrAspectRatio_t aspectratio
;
630 l
= MAX2(logw
, logh
);
631 aspectratio
= logw
- logh
;
635 /* hardware only allows a maximum aspect ratio of 8x1, so handle
636 * |aspectratio| > 3 by scaling the image and using an 8x1 aspect
639 switch (aspectratio
) {
661 if (aspectratio
> 3) {
663 hs
= 1 << (aspectratio
- 3);
664 aspectratio
= GR_ASPECT_LOG2_8x1
;
665 } else /*if (aspectratio < -3)*/ {
667 ws
= 1 << (-aspectratio
- 3);
668 aspectratio
= GR_ASPECT_LOG2_1x8
;
695 fxIsTexSupported(GLenum target
, GLint internalFormat
,
696 const struct gl_texture_image
*image
)
698 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
702 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
706 if (image
->Border
> 0)
713 /**********************************************************************/
714 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
715 /**********************************************************************/
717 fxt1_decode_1 (const void *texture
, int width
,
718 int i
, int j
, unsigned char *rgba
);
720 /* Texel-fetch functions for software texturing and glGetTexImage().
721 * We should have been able to use some "standard" fetch functions (which
722 * may get defined in texutil.c) but we have to account for scaled texture
723 * images on tdfx hardware (the 8:1 aspect ratio limit).
724 * Hence, we need special functions here.
728 fetch_intensity8(const struct gl_texture_image
*texImage
,
729 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
731 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
732 const GLubyte
*texel
;
737 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
738 rgba
[RCOMP
] = *texel
;
739 rgba
[GCOMP
] = *texel
;
740 rgba
[BCOMP
] = *texel
;
741 rgba
[ACOMP
] = *texel
;
746 fetch_luminance8(const struct gl_texture_image
*texImage
,
747 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
749 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
750 const GLubyte
*texel
;
755 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
756 rgba
[RCOMP
] = *texel
;
757 rgba
[GCOMP
] = *texel
;
758 rgba
[BCOMP
] = *texel
;
764 fetch_alpha8(const struct gl_texture_image
*texImage
,
765 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
767 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
768 const GLubyte
*texel
;
773 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
777 rgba
[ACOMP
] = *texel
;
782 fetch_index8(const struct gl_texture_image
*texImage
,
783 GLint i
, GLint j
, GLint k
, GLchan
*indexOut
)
785 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
786 const GLubyte
*texel
;
791 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
797 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
798 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
800 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
801 const GLubyte
*texel
;
806 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
807 rgba
[RCOMP
] = texel
[0];
808 rgba
[GCOMP
] = texel
[0];
809 rgba
[BCOMP
] = texel
[0];
810 rgba
[ACOMP
] = texel
[1];
815 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
816 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
818 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
819 const GLushort
*texel
;
824 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
825 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
826 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
827 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
833 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
834 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
836 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
837 const GLushort
*texel
;
842 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
843 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
844 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
845 rgba
[BCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
846 rgba
[ACOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
851 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
852 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
854 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
855 const GLushort
*texel
;
860 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
861 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
862 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 6) & 0x1F];
863 rgba
[BCOMP
] = FX_rgb_scale_5
[(*texel
>> 1) & 0x1F];
864 rgba
[ACOMP
] = ((*texel
) & 0x01) * 255;
869 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
870 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
872 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
878 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
879 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
880 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
881 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
882 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
887 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
888 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
890 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
895 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
901 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
902 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
904 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
909 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
914 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
915 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
917 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
922 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
927 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
928 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
930 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
935 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
940 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
941 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
943 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
948 _mesa_texformat_rgba_dxt3
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
953 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
954 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
956 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
961 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
966 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
969 for (i
= 0; i
< h
; i
++) {
970 for (j
= 0; j
< w
; j
++) {
972 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
974 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
977 fprintf(stderr
, "\n");
982 const struct gl_texture_format
*
983 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
984 GLenum srcFormat
, GLenum srcType
)
986 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
987 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
989 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
990 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
993 switch (internalFormat
) {
994 case GL_COMPRESSED_RGB
:
996 if (fxMesa
->HaveTexus2
) {
997 return &_mesa_texformat_argb8888
;
1000 /* intentional fall through */
1003 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1004 return &_mesa_texformat_rgb565
;
1006 /* intentional fall through */
1011 return (allow32bpt
) ? &_mesa_texformat_argb8888
1012 : &_mesa_texformat_rgb565
;
1015 return &_mesa_texformat_argb4444
;
1016 case GL_COMPRESSED_RGBA
:
1018 if (fxMesa
->HaveTexus2
) {
1019 return &_mesa_texformat_argb8888
;
1022 /* intentional fall through */
1025 if ( srcFormat
== GL_BGRA
) {
1026 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1027 return &_mesa_texformat_argb8888
;
1029 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1030 return &_mesa_texformat_argb4444
;
1032 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1033 return &_mesa_texformat_argb1555
;
1036 /* intentional fall through */
1041 return (allow32bpt
) ? &_mesa_texformat_argb8888
1042 : &_mesa_texformat_argb4444
;
1046 case GL_INTENSITY12
:
1047 case GL_INTENSITY16
:
1048 case GL_COMPRESSED_INTENSITY
:
1049 return &_mesa_texformat_i8
;
1054 case GL_LUMINANCE12
:
1055 case GL_LUMINANCE16
:
1056 case GL_COMPRESSED_LUMINANCE
:
1057 return &_mesa_texformat_l8
;
1063 case GL_COMPRESSED_ALPHA
:
1064 return &_mesa_texformat_a8
;
1065 case GL_COLOR_INDEX
:
1066 case GL_COLOR_INDEX1_EXT
:
1067 case GL_COLOR_INDEX2_EXT
:
1068 case GL_COLOR_INDEX4_EXT
:
1069 case GL_COLOR_INDEX8_EXT
:
1070 case GL_COLOR_INDEX12_EXT
:
1071 case GL_COLOR_INDEX16_EXT
:
1072 return &_mesa_texformat_ci8
;
1074 case GL_LUMINANCE_ALPHA
:
1075 case GL_LUMINANCE4_ALPHA4
:
1076 case GL_LUMINANCE6_ALPHA2
:
1077 case GL_LUMINANCE8_ALPHA8
:
1078 case GL_LUMINANCE12_ALPHA4
:
1079 case GL_LUMINANCE12_ALPHA12
:
1080 case GL_LUMINANCE16_ALPHA16
:
1081 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1082 return &_mesa_texformat_al88
;
1086 return &_mesa_texformat_rgb565
;
1088 return &_mesa_texformat_argb1555
;
1089 /* GL_EXT_texture_compression_s3tc */
1091 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1094 return &_mesa_texformat_rgb_dxt1
;
1095 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1096 return &_mesa_texformat_rgba_dxt1
;
1097 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1100 return &_mesa_texformat_rgba_dxt3
;
1101 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1102 return &_mesa_texformat_rgba_dxt5
;
1103 /* GL_3DFX_texture_compression_FXT1 */
1104 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1105 return &_mesa_texformat_rgb_fxt1
;
1106 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1107 return &_mesa_texformat_rgba_fxt1
;
1109 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1115 static GrTextureFormat_t
1116 fxGlideFormat(GLint mesaFormat
)
1118 switch (mesaFormat
) {
1119 case MESA_FORMAT_I8
:
1120 return GR_TEXFMT_ALPHA_8
;
1121 case MESA_FORMAT_A8
:
1122 return GR_TEXFMT_ALPHA_8
;
1123 case MESA_FORMAT_L8
:
1124 return GR_TEXFMT_INTENSITY_8
;
1125 case MESA_FORMAT_CI8
:
1126 return GR_TEXFMT_P_8
;
1127 case MESA_FORMAT_AL88
:
1128 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1129 case MESA_FORMAT_RGB565
:
1130 return GR_TEXFMT_RGB_565
;
1131 case MESA_FORMAT_ARGB4444
:
1132 return GR_TEXFMT_ARGB_4444
;
1133 case MESA_FORMAT_ARGB1555
:
1134 return GR_TEXFMT_ARGB_1555
;
1135 case MESA_FORMAT_ARGB8888
:
1136 return GR_TEXFMT_ARGB_8888
;
1137 case MESA_FORMAT_RGB_FXT1
:
1138 case MESA_FORMAT_RGBA_FXT1
:
1139 return GR_TEXFMT_ARGB_CMP_FXT1
;
1140 case MESA_FORMAT_RGB_DXT1
:
1141 case MESA_FORMAT_RGBA_DXT1
:
1142 return GR_TEXFMT_ARGB_CMP_DXT1
;
1143 case MESA_FORMAT_RGBA_DXT3
:
1144 return GR_TEXFMT_ARGB_CMP_DXT3
;
1145 case MESA_FORMAT_RGBA_DXT5
:
1146 return GR_TEXFMT_ARGB_CMP_DXT5
;
1148 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1154 static FetchTexelFuncC
1155 fxFetchFunction(GLint mesaFormat
)
1157 switch (mesaFormat
) {
1158 case MESA_FORMAT_I8
:
1159 return &fetch_intensity8
;
1160 case MESA_FORMAT_A8
:
1161 return &fetch_alpha8
;
1162 case MESA_FORMAT_L8
:
1163 return &fetch_luminance8
;
1164 case MESA_FORMAT_CI8
:
1165 return &fetch_index8
;
1166 case MESA_FORMAT_AL88
:
1167 return &fetch_luminance8_alpha8
;
1168 case MESA_FORMAT_RGB565
:
1169 return &fetch_r5g6b5
;
1170 case MESA_FORMAT_ARGB4444
:
1171 return &fetch_r4g4b4a4
;
1172 case MESA_FORMAT_ARGB1555
:
1173 return &fetch_r5g5b5a1
;
1174 case MESA_FORMAT_ARGB8888
:
1175 return &fetch_a8r8g8b8
;
1176 case MESA_FORMAT_RGB_FXT1
:
1177 return &fetch_rgb_fxt1
;
1178 case MESA_FORMAT_RGBA_FXT1
:
1179 return &fetch_rgba_fxt1
;
1180 case MESA_FORMAT_RGB_DXT1
:
1181 return &fetch_rgb_dxt1
;
1182 case MESA_FORMAT_RGBA_DXT1
:
1183 return &fetch_rgba_dxt1
;
1184 case MESA_FORMAT_RGBA_DXT3
:
1185 return &fetch_rgba_dxt3
;
1186 case MESA_FORMAT_RGBA_DXT5
:
1187 return &fetch_rgba_dxt5
;
1189 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1196 adjust2DRatio (GLcontext
*ctx
,
1197 GLint xoffset
, GLint yoffset
,
1198 GLint width
, GLint height
,
1199 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1200 const struct gl_pixelstore_attrib
*packing
,
1201 tfxMipMapLevel
*mml
,
1202 struct gl_texture_image
*texImage
,
1206 const GLint newWidth
= width
* mml
->wScale
;
1207 const GLint newHeight
= height
* mml
->hScale
;
1210 if (!texImage
->IsCompressed
) {
1212 tempImage
= MALLOC(width
* height
* texelBytes
);
1217 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1218 texImage
->TexFormat
, tempImage
,
1219 0, 0, 0, /* dstX/Y/Zoffset */
1220 width
* texelBytes
, /* dstRowStride */
1221 0, /* dstImageStride */
1223 format
, type
, pixels
, packing
);
1226 /* compute address of dest subimage within the overal tex image */
1227 destAddr
= (GLubyte
*) texImage
->Data
1228 + (yoffset
* mml
->hScale
* mml
->width
1229 + xoffset
* mml
->wScale
) * texelBytes
;
1231 _mesa_rescale_teximage2d(texelBytes
,
1232 dstRowStride
, /* dst stride */
1234 newWidth
, newHeight
,
1235 tempImage
, destAddr
);
1237 const GLint rawBytes
= 4;
1238 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1242 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1246 /* unpack image, apply transfer ops and store in rawImage */
1247 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
1248 &_mesa_texformat_rgba8888_rev
, rawImage
,
1249 0, 0, 0, /* dstX/Y/Zoffset */
1250 width
* rawBytes
, /* dstRowStride */
1251 0, /* dstImageStride */
1253 format
, type
, pixels
, packing
);
1254 _mesa_rescale_teximage2d(rawBytes
,
1255 newWidth
* rawBytes
, /* dst stride */
1256 width
, height
, /* src */
1257 newWidth
, newHeight
, /* dst */
1258 rawImage
/*src*/, tempImage
/*dst*/ );
1259 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1260 texImage
->TexFormat
, texImage
->Data
,
1261 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1263 0, /* dstImageStride */
1264 newWidth
, newHeight
, 1,
1265 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1276 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1277 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1278 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1279 const struct gl_pixelstore_attrib
*packing
,
1280 struct gl_texture_object
*texObj
,
1281 struct gl_texture_image
*texImage
)
1283 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1285 tfxMipMapLevel
*mml
;
1286 GLint texelBytes
, dstRowStride
;
1288 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1289 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1290 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1291 texImage
->Width
, texImage
->Height
);
1294 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1295 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1299 if (!texObj
->DriverData
) {
1300 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1301 if (!texObj
->DriverData
) {
1302 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1306 ti
= fxTMGetTexInfo(texObj
);
1308 if (!texImage
->DriverData
) {
1309 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1310 if (!texImage
->DriverData
) {
1311 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1315 mml
= FX_MIPMAP_DATA(texImage
);
1317 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1318 &mml
->wScale
, &mml
->hScale
);
1320 mml
->width
= width
* mml
->wScale
;
1321 mml
->height
= height
* mml
->hScale
;
1323 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1324 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1325 /* [dBorca] we should update texture's attribute, then,
1326 * because if the application asks us to decompress, we
1327 * have to know the REAL format! Also, DXT3/5 might not
1328 * be correct, since it would mess with "compressedSize".
1329 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1331 if (texImage
->IsCompressed
) {
1332 switch (internalFormat
) {
1333 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1336 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1338 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1339 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1340 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1343 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1345 texImage
->IntFormat
= internalFormat
;
1349 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1350 GLenum texNapalm
= 0;
1351 if (internalFormat
== GL_COMPRESSED_RGB
) {
1352 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1353 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1354 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1357 texImage
->IntFormat
= internalFormat
= texNapalm
;
1358 texImage
->IsCompressed
= GL_TRUE
;
1363 /* choose the texture format */
1364 assert(ctx
->Driver
.ChooseTextureFormat
);
1365 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1366 internalFormat
, format
, type
);
1367 assert(texImage
->TexFormat
);
1368 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1369 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1371 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1373 /* allocate mipmap buffer */
1374 assert(!texImage
->Data
);
1375 if (texImage
->IsCompressed
) {
1376 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1381 dstRowStride
= _mesa_compressed_row_stride(internalFormat
, mml
->width
);
1382 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1384 dstRowStride
= mml
->width
* texelBytes
;
1385 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1387 if (!texImage
->Data
) {
1388 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1392 if (pixels
!= NULL
) {
1393 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1394 /* rescale image to overcome 1:8 aspect limitation */
1395 if (!adjust2DRatio(ctx
,
1398 format
, type
, pixels
,
1405 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1410 /* no rescaling needed */
1411 /* unpack image, apply transfer ops and store in texImage->Data */
1412 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1413 texImage
->TexFormat
, texImage
->Data
,
1414 0, 0, 0, /* dstX/Y/Zoffset */
1416 0, /* dstImageStride */
1418 format
, type
, pixels
, packing
);
1421 if (fxMesa
->HaveTexus2
) {
1423 GLuint texSize
= mml
->width
* mml
->height
;
1424 if (internalFormat
== GL_COMPRESSED_RGB
) {
1425 texNCC
= GR_TEXFMT_YIQ_422
;
1426 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1427 texNCC
= GR_TEXFMT_AYIQ_8422
;
1432 GLubyte
*tempImage
= MESA_PBUFFER_ALLOC(texSize
);
1434 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1437 txMip
.width
= mml
->width
;
1438 txMip
.height
= mml
->height
;
1440 txMip
.data
[0] = texImage
->Data
;
1441 pxMip
.data
[0] = tempImage
;
1442 fxMesa
->Glide
.txMipQuantize(&pxMip
, &txMip
, texNCC
, TX_DITHER_ERR
, TX_COMPRESSION_HEURISTIC
);
1444 fxMesa
->Glide
.txPalToNcc((GuNccTable
*)(&(ti
->palette
)), pxMip
.pal
);
1446 MESA_PBUFFER_FREE(texImage
->Data
);
1447 texImage
->Data
= tempImage
;
1448 mml
->glideFormat
= texNCC
;
1453 /* GL_SGIS_generate_mipmap */
1454 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1455 GLint mipWidth
, mipHeight
;
1456 tfxMipMapLevel
*mip
;
1457 struct gl_texture_image
*mipImage
;
1458 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1459 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1461 assert(!texImage
->IsCompressed
);
1463 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1464 mipWidth
= width
/ 2;
1468 mipHeight
= height
/ 2;
1472 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1475 _mesa_TexImage2D(target
, ++level
, internalFormat
,
1476 mipWidth
, mipHeight
, border
,
1479 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1480 mip
= FX_MIPMAP_DATA(mipImage
);
1481 _mesa_halve2x2_teximage2d(texelBytes
,
1482 mml
->width
, mml
->height
,
1483 texImage
->Data
, mipImage
->Data
);
1484 texImage
= mipImage
;
1492 ti
->info
.format
= mml
->glideFormat
;
1493 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1496 * Hack alert: unsure...
1498 if (0 && ti
->validated
&& ti
->isInTM
) {
1499 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1500 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1503 /*fprintf(stderr, "invalidate2\n"); */
1504 fxTexInvalidate(ctx
, texObj
);
1510 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1511 GLint xoffset
, GLint yoffset
,
1512 GLsizei width
, GLsizei height
,
1513 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1514 const struct gl_pixelstore_attrib
*packing
,
1515 struct gl_texture_object
*texObj
,
1516 struct gl_texture_image
*texImage
)
1518 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1520 tfxMipMapLevel
*mml
;
1521 GLint texelBytes
, dstRowStride
;
1523 /* [dBorca] Hack alert:
1524 * FX_TC_NCC not supported
1527 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1528 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1531 if (!texObj
->DriverData
) {
1532 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1536 ti
= fxTMGetTexInfo(texObj
);
1538 mml
= FX_MIPMAP_DATA(texImage
);
1541 assert(texImage
->Data
); /* must have an existing texture image! */
1542 assert(texImage
->Format
);
1544 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1545 if (texImage
->IsCompressed
) {
1546 dstRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, mml
->width
);
1548 dstRowStride
= mml
->width
* texelBytes
;
1551 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1552 /* need to rescale subimage to match mipmap level's rescale factors */
1553 if (!adjust2DRatio(ctx
,
1556 format
, type
, pixels
,
1563 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1568 /* no rescaling needed */
1569 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1570 texImage
->TexFormat
, (GLubyte
*) texImage
->Data
,
1571 xoffset
, yoffset
, 0, /* dstX/Y/Zoffset */
1573 0, /* dstImageStride */
1575 format
, type
, pixels
, packing
);
1578 /* GL_SGIS_generate_mipmap */
1579 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1580 GLint mipWidth
, mipHeight
;
1581 tfxMipMapLevel
*mip
;
1582 struct gl_texture_image
*mipImage
;
1583 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1584 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1586 assert(!texImage
->IsCompressed
);
1588 width
= texImage
->Width
;
1589 height
= texImage
->Height
;
1590 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1591 mipWidth
= width
/ 2;
1595 mipHeight
= height
/ 2;
1599 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1603 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1604 mip
= FX_MIPMAP_DATA(mipImage
);
1605 _mesa_halve2x2_teximage2d(texelBytes
,
1606 mml
->width
, mml
->height
,
1607 texImage
->Data
, mipImage
->Data
);
1608 texImage
= mipImage
;
1615 if (ti
->validated
&& ti
->isInTM
&& !texObj
->GenerateMipmap
)
1616 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1618 fxTexInvalidate(ctx
, texObj
);
1623 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1624 GLint level
, GLint internalFormat
,
1625 GLsizei width
, GLsizei height
, GLint border
,
1626 GLsizei imageSize
, const GLvoid
*data
,
1627 struct gl_texture_object
*texObj
,
1628 struct gl_texture_image
*texImage
)
1630 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1632 tfxMipMapLevel
*mml
;
1634 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1635 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1636 texObj
->Name
, internalFormat
,
1640 assert(texImage
->IsCompressed
);
1642 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1643 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1647 if (!texObj
->DriverData
) {
1648 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1649 if (!texObj
->DriverData
) {
1650 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1654 ti
= fxTMGetTexInfo(texObj
);
1656 if (!texImage
->DriverData
) {
1657 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1658 if (!texImage
->DriverData
) {
1659 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1663 mml
= FX_MIPMAP_DATA(texImage
);
1665 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1666 &mml
->wScale
, &mml
->hScale
);
1668 mml
->width
= width
* mml
->wScale
;
1669 mml
->height
= height
* mml
->hScale
;
1672 /* choose the texture format */
1673 assert(ctx
->Driver
.ChooseTextureFormat
);
1674 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1675 internalFormat
, -1/*format*/, -1/*type*/);
1676 assert(texImage
->TexFormat
);
1678 /* Determine the appropriate Glide texel format,
1679 * given the user's internal texture format hint.
1681 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1683 /* allocate new storage for texture image, if needed */
1684 if (!texImage
->Data
) {
1685 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1690 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1691 if (!texImage
->Data
) {
1692 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1697 /* save the texture data */
1698 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1699 /* [dBorca] Hack alert:
1700 * now we're screwed. We can't decompress,
1701 * unless we do it in HW (via textureBuffer).
1702 * We still have some chances:
1703 * 1) we got FXT1 textures - we CAN decompress, rescale for
1704 * aspectratio, then compress back.
1705 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1706 * Thus, we don't care about textureclamp and we could lower
1707 * MIN("uscale", "vscale") below 32. We still have to have
1708 * our data aligned inside a 8:1 rectangle.
1709 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1710 * we replicate the data over the padded area.
1711 * For now, we take 2) + 3) but texelfetchers will be wrong!
1713 GLuint srcRowStride
= _mesa_compressed_row_stride(internalFormat
, width
);
1715 GLuint destRowStride
= _mesa_compressed_row_stride(internalFormat
,
1718 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1719 destRowStride
, (mml
->height
+3) / 4,
1720 1, data
, srcRowStride
,
1722 ti
->padded
= GL_TRUE
;
1724 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1727 ti
->info
.format
= mml
->glideFormat
;
1728 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1730 /* GL_SGIS_generate_mipmap */
1731 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1732 assert(!texImage
->IsCompressed
);
1736 * Hack alert: unsure...
1738 if (0 && ti
->validated
&& ti
->isInTM
) {
1739 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1740 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1743 /*fprintf(stderr, "invalidate2\n"); */
1744 fxTexInvalidate(ctx
, texObj
);
1750 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1751 GLint level
, GLint xoffset
,
1752 GLint yoffset
, GLsizei width
,
1753 GLint height
, GLenum format
,
1754 GLsizei imageSize
, const GLvoid
*data
,
1755 struct gl_texture_object
*texObj
,
1756 struct gl_texture_image
*texImage
)
1758 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1760 tfxMipMapLevel
*mml
;
1761 GLint destRowStride
, srcRowStride
;
1765 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1766 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1769 ti
= fxTMGetTexInfo(texObj
);
1771 mml
= FX_MIPMAP_DATA(texImage
);
1774 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, width
);
1776 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1778 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1779 texImage
->IntFormat
,
1781 (GLubyte
*) texImage
->Data
);
1783 rows
= height
/ 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1785 for (i
= 0; i
< rows
; i
++) {
1786 MEMCPY(dest
, data
, srcRowStride
);
1787 dest
+= destRowStride
;
1788 data
= (GLvoid
*)((GLuint
)data
+ (GLuint
)srcRowStride
);
1791 /* [dBorca] Hack alert:
1792 * see fxDDCompressedTexImage2D for caveats
1794 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1795 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, texImage
->Width
);
1797 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1799 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1800 destRowStride
, mml
->height
/ 4,
1801 1, texImage
->Data
, destRowStride
,
1805 /* GL_SGIS_generate_mipmap */
1806 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1807 assert(!texImage
->IsCompressed
);
1810 if (ti
->validated
&& ti
->isInTM
)
1811 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1813 fxTexInvalidate(ctx
, texObj
);
1818 fxDDTexImage1D (GLcontext
*ctx
, GLenum target
, GLint level
,
1819 GLint internalFormat
, GLint width
, GLint border
,
1820 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1821 const struct gl_pixelstore_attrib
*packing
,
1822 struct gl_texture_object
*texObj
,
1823 struct gl_texture_image
*texImage
)
1825 fxDDTexImage2D(ctx
, target
, level
,
1826 internalFormat
, width
, 1, border
,
1827 format
, type
, pixels
,
1835 fxDDTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1838 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1839 const struct gl_pixelstore_attrib
*packing
,
1840 struct gl_texture_object
*texObj
,
1841 struct gl_texture_image
*texImage
)
1843 fxDDTexSubImage2D(ctx
, target
, level
,
1844 xoffset
, 0, width
, 1,
1845 format
, type
, pixels
,
1853 fxDDTestProxyTexImage (GLcontext
*ctx
, GLenum target
,
1854 GLint level
, GLint internalFormat
,
1855 GLenum format
, GLenum type
,
1856 GLint width
, GLint height
,
1857 GLint depth
, GLint border
)
1860 * TODO - maybe through fxTexValidate()
1862 return _mesa_test_proxy_teximage(ctx
, target
,
1863 level
, internalFormat
,
1873 * Need this to provide at least one external definition.
1876 extern int gl_fx_dummy_function_ddtex(void);
1878 gl_fx_dummy_function_ddtex(void)