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"
51 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
53 _mesa_halve2x2_teximage2d ( GLcontext
*ctx
,
54 struct gl_texture_image
*texImage
,
56 GLint srcWidth
, GLint srcHeight
,
57 const GLvoid
*srcImage
, GLvoid
*dstImage
)
60 GLint dstWidth
= srcWidth
/ 2;
61 GLint dstHeight
= srcHeight
/ 2;
62 GLint srcRowStride
= srcWidth
* bytesPerPixel
;
63 GLubyte
*src
= (GLubyte
*)srcImage
;
64 GLubyte
*dst
= dstImage
;
71 if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_RGB565
) {
72 _t
= GL_UNSIGNED_SHORT_5_6_5_REV
;
74 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
75 _t
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
77 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
78 _t
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
83 srcRowStride
= srcWidth
* bytesPerPixel
;
90 _s
= src
= MALLOC(srcRowStride
* srcHeight
);
91 _d
= dst
= MALLOC(dstWidth
* bytesPerPixel
* dstHeight
);
92 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
93 &_mesa_texformat_rgba8888_rev
, src
,
94 0, 0, 0, /* dstX/Y/Zoffset */
95 srcRowStride
, /* dstRowStride */
96 0, /* dstImageStride */
97 srcWidth
, srcHeight
, 1,
98 texImage
->Format
, _t
, srcImage
, &ctx
->DefaultPacking
);
101 if (srcHeight
== 1) {
102 for (i
= 0; i
< dstWidth
; i
++) {
103 for (k
= 0; k
< bytesPerPixel
; k
++) {
104 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
108 src
+= bytesPerPixel
;
110 } else if (srcWidth
== 1) {
111 for (j
= 0; j
< dstHeight
; j
++) {
112 for (k
= 0; k
< bytesPerPixel
; k
++) {
113 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
120 for (j
= 0; j
< dstHeight
; j
++) {
121 for (i
= 0; i
< dstWidth
; i
++) {
122 for (k
= 0; k
< bytesPerPixel
; k
++) {
126 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
130 src
+= bytesPerPixel
;
139 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
140 texImage
->TexFormat
, dstImage
,
141 0, 0, 0, /* dstX/Y/Zoffset */
143 0, /* dstImageStride */
144 dstWidth
, dstHeight
, 1,
145 GL_BGRA
, CHAN_TYPE
, dst
, &ctx
->DefaultPacking
);
153 fxPrintTextureData(tfxTexInfo
* ti
)
155 fprintf(stderr
, "Texture Data:\n");
157 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
158 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
159 fprintf(stderr
, "\tSize: %d x %d\n",
160 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Width
,
161 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Height
);
164 fprintf(stderr
, "\tName: UNNAMED\n");
165 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
166 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
167 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
169 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
170 (unsigned) ti
->tm
[0]->endAddr
);
172 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
173 (unsigned) ti
->tm
[1]->endAddr
);
174 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
175 fprintf(stderr
, "\tFilters: min %d max %d\n",
176 (int) ti
->minFilt
, (int) ti
->maxFilt
);
177 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
179 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
180 fprintf(stderr
, "\t%s\n",
181 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
182 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
186 /************************************************************************/
187 /*************************** Texture Mapping ****************************/
188 /************************************************************************/
191 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
193 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
196 ti
= fxTMGetTexInfo(tObj
);
198 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
200 ti
->validated
= GL_FALSE
;
201 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
205 fxAllocTexObjData(fxMesaContext fxMesa
)
209 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
210 fprintf(stderr
, "fxAllocTexObjData: ERROR: out of memory !\n");
215 ti
->validated
= GL_FALSE
;
216 ti
->isInTM
= GL_FALSE
;
218 ti
->whichTMU
= FX_TMU_NONE
;
220 ti
->tm
[FX_TMU0
] = NULL
;
221 ti
->tm
[FX_TMU1
] = NULL
;
223 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
224 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
226 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
227 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
229 ti
->mmMode
= GR_MIPMAP_NEAREST
;
230 ti
->LODblend
= FXFALSE
;
236 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
238 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
241 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
242 fprintf(stderr
, "fxDDTexBind(%d, %x)\n", tObj
->Name
, (GLuint
)tObj
->DriverData
);
245 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
248 if (!tObj
->DriverData
) {
249 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
251 ti
= fxTMGetTexInfo(tObj
);
253 fxMesa
->texBindNumber
++;
254 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
256 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
260 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
261 const GLfloat
* param
)
263 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
265 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
267 fprintf(stderr
, "fxDDTexEnv(%x, %x)\n", pname
, (GLint
) (*param
));
269 fprintf(stderr
, "fxDDTexEnv(%x)\n", pname
);
272 /* apply any lod biasing right now */
273 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
274 GLfloat bias
= *param
;
275 CLAMP_SELF(bias
, -ctx
->Const
.MaxTextureLodBias
,
276 ctx
->Const
.MaxTextureLodBias
- 0.25);
278 grTexLodBiasValue(GR_TMU0
, bias
);
280 if (fxMesa
->haveTwoTMUs
) {
281 grTexLodBiasValue(GR_TMU1
, bias
);
286 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
290 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
291 GLenum pname
, const GLfloat
* params
)
293 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
294 GLenum param
= (GLenum
) (GLint
) params
[0];
297 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
298 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
299 tObj
->Name
, (GLuint
) tObj
->DriverData
,
300 _mesa_lookup_enum_by_nr(pname
),
301 _mesa_lookup_enum_by_nr(param
));
304 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
307 if (!tObj
->DriverData
)
308 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
309 ti
= fxTMGetTexInfo(tObj
);
312 case GL_TEXTURE_MIN_FILTER
:
315 ti
->mmMode
= GR_MIPMAP_DISABLE
;
316 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
317 ti
->LODblend
= FXFALSE
;
320 ti
->mmMode
= GR_MIPMAP_DISABLE
;
321 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
322 ti
->LODblend
= FXFALSE
;
324 case GL_NEAREST_MIPMAP_LINEAR
:
326 * trilinear is bugged! mipmap blending produce
327 * incorrect filtered colors for the smallest mipmap levels.
329 * currently Napalm can't do single-pass trilinear,
330 * because the way its combiners are set. So we fall back
331 * to GL_NEAREST_MIPMAP_NEAREST. We'll let true trilinear
332 * enabled for V2, V3. If user shoots foot, not our problem!
334 if (!fxMesa
->HaveCmbExt
) {
335 if (fxMesa
->haveTwoTMUs
) {
336 ti
->mmMode
= GR_MIPMAP_NEAREST
;
337 ti
->LODblend
= FXTRUE
;
339 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
340 ti
->LODblend
= FXFALSE
;
342 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
345 case GL_NEAREST_MIPMAP_NEAREST
:
346 ti
->mmMode
= GR_MIPMAP_NEAREST
;
347 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
348 ti
->LODblend
= FXFALSE
;
350 case GL_LINEAR_MIPMAP_LINEAR
:
352 * trilinear is bugged! mipmap blending produce
353 * incorrect filtered colors for the smallest mipmap levels.
355 * currently Napalm can't do single-pass trilinear,
356 * because the way its combiners are set. So we fall back
357 * to GL_LINEAR_MIPMAP_NEAREST. We'll let true trilinear
358 * enabled for V2, V3. If user shoots foot, not our problem!
360 if (!fxMesa
->HaveCmbExt
) {
361 if (fxMesa
->haveTwoTMUs
) {
362 ti
->mmMode
= GR_MIPMAP_NEAREST
;
363 ti
->LODblend
= FXTRUE
;
365 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
366 ti
->LODblend
= FXFALSE
;
368 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
371 case GL_LINEAR_MIPMAP_NEAREST
:
372 ti
->mmMode
= GR_MIPMAP_NEAREST
;
373 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
374 ti
->LODblend
= FXFALSE
;
379 fxTexInvalidate(ctx
, tObj
);
382 case GL_TEXTURE_MAG_FILTER
:
385 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
388 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
393 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
396 case GL_TEXTURE_WRAP_S
:
398 case GL_MIRRORED_REPEAT
:
399 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
401 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
402 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
404 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
407 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
412 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
415 case GL_TEXTURE_WRAP_T
:
417 case GL_MIRRORED_REPEAT
:
418 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
420 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
421 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
423 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
426 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
431 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
434 case GL_TEXTURE_BORDER_COLOR
:
438 case GL_TEXTURE_MIN_LOD
:
441 case GL_TEXTURE_MAX_LOD
:
444 case GL_TEXTURE_BASE_LEVEL
:
445 fxTexInvalidate(ctx
, tObj
);
447 case GL_TEXTURE_MAX_LEVEL
:
448 fxTexInvalidate(ctx
, tObj
);
457 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
459 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
460 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
462 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
463 fprintf(stderr
, "fxDDTexDel(%d, %p)\n", tObj
->Name
, (void *) ti
);
469 fxTMFreeTexture(fxMesa
, tObj
);
472 tObj
->DriverData
= NULL
;
474 /* Free mipmap images and the texture object itself */
475 _mesa_delete_texture_object(ctx
, tObj
);
480 * Allocate a new texture object.
481 * Called via ctx->Driver.NewTextureObject.
482 * Note: this function will be called during context creation to
483 * allocate the default texture objects.
485 struct gl_texture_object
*
486 fxDDNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
488 struct gl_texture_object
*obj
;
489 obj
= _mesa_new_texture_object(ctx
, name
, target
);
495 * Return true if texture is resident, false otherwise.
498 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
500 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
501 return (ti
&& ti
->isInTM
);
507 * Convert a gl_color_table texture palette to Glide's format.
510 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
512 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
513 GLint width
= table
->Size
;
517 ASSERT(table
->Type
== GL_UNSIGNED_BYTE
);
519 switch (table
->Format
) {
521 for (i
= 0; i
< width
; i
++) {
526 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
528 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
530 for (i
= 0; i
< width
; i
++) {
535 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
537 return GR_TEXTABLE_PALETTE
;
539 for (i
= 0; i
< width
; i
++) {
542 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
544 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
545 case GL_LUMINANCE_ALPHA
:
546 for (i
= 0; i
< width
; i
++) {
547 r
= g
= b
= tableUB
[i
* 2 + 0];
548 a
= tableUB
[i
* 2 + 1];
549 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
551 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
554 for (i
= 0; i
< width
; i
++) {
555 r
= tableUB
[i
* 3 + 0];
556 g
= tableUB
[i
* 3 + 1];
557 b
= tableUB
[i
* 3 + 2];
559 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
561 return GR_TEXTABLE_PALETTE
;
563 for (i
= 0; i
< width
; i
++) {
564 r
= tableUB
[i
* 4 + 0];
565 g
= tableUB
[i
* 4 + 1];
566 b
= tableUB
[i
* 4 + 2];
567 a
= tableUB
[i
* 4 + 3];
568 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
570 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
576 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
578 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
581 /* per-texture palette */
583 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
584 fprintf(stderr
, "fxDDTexPalette(%d, %x)\n",
585 tObj
->Name
, (GLuint
) tObj
->DriverData
);
587 /* This might be a proxy texture. */
588 if (!tObj
->Palette
.Table
)
590 if (!tObj
->DriverData
)
591 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
592 ti
= fxTMGetTexInfo(tObj
);
593 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
594 fxTexInvalidate(ctx
, tObj
);
597 /* global texture palette */
598 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
599 fprintf(stderr
, "fxDDTexPalette(global)\n");
601 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
602 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
604 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
610 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
612 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
614 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
615 fprintf(stderr
, "fxDDTexUseGlbPalette(%d)\n", state
);
618 fxMesa
->haveGlobalPaletteTexture
= state
;
619 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
647 * w, h - source texture width and height
648 * lodlevel - Glide lod level token for the larger texture dimension
649 * ar - Glide aspect ratio token
650 * sscale - S scale factor used during triangle setup
651 * tscale - T scale factor used during triangle setup
652 * wscale - OpenGL -> Glide image width scale factor
653 * hscale - OpenGL -> Glide image height scale factor
656 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
657 float *sscale
, float *tscale
,
658 int *wscale
, int *hscale
)
660 int logw
, logh
, ws
, hs
;
662 GrAspectRatio_t aspectratio
;
668 l
= MAX2(logw
, logh
);
669 aspectratio
= logw
- logh
;
673 /* hardware only allows a maximum aspect ratio of 8x1, so handle
674 * |aspectratio| > 3 by scaling the image and using an 8x1 aspect
677 switch (aspectratio
) {
699 if (aspectratio
> 3) {
701 hs
= 1 << (aspectratio
- 3);
702 aspectratio
= GR_ASPECT_LOG2_8x1
;
703 } else /*if (aspectratio < -3)*/ {
705 ws
= 1 << (-aspectratio
- 3);
706 aspectratio
= GR_ASPECT_LOG2_1x8
;
733 fxIsTexSupported(GLenum target
, GLint internalFormat
,
734 const struct gl_texture_image
*image
)
736 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
740 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
744 if (image
->Border
> 0)
751 /**********************************************************************/
752 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
753 /**********************************************************************/
755 fxt1_decode_1 (const void *texture
, int width
,
756 int i
, int j
, unsigned char *rgba
);
758 /* Texel-fetch functions for software texturing and glGetTexImage().
759 * We should have been able to use some "standard" fetch functions (which
760 * may get defined in texutil.c) but we have to account for scaled texture
761 * images on tdfx hardware (the 8:1 aspect ratio limit).
762 * Hence, we need special functions here.
766 fetch_intensity8(const struct gl_texture_image
*texImage
,
767 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
769 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
770 const GLubyte
*texel
;
775 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
776 rgba
[RCOMP
] = *texel
;
777 rgba
[GCOMP
] = *texel
;
778 rgba
[BCOMP
] = *texel
;
779 rgba
[ACOMP
] = *texel
;
784 fetch_luminance8(const struct gl_texture_image
*texImage
,
785 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
787 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
788 const GLubyte
*texel
;
793 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
794 rgba
[RCOMP
] = *texel
;
795 rgba
[GCOMP
] = *texel
;
796 rgba
[BCOMP
] = *texel
;
802 fetch_alpha8(const struct gl_texture_image
*texImage
,
803 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
805 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
806 const GLubyte
*texel
;
811 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
815 rgba
[ACOMP
] = *texel
;
820 fetch_index8(const struct gl_texture_image
*texImage
,
821 GLint i
, GLint j
, GLint k
, GLchan
*indexOut
)
823 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
824 const GLubyte
*texel
;
829 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
835 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
836 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
838 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
839 const GLubyte
*texel
;
844 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
845 rgba
[RCOMP
] = texel
[0];
846 rgba
[GCOMP
] = texel
[0];
847 rgba
[BCOMP
] = texel
[0];
848 rgba
[ACOMP
] = texel
[1];
853 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
854 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
856 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
857 const GLushort
*texel
;
862 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
863 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
864 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
865 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
871 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
872 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
874 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
875 const GLushort
*texel
;
880 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
881 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
882 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
883 rgba
[BCOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
884 rgba
[ACOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
889 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
890 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
892 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
893 const GLushort
*texel
;
898 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
899 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 10) & 0x1F];
900 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 5) & 0x1F];
901 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
902 rgba
[ACOMP
] = (*texel
>> 15) * 255;
907 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
908 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
910 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
916 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
917 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
918 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
919 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
920 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
925 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
926 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
928 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
933 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
939 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
940 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
942 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
947 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
952 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
953 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
955 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
960 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
965 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
966 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
968 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
973 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
978 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
979 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
981 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
986 _mesa_texformat_rgba_dxt3
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
991 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
992 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
994 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
999 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1004 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1007 for (i
= 0; i
< h
; i
++) {
1008 for (j
= 0; j
< w
; j
++) {
1010 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
1012 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
1015 fprintf(stderr
, "\n");
1020 const struct gl_texture_format
*
1021 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
1022 GLenum srcFormat
, GLenum srcType
)
1024 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1025 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
1027 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1028 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
1031 switch (internalFormat
) {
1032 case GL_COMPRESSED_RGB
:
1034 if (fxMesa
->HaveTexus2
) {
1035 return &_mesa_texformat_argb8888
;
1038 /* intentional fall through */
1041 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1042 return &_mesa_texformat_rgb565
;
1044 /* intentional fall through */
1049 return (allow32bpt
) ? &_mesa_texformat_argb8888
1050 : &_mesa_texformat_rgb565
;
1053 return &_mesa_texformat_argb4444
;
1054 case GL_COMPRESSED_RGBA
:
1056 if (fxMesa
->HaveTexus2
) {
1057 return &_mesa_texformat_argb8888
;
1060 /* intentional fall through */
1063 if ( srcFormat
== GL_BGRA
) {
1064 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1065 return &_mesa_texformat_argb8888
;
1067 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1068 return &_mesa_texformat_argb4444
;
1070 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1071 return &_mesa_texformat_argb1555
;
1074 /* intentional fall through */
1079 return (allow32bpt
) ? &_mesa_texformat_argb8888
1080 : &_mesa_texformat_argb4444
;
1084 case GL_INTENSITY12
:
1085 case GL_INTENSITY16
:
1086 case GL_COMPRESSED_INTENSITY
:
1087 return &_mesa_texformat_i8
;
1092 case GL_LUMINANCE12
:
1093 case GL_LUMINANCE16
:
1094 case GL_COMPRESSED_LUMINANCE
:
1095 return &_mesa_texformat_l8
;
1101 case GL_COMPRESSED_ALPHA
:
1102 return &_mesa_texformat_a8
;
1103 case GL_COLOR_INDEX
:
1104 case GL_COLOR_INDEX1_EXT
:
1105 case GL_COLOR_INDEX2_EXT
:
1106 case GL_COLOR_INDEX4_EXT
:
1107 case GL_COLOR_INDEX8_EXT
:
1108 case GL_COLOR_INDEX12_EXT
:
1109 case GL_COLOR_INDEX16_EXT
:
1110 return &_mesa_texformat_ci8
;
1112 case GL_LUMINANCE_ALPHA
:
1113 case GL_LUMINANCE4_ALPHA4
:
1114 case GL_LUMINANCE6_ALPHA2
:
1115 case GL_LUMINANCE8_ALPHA8
:
1116 case GL_LUMINANCE12_ALPHA4
:
1117 case GL_LUMINANCE12_ALPHA12
:
1118 case GL_LUMINANCE16_ALPHA16
:
1119 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1120 return &_mesa_texformat_al88
;
1124 return &_mesa_texformat_rgb565
;
1126 return &_mesa_texformat_argb1555
;
1127 /* GL_EXT_texture_compression_s3tc */
1129 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1132 return &_mesa_texformat_rgb_dxt1
;
1133 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1134 return &_mesa_texformat_rgba_dxt1
;
1135 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1138 return &_mesa_texformat_rgba_dxt3
;
1139 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1140 return &_mesa_texformat_rgba_dxt5
;
1141 /* GL_3DFX_texture_compression_FXT1 */
1142 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1143 return &_mesa_texformat_rgb_fxt1
;
1144 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1145 return &_mesa_texformat_rgba_fxt1
;
1147 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1153 static GrTextureFormat_t
1154 fxGlideFormat(GLint mesaFormat
)
1156 switch (mesaFormat
) {
1157 case MESA_FORMAT_I8
:
1158 return GR_TEXFMT_ALPHA_8
;
1159 case MESA_FORMAT_A8
:
1160 return GR_TEXFMT_ALPHA_8
;
1161 case MESA_FORMAT_L8
:
1162 return GR_TEXFMT_INTENSITY_8
;
1163 case MESA_FORMAT_CI8
:
1164 return GR_TEXFMT_P_8
;
1165 case MESA_FORMAT_AL88
:
1166 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1167 case MESA_FORMAT_RGB565
:
1168 return GR_TEXFMT_RGB_565
;
1169 case MESA_FORMAT_ARGB4444
:
1170 return GR_TEXFMT_ARGB_4444
;
1171 case MESA_FORMAT_ARGB1555
:
1172 return GR_TEXFMT_ARGB_1555
;
1173 case MESA_FORMAT_ARGB8888
:
1174 return GR_TEXFMT_ARGB_8888
;
1175 case MESA_FORMAT_RGB_FXT1
:
1176 case MESA_FORMAT_RGBA_FXT1
:
1177 return GR_TEXFMT_ARGB_CMP_FXT1
;
1178 case MESA_FORMAT_RGB_DXT1
:
1179 case MESA_FORMAT_RGBA_DXT1
:
1180 return GR_TEXFMT_ARGB_CMP_DXT1
;
1181 case MESA_FORMAT_RGBA_DXT3
:
1182 return GR_TEXFMT_ARGB_CMP_DXT3
;
1183 case MESA_FORMAT_RGBA_DXT5
:
1184 return GR_TEXFMT_ARGB_CMP_DXT5
;
1186 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1192 static FetchTexelFuncC
1193 fxFetchFunction(GLint mesaFormat
)
1195 switch (mesaFormat
) {
1196 case MESA_FORMAT_I8
:
1197 return &fetch_intensity8
;
1198 case MESA_FORMAT_A8
:
1199 return &fetch_alpha8
;
1200 case MESA_FORMAT_L8
:
1201 return &fetch_luminance8
;
1202 case MESA_FORMAT_CI8
:
1203 return &fetch_index8
;
1204 case MESA_FORMAT_AL88
:
1205 return &fetch_luminance8_alpha8
;
1206 case MESA_FORMAT_RGB565
:
1207 return &fetch_r5g6b5
;
1208 case MESA_FORMAT_ARGB4444
:
1209 return &fetch_r4g4b4a4
;
1210 case MESA_FORMAT_ARGB1555
:
1211 return &fetch_r5g5b5a1
;
1212 case MESA_FORMAT_ARGB8888
:
1213 return &fetch_a8r8g8b8
;
1214 case MESA_FORMAT_RGB_FXT1
:
1215 return &fetch_rgb_fxt1
;
1216 case MESA_FORMAT_RGBA_FXT1
:
1217 return &fetch_rgba_fxt1
;
1218 case MESA_FORMAT_RGB_DXT1
:
1219 return &fetch_rgb_dxt1
;
1220 case MESA_FORMAT_RGBA_DXT1
:
1221 return &fetch_rgba_dxt1
;
1222 case MESA_FORMAT_RGBA_DXT3
:
1223 return &fetch_rgba_dxt3
;
1224 case MESA_FORMAT_RGBA_DXT5
:
1225 return &fetch_rgba_dxt5
;
1227 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1234 adjust2DRatio (GLcontext
*ctx
,
1235 GLint xoffset
, GLint yoffset
,
1236 GLint width
, GLint height
,
1237 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1238 const struct gl_pixelstore_attrib
*packing
,
1239 tfxMipMapLevel
*mml
,
1240 struct gl_texture_image
*texImage
,
1244 const GLint newWidth
= width
* mml
->wScale
;
1245 const GLint newHeight
= height
* mml
->hScale
;
1248 if (!texImage
->IsCompressed
) {
1250 tempImage
= MALLOC(width
* height
* texelBytes
);
1255 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1256 texImage
->TexFormat
, tempImage
,
1257 0, 0, 0, /* dstX/Y/Zoffset */
1258 width
* texelBytes
, /* dstRowStride */
1259 0, /* dstImageStride */
1261 format
, type
, pixels
, packing
);
1264 /* compute address of dest subimage within the overal tex image */
1265 destAddr
= (GLubyte
*) texImage
->Data
1266 + (yoffset
* mml
->hScale
* mml
->width
1267 + xoffset
* mml
->wScale
) * texelBytes
;
1269 _mesa_rescale_teximage2d(texelBytes
,
1271 dstRowStride
, /* dst stride */
1273 newWidth
, newHeight
,
1274 tempImage
, destAddr
);
1276 const GLint rawBytes
= 4;
1277 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1281 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1285 /* unpack image, apply transfer ops and store in rawImage */
1286 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
1287 &_mesa_texformat_rgba8888_rev
, rawImage
,
1288 0, 0, 0, /* dstX/Y/Zoffset */
1289 width
* rawBytes
, /* dstRowStride */
1290 0, /* dstImageStride */
1292 format
, type
, pixels
, packing
);
1293 _mesa_rescale_teximage2d(rawBytes
,
1295 newWidth
* rawBytes
, /* dst stride */
1296 width
, height
, /* src */
1297 newWidth
, newHeight
, /* dst */
1298 rawImage
/*src*/, tempImage
/*dst*/ );
1299 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1300 texImage
->TexFormat
, texImage
->Data
,
1301 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1303 0, /* dstImageStride */
1304 newWidth
, newHeight
, 1,
1305 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1316 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1317 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1318 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1319 const struct gl_pixelstore_attrib
*packing
,
1320 struct gl_texture_object
*texObj
,
1321 struct gl_texture_image
*texImage
)
1323 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1325 tfxMipMapLevel
*mml
;
1326 GLint texelBytes
, dstRowStride
;
1328 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1329 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1330 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1331 texImage
->Width
, texImage
->Height
);
1334 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1335 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1339 if (!texObj
->DriverData
) {
1340 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1341 if (!texObj
->DriverData
) {
1342 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1346 ti
= fxTMGetTexInfo(texObj
);
1348 if (!texImage
->DriverData
) {
1349 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1350 if (!texImage
->DriverData
) {
1351 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1355 mml
= FX_MIPMAP_DATA(texImage
);
1357 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1358 &mml
->wScale
, &mml
->hScale
);
1360 mml
->width
= width
* mml
->wScale
;
1361 mml
->height
= height
* mml
->hScale
;
1363 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1364 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1365 if (!ctx
->Mesa_DXTn
&& texImage
->IsCompressed
) {
1366 switch (internalFormat
) {
1367 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1370 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1372 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1373 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1374 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1377 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1379 texImage
->IntFormat
= internalFormat
;
1383 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1384 GLenum texNapalm
= 0;
1385 if (internalFormat
== GL_COMPRESSED_RGB
) {
1386 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1387 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1388 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1391 texImage
->IntFormat
= internalFormat
= texNapalm
;
1392 texImage
->IsCompressed
= GL_TRUE
;
1397 /* choose the texture format */
1398 assert(ctx
->Driver
.ChooseTextureFormat
);
1399 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1400 internalFormat
, format
, type
);
1401 assert(texImage
->TexFormat
);
1402 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1403 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1405 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1407 /* allocate mipmap buffer */
1408 assert(!texImage
->Data
);
1409 if (texImage
->IsCompressed
) {
1410 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1415 dstRowStride
= _mesa_compressed_row_stride(internalFormat
, mml
->width
);
1416 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1418 dstRowStride
= mml
->width
* texelBytes
;
1419 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1421 if (!texImage
->Data
) {
1422 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1426 if (pixels
!= NULL
) {
1427 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1428 /* rescale image to overcome 1:8 aspect limitation */
1429 if (!adjust2DRatio(ctx
,
1432 format
, type
, pixels
,
1439 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1444 /* no rescaling needed */
1445 /* unpack image, apply transfer ops and store in texImage->Data */
1446 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1447 texImage
->TexFormat
, texImage
->Data
,
1448 0, 0, 0, /* dstX/Y/Zoffset */
1450 0, /* dstImageStride */
1452 format
, type
, pixels
, packing
);
1455 if (fxMesa
->HaveTexus2
) {
1457 GLuint texSize
= mml
->width
* mml
->height
;
1458 if (internalFormat
== GL_COMPRESSED_RGB
) {
1459 texNCC
= GR_TEXFMT_YIQ_422
;
1460 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1461 texNCC
= GR_TEXFMT_AYIQ_8422
;
1466 GLubyte
*tempImage
= MESA_PBUFFER_ALLOC(texSize
);
1468 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1471 txMip
.width
= mml
->width
;
1472 txMip
.height
= mml
->height
;
1474 txMip
.data
[0] = texImage
->Data
;
1475 pxMip
.data
[0] = tempImage
;
1476 fxMesa
->Glide
.txMipQuantize(&pxMip
, &txMip
, texNCC
, TX_DITHER_ERR
, TX_COMPRESSION_HEURISTIC
);
1478 fxMesa
->Glide
.txPalToNcc((GuNccTable
*)(&(ti
->palette
)), pxMip
.pal
);
1480 MESA_PBUFFER_FREE(texImage
->Data
);
1481 texImage
->Data
= tempImage
;
1482 mml
->glideFormat
= texNCC
;
1487 /* GL_SGIS_generate_mipmap */
1488 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1489 GLint mipWidth
, mipHeight
;
1490 tfxMipMapLevel
*mip
;
1491 struct gl_texture_image
*mipImage
;
1492 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1493 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1495 assert(!texImage
->IsCompressed
);
1497 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1498 mipWidth
= width
/ 2;
1502 mipHeight
= height
/ 2;
1506 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1509 _mesa_TexImage2D(target
, ++level
, internalFormat
,
1510 mipWidth
, mipHeight
, border
,
1513 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1514 mip
= FX_MIPMAP_DATA(mipImage
);
1515 _mesa_halve2x2_teximage2d(ctx
,
1518 mml
->width
, mml
->height
,
1519 texImage
->Data
, mipImage
->Data
);
1520 texImage
= mipImage
;
1528 ti
->info
.format
= mml
->glideFormat
;
1529 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1531 fxTexInvalidate(ctx
, texObj
);
1536 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1537 GLint xoffset
, GLint yoffset
,
1538 GLsizei width
, GLsizei height
,
1539 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1540 const struct gl_pixelstore_attrib
*packing
,
1541 struct gl_texture_object
*texObj
,
1542 struct gl_texture_image
*texImage
)
1544 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1546 tfxMipMapLevel
*mml
;
1547 GLint texelBytes
, dstRowStride
;
1549 /* [dBorca] Hack alert:
1550 * FX_TC_NCC not supported
1553 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1554 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1557 if (!texObj
->DriverData
) {
1558 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1562 ti
= fxTMGetTexInfo(texObj
);
1564 mml
= FX_MIPMAP_DATA(texImage
);
1567 assert(texImage
->Data
); /* must have an existing texture image! */
1568 assert(texImage
->Format
);
1570 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1571 if (texImage
->IsCompressed
) {
1572 dstRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, mml
->width
);
1574 dstRowStride
= mml
->width
* texelBytes
;
1577 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1578 /* need to rescale subimage to match mipmap level's rescale factors */
1579 if (!adjust2DRatio(ctx
,
1582 format
, type
, pixels
,
1589 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1594 /* no rescaling needed */
1595 texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->Format
,
1596 texImage
->TexFormat
, (GLubyte
*) texImage
->Data
,
1597 xoffset
, yoffset
, 0, /* dstX/Y/Zoffset */
1599 0, /* dstImageStride */
1601 format
, type
, pixels
, packing
);
1604 /* GL_SGIS_generate_mipmap */
1605 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1606 GLint mipWidth
, mipHeight
;
1607 tfxMipMapLevel
*mip
;
1608 struct gl_texture_image
*mipImage
;
1609 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1610 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1612 assert(!texImage
->IsCompressed
);
1614 width
= texImage
->Width
;
1615 height
= texImage
->Height
;
1616 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1617 mipWidth
= width
/ 2;
1621 mipHeight
= height
/ 2;
1625 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1629 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1630 mip
= FX_MIPMAP_DATA(mipImage
);
1631 _mesa_halve2x2_teximage2d(ctx
,
1634 mml
->width
, mml
->height
,
1635 texImage
->Data
, mipImage
->Data
);
1636 texImage
= mipImage
;
1643 if (ti
->validated
&& ti
->isInTM
&& !texObj
->GenerateMipmap
)
1644 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1646 fxTexInvalidate(ctx
, texObj
);
1651 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1652 GLint level
, GLint internalFormat
,
1653 GLsizei width
, GLsizei height
, GLint border
,
1654 GLsizei imageSize
, const GLvoid
*data
,
1655 struct gl_texture_object
*texObj
,
1656 struct gl_texture_image
*texImage
)
1658 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1660 tfxMipMapLevel
*mml
;
1662 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1663 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1664 texObj
->Name
, internalFormat
,
1668 assert(texImage
->IsCompressed
);
1670 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1671 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1675 if (!texObj
->DriverData
) {
1676 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1677 if (!texObj
->DriverData
) {
1678 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1682 ti
= fxTMGetTexInfo(texObj
);
1684 if (!texImage
->DriverData
) {
1685 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1686 if (!texImage
->DriverData
) {
1687 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1691 mml
= FX_MIPMAP_DATA(texImage
);
1693 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1694 &mml
->wScale
, &mml
->hScale
);
1696 mml
->width
= width
* mml
->wScale
;
1697 mml
->height
= height
* mml
->hScale
;
1700 /* choose the texture format */
1701 assert(ctx
->Driver
.ChooseTextureFormat
);
1702 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1703 internalFormat
, -1/*format*/, -1/*type*/);
1704 assert(texImage
->TexFormat
);
1706 /* Determine the appropriate Glide texel format,
1707 * given the user's internal texture format hint.
1709 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1711 /* allocate new storage for texture image, if needed */
1712 if (!texImage
->Data
) {
1713 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1718 texImage
->Data
= MESA_PBUFFER_ALLOC(texImage
->CompressedSize
);
1719 if (!texImage
->Data
) {
1720 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1725 /* save the texture data */
1726 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1727 /* [dBorca] Hack alert:
1728 * now we're screwed. We can't decompress,
1729 * unless we do it in HW (via textureBuffer).
1730 * We still have some chances:
1731 * 1) we got FXT1 textures - we CAN decompress, rescale for
1732 * aspectratio, then compress back.
1733 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1734 * Thus, we don't care about textureclamp and we could lower
1735 * MIN("uscale", "vscale") below 32. We still have to have
1736 * our data aligned inside a 8:1 rectangle.
1737 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1738 * we replicate the data over the padded area.
1739 * For now, we take 2) + 3) but texelfetchers will be wrong!
1741 GLuint srcRowStride
= _mesa_compressed_row_stride(internalFormat
, width
);
1743 GLuint destRowStride
= _mesa_compressed_row_stride(internalFormat
,
1746 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1747 destRowStride
, (mml
->height
+3) / 4,
1748 1, data
, srcRowStride
,
1750 ti
->padded
= GL_TRUE
;
1752 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1755 ti
->info
.format
= mml
->glideFormat
;
1756 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1758 /* GL_SGIS_generate_mipmap */
1759 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1760 assert(!texImage
->IsCompressed
);
1763 fxTexInvalidate(ctx
, texObj
);
1768 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1769 GLint level
, GLint xoffset
,
1770 GLint yoffset
, GLsizei width
,
1771 GLint height
, GLenum format
,
1772 GLsizei imageSize
, const GLvoid
*data
,
1773 struct gl_texture_object
*texObj
,
1774 struct gl_texture_image
*texImage
)
1776 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1778 tfxMipMapLevel
*mml
;
1779 GLint destRowStride
, srcRowStride
;
1783 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1784 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1787 ti
= fxTMGetTexInfo(texObj
);
1789 mml
= FX_MIPMAP_DATA(texImage
);
1792 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, width
);
1794 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1796 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1797 texImage
->IntFormat
,
1799 (GLubyte
*) texImage
->Data
);
1801 rows
= height
/ 4; /* hardcoded 4, but works for FXT1/DXTC */
1803 for (i
= 0; i
< rows
; i
++) {
1804 MEMCPY(dest
, data
, srcRowStride
);
1805 dest
+= destRowStride
;
1806 data
= (GLvoid
*)((GLuint
)data
+ (GLuint
)srcRowStride
);
1809 /* [dBorca] Hack alert:
1810 * see fxDDCompressedTexImage2D for caveats
1812 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1813 srcRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
, texImage
->Width
);
1815 destRowStride
= _mesa_compressed_row_stride(texImage
->IntFormat
,
1817 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1818 destRowStride
, mml
->height
/ 4,
1819 1, texImage
->Data
, destRowStride
,
1823 /* GL_SGIS_generate_mipmap */
1824 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1825 assert(!texImage
->IsCompressed
);
1828 if (ti
->validated
&& ti
->isInTM
)
1829 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1831 fxTexInvalidate(ctx
, texObj
);
1836 fxDDTexImage1D (GLcontext
*ctx
, GLenum target
, GLint level
,
1837 GLint internalFormat
, GLint width
, GLint border
,
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 fxDDTexImage2D(ctx
, target
, level
,
1844 internalFormat
, width
, 1, border
,
1845 format
, type
, pixels
,
1853 fxDDTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1856 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1857 const struct gl_pixelstore_attrib
*packing
,
1858 struct gl_texture_object
*texObj
,
1859 struct gl_texture_image
*texImage
)
1861 fxDDTexSubImage2D(ctx
, target
, level
,
1862 xoffset
, 0, width
, 1,
1863 format
, type
, pixels
,
1871 fxDDTestProxyTexImage (GLcontext
*ctx
, GLenum target
,
1872 GLint level
, GLint internalFormat
,
1873 GLenum format
, GLenum type
,
1874 GLint width
, GLint height
,
1875 GLint depth
, GLint border
)
1877 /* XXX todo - maybe through fxTexValidate() */
1878 return _mesa_test_proxy_teximage(ctx
, target
,
1879 level
, internalFormat
,
1889 * Need this to provide at least one external definition.
1892 extern int gl_fx_dummy_function_ddtex(void);
1894 gl_fx_dummy_function_ddtex(void)