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.
42 #include "main/enums.h"
43 #include "main/image.h"
44 #include "main/teximage.h"
45 #include "main/texstore.h"
46 #include "main/texformat.h"
47 #include "main/texcompress.h"
48 #include "main/texobj.h"
49 #include "main/texstore.h"
52 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
54 _mesa_halve2x2_teximage2d ( GLcontext
*ctx
,
55 struct gl_texture_image
*texImage
,
57 GLint srcWidth
, GLint srcHeight
,
58 const GLvoid
*srcImage
, GLvoid
*dstImage
)
61 GLint dstWidth
= srcWidth
/ 2;
62 GLint dstHeight
= srcHeight
/ 2;
63 GLint srcRowStride
= srcWidth
* bytesPerPixel
;
64 GLubyte
*src
= (GLubyte
*)srcImage
;
65 GLubyte
*dst
= dstImage
;
72 if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_RGB565
) {
73 _t
= GL_UNSIGNED_SHORT_5_6_5_REV
;
75 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
76 _t
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
78 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
79 _t
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
84 srcRowStride
= srcWidth
* bytesPerPixel
;
91 _s
= src
= MALLOC(srcRowStride
* srcHeight
);
92 _d
= dst
= MALLOC(dstWidth
* bytesPerPixel
* dstHeight
);
93 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
94 &_mesa_texformat_rgba8888_rev
, src
,
95 0, 0, 0, /* dstX/Y/Zoffset */
96 srcRowStride
, /* dstRowStride */
97 0, /* dstImageStride */
98 srcWidth
, srcHeight
, 1,
99 texImage
->_BaseFormat
, _t
,
100 srcImage
, &ctx
->DefaultPacking
);
103 if (srcHeight
== 1) {
104 for (i
= 0; i
< dstWidth
; i
++) {
105 for (k
= 0; k
< bytesPerPixel
; k
++) {
106 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
110 src
+= bytesPerPixel
;
112 } else if (srcWidth
== 1) {
113 for (j
= 0; j
< dstHeight
; j
++) {
114 for (k
= 0; k
< bytesPerPixel
; k
++) {
115 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
122 for (j
= 0; j
< dstHeight
; j
++) {
123 for (i
= 0; i
< dstWidth
; i
++) {
124 for (k
= 0; k
< bytesPerPixel
; k
++) {
128 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
132 src
+= bytesPerPixel
;
139 StoreTexImageFunc storeImage
=
140 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
144 storeImage(ctx
, 2, texImage
->_BaseFormat
,
145 texImage
->TexFormat
, dstImage
,
146 0, 0, 0, /* dstX/Y/Zoffset */
148 0, /* dstImageStride */
149 dstWidth
, dstHeight
, 1,
150 GL_BGRA
, CHAN_TYPE
, dst
, &ctx
->DefaultPacking
);
158 fxPrintTextureData(tfxTexInfo
* ti
)
160 fprintf(stderr
, "Texture Data:\n");
162 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
163 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
164 fprintf(stderr
, "\tSize: %d x %d\n",
165 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Width
,
166 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Height
);
169 fprintf(stderr
, "\tName: UNNAMED\n");
170 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
171 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
172 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
174 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
175 (unsigned) ti
->tm
[0]->endAddr
);
177 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
178 (unsigned) ti
->tm
[1]->endAddr
);
179 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
180 fprintf(stderr
, "\tFilters: min %d max %d\n",
181 (int) ti
->minFilt
, (int) ti
->maxFilt
);
182 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
184 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
185 fprintf(stderr
, "\t%s\n",
186 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
187 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
191 /************************************************************************/
192 /*************************** Texture Mapping ****************************/
193 /************************************************************************/
196 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
198 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
201 ti
= fxTMGetTexInfo(tObj
);
203 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
205 ti
->validated
= GL_FALSE
;
206 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
210 fxAllocTexObjData(fxMesaContext fxMesa
)
214 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
215 fprintf(stderr
, "fxAllocTexObjData: ERROR: out of memory !\n");
220 ti
->validated
= GL_FALSE
;
221 ti
->isInTM
= GL_FALSE
;
223 ti
->whichTMU
= FX_TMU_NONE
;
225 ti
->tm
[FX_TMU0
] = NULL
;
226 ti
->tm
[FX_TMU1
] = NULL
;
228 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
229 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
231 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
232 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
234 ti
->mmMode
= GR_MIPMAP_NEAREST
;
235 ti
->LODblend
= FXFALSE
;
241 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
243 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
246 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
247 fprintf(stderr
, "fxDDTexBind(%d, %x)\n", tObj
->Name
, (GLuint
)tObj
->DriverData
);
250 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
253 if (!tObj
->DriverData
) {
254 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
256 ti
= fxTMGetTexInfo(tObj
);
258 fxMesa
->texBindNumber
++;
259 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
261 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
265 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
266 const GLfloat
* param
)
268 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
270 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
272 fprintf(stderr
, "fxDDTexEnv(%x, %x)\n", pname
, (GLint
) (*param
));
274 fprintf(stderr
, "fxDDTexEnv(%x)\n", pname
);
277 /* apply any lod biasing right now */
278 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
279 GLfloat bias
= *param
;
280 CLAMP_SELF(bias
, -ctx
->Const
.MaxTextureLodBias
,
281 ctx
->Const
.MaxTextureLodBias
- 0.25);
283 grTexLodBiasValue(GR_TMU0
, bias
);
285 if (fxMesa
->haveTwoTMUs
) {
286 grTexLodBiasValue(GR_TMU1
, bias
);
291 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
295 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
296 GLenum pname
, const GLfloat
* params
)
298 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
299 GLenum param
= (GLenum
) (GLint
) params
[0];
302 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
303 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
304 tObj
->Name
, (GLuint
) tObj
->DriverData
,
305 _mesa_lookup_enum_by_nr(pname
),
306 _mesa_lookup_enum_by_nr(param
));
309 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
312 if (!tObj
->DriverData
)
313 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
314 ti
= fxTMGetTexInfo(tObj
);
317 case GL_TEXTURE_MIN_FILTER
:
320 ti
->mmMode
= GR_MIPMAP_DISABLE
;
321 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
322 ti
->LODblend
= FXFALSE
;
325 ti
->mmMode
= GR_MIPMAP_DISABLE
;
326 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
327 ti
->LODblend
= FXFALSE
;
329 case GL_NEAREST_MIPMAP_LINEAR
:
331 * currently Napalm can't do single-pass trilinear,
332 * because the way its combiners are set. So we fall back
333 * to GL_NEAREST_MIPMAP_NEAREST. We'll let true trilinear
334 * enabled for V2, V3.
336 if (!fxMesa
->HaveCmbExt
) {
337 if (fxMesa
->haveTwoTMUs
) {
338 ti
->mmMode
= GR_MIPMAP_NEAREST
;
339 ti
->LODblend
= FXTRUE
;
341 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
342 ti
->LODblend
= FXFALSE
;
344 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
347 case GL_NEAREST_MIPMAP_NEAREST
:
348 ti
->mmMode
= GR_MIPMAP_NEAREST
;
349 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
350 ti
->LODblend
= FXFALSE
;
352 case GL_LINEAR_MIPMAP_LINEAR
:
354 * currently Napalm can't do single-pass trilinear,
355 * because the way its combiners are set. So we fall back
356 * to GL_LINEAR_MIPMAP_NEAREST. We'll let true trilinear
357 * enabled for V2, V3.
359 if (!fxMesa
->HaveCmbExt
) {
360 if (fxMesa
->haveTwoTMUs
) {
361 ti
->mmMode
= GR_MIPMAP_NEAREST
;
362 ti
->LODblend
= FXTRUE
;
364 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
365 ti
->LODblend
= FXFALSE
;
367 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
370 case GL_LINEAR_MIPMAP_NEAREST
:
371 ti
->mmMode
= GR_MIPMAP_NEAREST
;
372 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
373 ti
->LODblend
= FXFALSE
;
378 fxTexInvalidate(ctx
, tObj
);
381 case GL_TEXTURE_MAG_FILTER
:
384 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
387 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
392 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
395 case GL_TEXTURE_WRAP_S
:
397 case GL_MIRRORED_REPEAT
:
398 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
400 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
401 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
403 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
406 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
411 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
414 case GL_TEXTURE_WRAP_T
:
416 case GL_MIRRORED_REPEAT
:
417 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
419 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
420 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
422 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
425 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
430 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
433 case GL_TEXTURE_BORDER_COLOR
:
437 case GL_TEXTURE_MIN_LOD
:
440 case GL_TEXTURE_MAX_LOD
:
443 case GL_TEXTURE_BASE_LEVEL
:
444 fxTexInvalidate(ctx
, tObj
);
446 case GL_TEXTURE_MAX_LEVEL
:
447 fxTexInvalidate(ctx
, tObj
);
456 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
458 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
459 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
461 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
462 fprintf(stderr
, "fxDDTexDel(%d, %p)\n", tObj
->Name
, (void *) ti
);
468 fxTMFreeTexture(fxMesa
, tObj
);
471 tObj
->DriverData
= NULL
;
473 /* Free mipmap images and the texture object itself */
474 _mesa_delete_texture_object(ctx
, tObj
);
479 * Allocate a new texture object.
480 * Called via ctx->Driver.NewTextureObject.
481 * Note: this function will be called during context creation to
482 * allocate the default texture objects.
484 struct gl_texture_object
*
485 fxDDNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
487 struct gl_texture_object
*obj
;
488 obj
= _mesa_new_texture_object(ctx
, name
, target
);
494 * Return true if texture is resident, false otherwise.
497 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
499 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
500 return (ti
&& ti
->isInTM
);
506 * Convert a gl_color_table texture palette to Glide's format.
509 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
511 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
512 GLint width
= table
->Size
;
516 ASSERT(table
->Type
== GL_UNSIGNED_BYTE
);
518 switch (table
->_BaseFormat
) {
520 for (i
= 0; i
< width
; i
++) {
525 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
527 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
529 for (i
= 0; i
< width
; i
++) {
534 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
536 return GR_TEXTABLE_PALETTE
;
538 for (i
= 0; i
< width
; i
++) {
541 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
543 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
544 case GL_LUMINANCE_ALPHA
:
545 for (i
= 0; i
< width
; i
++) {
546 r
= g
= b
= tableUB
[i
* 2 + 0];
547 a
= tableUB
[i
* 2 + 1];
548 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
550 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
553 for (i
= 0; i
< width
; i
++) {
554 r
= tableUB
[i
* 3 + 0];
555 g
= tableUB
[i
* 3 + 1];
556 b
= tableUB
[i
* 3 + 2];
558 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
560 return GR_TEXTABLE_PALETTE
;
562 for (i
= 0; i
< width
; i
++) {
563 r
= tableUB
[i
* 4 + 0];
564 g
= tableUB
[i
* 4 + 1];
565 b
= tableUB
[i
* 4 + 2];
566 a
= tableUB
[i
* 4 + 3];
567 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
569 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
575 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
577 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
580 /* per-texture palette */
582 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
583 fprintf(stderr
, "fxDDTexPalette(%d, %x)\n",
584 tObj
->Name
, (GLuint
) tObj
->DriverData
);
586 /* This might be a proxy texture. */
587 if (!tObj
->Palette
.Table
)
589 if (!tObj
->DriverData
)
590 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
591 ti
= fxTMGetTexInfo(tObj
);
592 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
593 fxTexInvalidate(ctx
, tObj
);
596 /* global texture palette */
597 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
598 fprintf(stderr
, "fxDDTexPalette(global)\n");
600 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
601 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
603 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
609 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
611 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
613 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
614 fprintf(stderr
, "fxDDTexUseGlbPalette(%d)\n", state
);
617 fxMesa
->haveGlobalPaletteTexture
= state
;
618 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
646 * w, h - source texture width and height
647 * lodlevel - Glide lod level token for the larger texture dimension
648 * ar - Glide aspect ratio token
649 * sscale - S scale factor used during triangle setup
650 * tscale - T scale factor used during triangle setup
651 * wscale - OpenGL -> Glide image width scale factor
652 * hscale - OpenGL -> Glide image height scale factor
655 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
656 float *sscale
, float *tscale
,
657 int *wscale
, int *hscale
)
659 int logw
, logh
, ws
, hs
;
661 GrAspectRatio_t aspectratio
;
667 l
= MAX2(logw
, logh
);
668 aspectratio
= logw
- logh
;
672 /* hardware only allows a maximum aspect ratio of 8x1, so handle
673 * |aspectratio| > 3 by scaling the image and using an 8x1 aspect
676 switch (aspectratio
) {
698 if (aspectratio
> 3) {
700 hs
= 1 << (aspectratio
- 3);
701 aspectratio
= GR_ASPECT_LOG2_8x1
;
702 } else /*if (aspectratio < -3)*/ {
704 ws
= 1 << (-aspectratio
- 3);
705 aspectratio
= GR_ASPECT_LOG2_1x8
;
732 fxIsTexSupported(GLenum target
, GLint internalFormat
,
733 const struct gl_texture_image
*image
)
735 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
739 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
743 if (image
->Border
> 0)
750 /**********************************************************************/
751 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
752 /**********************************************************************/
754 fxt1_decode_1 (const void *texture
, int width
,
755 int i
, int j
, unsigned char *rgba
);
757 /* Texel-fetch functions for software texturing and glGetTexImage().
758 * We should have been able to use some "standard" fetch functions (which
759 * may get defined in texutil.c) but we have to account for scaled texture
760 * images on tdfx hardware (the 8:1 aspect ratio limit).
761 * Hence, we need special functions here.
765 fetch_intensity8(const struct gl_texture_image
*texImage
,
766 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
768 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
769 const GLubyte
*texel
;
774 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
775 rgba
[RCOMP
] = *texel
;
776 rgba
[GCOMP
] = *texel
;
777 rgba
[BCOMP
] = *texel
;
778 rgba
[ACOMP
] = *texel
;
783 fetch_luminance8(const struct gl_texture_image
*texImage
,
784 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
786 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
787 const GLubyte
*texel
;
792 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
793 rgba
[RCOMP
] = *texel
;
794 rgba
[GCOMP
] = *texel
;
795 rgba
[BCOMP
] = *texel
;
801 fetch_alpha8(const struct gl_texture_image
*texImage
,
802 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
804 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
805 const GLubyte
*texel
;
810 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
814 rgba
[ACOMP
] = *texel
;
819 fetch_index8(const struct gl_texture_image
*texImage
,
820 GLint i
, GLint j
, GLint k
, GLchan
*indexOut
)
822 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
823 const GLubyte
*texel
;
828 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
834 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
835 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
837 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
838 const GLubyte
*texel
;
843 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
844 rgba
[RCOMP
] = texel
[0];
845 rgba
[GCOMP
] = texel
[0];
846 rgba
[BCOMP
] = texel
[0];
847 rgba
[ACOMP
] = texel
[1];
852 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
853 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
855 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
856 const GLushort
*texel
;
861 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
862 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
863 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
864 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
870 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
871 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
873 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
874 const GLushort
*texel
;
879 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
880 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
881 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
882 rgba
[BCOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
883 rgba
[ACOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
888 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
889 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
891 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
892 const GLushort
*texel
;
897 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
898 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 10) & 0x1F];
899 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 5) & 0x1F];
900 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
901 rgba
[ACOMP
] = (*texel
>> 15) * 255;
906 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
907 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
909 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
915 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
916 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
917 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
918 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
919 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
924 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
925 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
927 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
932 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
938 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
939 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
941 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
946 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
951 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
952 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
954 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
959 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
964 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
965 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
967 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
972 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
977 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
978 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
980 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
985 _mesa_texformat_rgba_dxt3
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
990 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
991 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
993 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
998 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1002 #if 0 /* break glass in case of emergency */
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");
1021 const struct gl_texture_format
*
1022 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
1023 GLenum srcFormat
, GLenum srcType
)
1025 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1026 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
1028 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1029 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
1032 switch (internalFormat
) {
1033 case GL_COMPRESSED_RGB
:
1034 /* intentional fall through */
1037 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1038 return &_mesa_texformat_rgb565
;
1040 /* intentional fall through */
1045 return (allow32bpt
) ? &_mesa_texformat_argb8888
1046 : &_mesa_texformat_rgb565
;
1049 return &_mesa_texformat_argb4444
;
1050 case GL_COMPRESSED_RGBA
:
1051 /* intentional fall through */
1054 if ( srcFormat
== GL_BGRA
) {
1055 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1056 return &_mesa_texformat_argb8888
;
1058 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1059 return &_mesa_texformat_argb4444
;
1061 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1062 return &_mesa_texformat_argb1555
;
1065 /* intentional fall through */
1070 return (allow32bpt
) ? &_mesa_texformat_argb8888
1071 : &_mesa_texformat_argb4444
;
1075 case GL_INTENSITY12
:
1076 case GL_INTENSITY16
:
1077 case GL_COMPRESSED_INTENSITY
:
1078 return &_mesa_texformat_i8
;
1083 case GL_LUMINANCE12
:
1084 case GL_LUMINANCE16
:
1085 case GL_COMPRESSED_LUMINANCE
:
1086 return &_mesa_texformat_l8
;
1092 case GL_COMPRESSED_ALPHA
:
1093 return &_mesa_texformat_a8
;
1094 case GL_COLOR_INDEX
:
1095 case GL_COLOR_INDEX1_EXT
:
1096 case GL_COLOR_INDEX2_EXT
:
1097 case GL_COLOR_INDEX4_EXT
:
1098 case GL_COLOR_INDEX8_EXT
:
1099 case GL_COLOR_INDEX12_EXT
:
1100 case GL_COLOR_INDEX16_EXT
:
1101 return &_mesa_texformat_ci8
;
1103 case GL_LUMINANCE_ALPHA
:
1104 case GL_LUMINANCE4_ALPHA4
:
1105 case GL_LUMINANCE6_ALPHA2
:
1106 case GL_LUMINANCE8_ALPHA8
:
1107 case GL_LUMINANCE12_ALPHA4
:
1108 case GL_LUMINANCE12_ALPHA12
:
1109 case GL_LUMINANCE16_ALPHA16
:
1110 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1111 return &_mesa_texformat_al88
;
1115 return &_mesa_texformat_rgb565
;
1117 return &_mesa_texformat_argb1555
;
1118 /* GL_EXT_texture_compression_s3tc */
1120 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1123 return &_mesa_texformat_rgb_dxt1
;
1124 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1125 return &_mesa_texformat_rgba_dxt1
;
1126 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1129 return &_mesa_texformat_rgba_dxt3
;
1130 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1131 return &_mesa_texformat_rgba_dxt5
;
1132 /* GL_3DFX_texture_compression_FXT1 */
1133 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1134 return &_mesa_texformat_rgb_fxt1
;
1135 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1136 return &_mesa_texformat_rgba_fxt1
;
1138 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1144 static GrTextureFormat_t
1145 fxGlideFormat(GLint mesaFormat
)
1147 switch (mesaFormat
) {
1148 case MESA_FORMAT_I8
:
1149 return GR_TEXFMT_ALPHA_8
;
1150 case MESA_FORMAT_A8
:
1151 return GR_TEXFMT_ALPHA_8
;
1152 case MESA_FORMAT_L8
:
1153 return GR_TEXFMT_INTENSITY_8
;
1154 case MESA_FORMAT_CI8
:
1155 return GR_TEXFMT_P_8
;
1156 case MESA_FORMAT_AL88
:
1157 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1158 case MESA_FORMAT_RGB565
:
1159 return GR_TEXFMT_RGB_565
;
1160 case MESA_FORMAT_ARGB4444
:
1161 return GR_TEXFMT_ARGB_4444
;
1162 case MESA_FORMAT_ARGB1555
:
1163 return GR_TEXFMT_ARGB_1555
;
1164 case MESA_FORMAT_ARGB8888
:
1165 return GR_TEXFMT_ARGB_8888
;
1166 case MESA_FORMAT_RGB_FXT1
:
1167 case MESA_FORMAT_RGBA_FXT1
:
1168 return GR_TEXFMT_ARGB_CMP_FXT1
;
1169 case MESA_FORMAT_RGB_DXT1
:
1170 case MESA_FORMAT_RGBA_DXT1
:
1171 return GR_TEXFMT_ARGB_CMP_DXT1
;
1172 case MESA_FORMAT_RGBA_DXT3
:
1173 return GR_TEXFMT_ARGB_CMP_DXT3
;
1174 case MESA_FORMAT_RGBA_DXT5
:
1175 return GR_TEXFMT_ARGB_CMP_DXT5
;
1177 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1183 static FetchTexelFuncC
1184 fxFetchFunction(GLint mesaFormat
)
1186 switch (mesaFormat
) {
1187 case MESA_FORMAT_I8
:
1188 return &fetch_intensity8
;
1189 case MESA_FORMAT_A8
:
1190 return &fetch_alpha8
;
1191 case MESA_FORMAT_L8
:
1192 return &fetch_luminance8
;
1193 case MESA_FORMAT_CI8
:
1194 return &fetch_index8
;
1195 case MESA_FORMAT_AL88
:
1196 return &fetch_luminance8_alpha8
;
1197 case MESA_FORMAT_RGB565
:
1198 return &fetch_r5g6b5
;
1199 case MESA_FORMAT_ARGB4444
:
1200 return &fetch_r4g4b4a4
;
1201 case MESA_FORMAT_ARGB1555
:
1202 return &fetch_r5g5b5a1
;
1203 case MESA_FORMAT_ARGB8888
:
1204 return &fetch_a8r8g8b8
;
1205 case MESA_FORMAT_RGB_FXT1
:
1206 return &fetch_rgb_fxt1
;
1207 case MESA_FORMAT_RGBA_FXT1
:
1208 return &fetch_rgba_fxt1
;
1209 case MESA_FORMAT_RGB_DXT1
:
1210 return &fetch_rgb_dxt1
;
1211 case MESA_FORMAT_RGBA_DXT1
:
1212 return &fetch_rgba_dxt1
;
1213 case MESA_FORMAT_RGBA_DXT3
:
1214 return &fetch_rgba_dxt3
;
1215 case MESA_FORMAT_RGBA_DXT5
:
1216 return &fetch_rgba_dxt5
;
1218 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1225 adjust2DRatio (GLcontext
*ctx
,
1226 GLint xoffset
, GLint yoffset
,
1227 GLint width
, GLint height
,
1228 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1229 const struct gl_pixelstore_attrib
*packing
,
1230 tfxMipMapLevel
*mml
,
1231 struct gl_texture_image
*texImage
,
1235 const GLint newWidth
= width
* mml
->wScale
;
1236 const GLint newHeight
= height
* mml
->hScale
;
1239 if (!texImage
->IsCompressed
) {
1241 StoreTexImageFunc storeImage
=
1242 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1244 tempImage
= MALLOC(width
* height
* texelBytes
);
1249 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1250 texImage
->TexFormat
, tempImage
,
1251 0, 0, 0, /* dstX/Y/Zoffset */
1252 width
* texelBytes
, /* dstRowStride */
1253 0, /* dstImageStride */
1255 format
, type
, pixels
, packing
);
1258 /* compute address of dest subimage within the overal tex image */
1259 destAddr
= (GLubyte
*) texImage
->Data
1260 + (yoffset
* mml
->hScale
* mml
->width
1261 + xoffset
* mml
->wScale
) * texelBytes
;
1263 _mesa_rescale_teximage2d(texelBytes
,
1265 dstRowStride
, /* dst stride */
1267 newWidth
, newHeight
,
1268 tempImage
, destAddr
);
1270 const GLint rawBytes
= 4;
1271 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1272 StoreTexImageFunc storeImage
=
1273 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1278 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1282 /* unpack image, apply transfer ops and store in rawImage */
1283 _mesa_texstore_rgba8888(ctx
, 2, GL_RGBA
,
1284 &_mesa_texformat_rgba8888_rev
, rawImage
,
1285 0, 0, 0, /* dstX/Y/Zoffset */
1286 width
* rawBytes
, /* dstRowStride */
1287 0, /* dstImageStride */
1289 format
, type
, pixels
, packing
);
1290 _mesa_rescale_teximage2d(rawBytes
,
1292 newWidth
* rawBytes
, /* dst stride */
1293 width
, height
, /* src */
1294 newWidth
, newHeight
, /* dst */
1295 rawImage
/*src*/, tempImage
/*dst*/ );
1296 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1297 texImage
->TexFormat
, texImage
->Data
,
1298 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1300 0, /* dstImageStride */
1301 newWidth
, newHeight
, 1,
1302 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1313 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1314 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1315 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1316 const struct gl_pixelstore_attrib
*packing
,
1317 struct gl_texture_object
*texObj
,
1318 struct gl_texture_image
*texImage
)
1320 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1322 tfxMipMapLevel
*mml
;
1323 GLint texelBytes
, dstRowStride
;
1325 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1326 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1327 texObj
->Name
, texImage
->InternalFormat
, format
, type
,
1328 texImage
->Width
, texImage
->Height
);
1331 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1332 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1336 if (!texObj
->DriverData
) {
1337 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1338 if (!texObj
->DriverData
) {
1339 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1343 ti
= fxTMGetTexInfo(texObj
);
1345 if (!texImage
->DriverData
) {
1346 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1347 if (!texImage
->DriverData
) {
1348 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1352 mml
= FX_MIPMAP_DATA(texImage
);
1354 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1355 &mml
->wScale
, &mml
->hScale
);
1357 mml
->width
= width
* mml
->wScale
;
1358 mml
->height
= height
* mml
->hScale
;
1360 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1361 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1362 if (!ctx
->Mesa_DXTn
&& texImage
->IsCompressed
) {
1363 switch (internalFormat
) {
1364 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1367 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1369 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1370 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1371 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1374 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1376 texImage
->InternalFormat
= internalFormat
;
1380 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1381 GLenum texNapalm
= 0;
1382 if (internalFormat
== GL_COMPRESSED_RGB
) {
1383 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1384 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1385 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1388 texImage
->InternalFormat
= internalFormat
= texNapalm
;
1389 texImage
->IsCompressed
= GL_TRUE
;
1394 /* choose the texture format */
1395 assert(ctx
->Driver
.ChooseTextureFormat
);
1396 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1397 internalFormat
, format
, type
);
1398 assert(texImage
->TexFormat
);
1399 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1400 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1402 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1404 /* allocate mipmap buffer */
1405 assert(!texImage
->Data
);
1406 if (texImage
->IsCompressed
) {
1407 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1412 dstRowStride
= _mesa_compressed_row_stride(internalFormat
, mml
->width
);
1413 texImage
->Data
= _mesa_malloc(texImage
->CompressedSize
);
1415 dstRowStride
= mml
->width
* texelBytes
;
1416 texImage
->Data
= _mesa_malloc(mml
->width
* mml
->height
* texelBytes
);
1418 if (!texImage
->Data
) {
1419 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1423 if (pixels
!= NULL
) {
1424 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1425 /* rescale image to overcome 1:8 aspect limitation */
1426 if (!adjust2DRatio(ctx
,
1429 format
, type
, pixels
,
1436 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1441 /* no rescaling needed */
1442 /* unpack image, apply transfer ops and store in texImage->Data */
1443 StoreTexImageFunc storeImage
=
1444 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1446 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1447 texImage
->TexFormat
, texImage
->Data
,
1448 0, 0, 0, /* dstX/Y/Zoffset */
1450 0, /* dstImageStride */
1452 format
, type
, pixels
, packing
);
1455 /* GL_SGIS_generate_mipmap */
1456 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1457 GLint mipWidth
, mipHeight
;
1458 tfxMipMapLevel
*mip
;
1459 struct gl_texture_image
*mipImage
;
1460 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1461 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1463 assert(!texImage
->IsCompressed
);
1465 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1466 mipWidth
= width
/ 2;
1470 mipHeight
= height
/ 2;
1474 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1477 _mesa_TexImage2D(target
, ++level
, internalFormat
,
1478 mipWidth
, mipHeight
, border
,
1481 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1482 mip
= FX_MIPMAP_DATA(mipImage
);
1483 _mesa_halve2x2_teximage2d(ctx
,
1486 mml
->width
, mml
->height
,
1487 texImage
->Data
, mipImage
->Data
);
1488 texImage
= mipImage
;
1496 ti
->info
.format
= mml
->glideFormat
;
1497 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1499 fxTexInvalidate(ctx
, texObj
);
1504 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1505 GLint xoffset
, GLint yoffset
,
1506 GLsizei width
, GLsizei height
,
1507 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1508 const struct gl_pixelstore_attrib
*packing
,
1509 struct gl_texture_object
*texObj
,
1510 struct gl_texture_image
*texImage
)
1512 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1514 tfxMipMapLevel
*mml
;
1515 GLint texelBytes
, dstRowStride
;
1517 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1518 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1521 if (!texObj
->DriverData
) {
1522 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1526 ti
= fxTMGetTexInfo(texObj
);
1528 mml
= FX_MIPMAP_DATA(texImage
);
1531 assert(texImage
->Data
); /* must have an existing texture image! */
1532 assert(texImage
->_BaseFormat
);
1534 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1535 if (texImage
->IsCompressed
) {
1536 dstRowStride
= _mesa_compressed_row_stride(texImage
->InternalFormat
, mml
->width
);
1538 dstRowStride
= mml
->width
* texelBytes
;
1541 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1542 /* need to rescale subimage to match mipmap level's rescale factors */
1543 if (!adjust2DRatio(ctx
,
1546 format
, type
, pixels
,
1553 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1558 /* no rescaling needed */
1559 StoreTexImageFunc storeImage
=
1560 _mesa_get_texstore_func(texImage
->TexFormat
->MesaFormat
);
1562 storeImage(ctx
, 2, texImage
->_BaseFormat
,
1563 texImage
->TexFormat
, (GLubyte
*) texImage
->Data
,
1564 xoffset
, yoffset
, 0, /* dstX/Y/Zoffset */
1566 0, /* dstImageStride */
1568 format
, type
, pixels
, packing
);
1571 /* GL_SGIS_generate_mipmap */
1572 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1573 GLint mipWidth
, mipHeight
;
1574 tfxMipMapLevel
*mip
;
1575 struct gl_texture_image
*mipImage
;
1576 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1577 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1579 assert(!texImage
->IsCompressed
);
1581 width
= texImage
->Width
;
1582 height
= texImage
->Height
;
1583 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1584 mipWidth
= width
/ 2;
1588 mipHeight
= height
/ 2;
1592 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1596 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1597 mip
= FX_MIPMAP_DATA(mipImage
);
1598 _mesa_halve2x2_teximage2d(ctx
,
1601 mml
->width
, mml
->height
,
1602 texImage
->Data
, mipImage
->Data
);
1603 texImage
= mipImage
;
1610 if (ti
->validated
&& ti
->isInTM
&& !texObj
->GenerateMipmap
)
1611 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1613 fxTexInvalidate(ctx
, texObj
);
1618 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1619 GLint level
, GLint internalFormat
,
1620 GLsizei width
, GLsizei height
, GLint border
,
1621 GLsizei imageSize
, const GLvoid
*data
,
1622 struct gl_texture_object
*texObj
,
1623 struct gl_texture_image
*texImage
)
1625 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1627 tfxMipMapLevel
*mml
;
1629 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1630 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1631 texObj
->Name
, internalFormat
,
1635 assert(texImage
->IsCompressed
);
1637 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1638 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1642 if (!texObj
->DriverData
) {
1643 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1644 if (!texObj
->DriverData
) {
1645 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1649 ti
= fxTMGetTexInfo(texObj
);
1651 if (!texImage
->DriverData
) {
1652 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1653 if (!texImage
->DriverData
) {
1654 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1658 mml
= FX_MIPMAP_DATA(texImage
);
1660 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1661 &mml
->wScale
, &mml
->hScale
);
1663 mml
->width
= width
* mml
->wScale
;
1664 mml
->height
= height
* mml
->hScale
;
1667 /* choose the texture format */
1668 assert(ctx
->Driver
.ChooseTextureFormat
);
1669 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1670 internalFormat
, -1/*format*/, -1/*type*/);
1671 assert(texImage
->TexFormat
);
1673 /* Determine the appropriate Glide texel format,
1674 * given the user's internal texture format hint.
1676 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1678 /* allocate new storage for texture image, if needed */
1679 if (!texImage
->Data
) {
1680 texImage
->CompressedSize
= _mesa_compressed_texture_size(ctx
,
1685 texImage
->Data
= _mesa_malloc(texImage
->CompressedSize
);
1686 if (!texImage
->Data
) {
1687 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1692 /* save the texture data */
1693 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1694 /* [dBorca] Hack alert:
1695 * now we're screwed. We can't decompress,
1696 * unless we do it in HW (via textureBuffer).
1697 * We still have some chances:
1698 * 1) we got FXT1 textures - we CAN decompress, rescale for
1699 * aspectratio, then compress back.
1700 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1701 * Thus, we don't care about textureclamp and we could lower
1702 * MIN("uscale", "vscale") below 32. We still have to have
1703 * our data aligned inside a 8:1 rectangle.
1704 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1705 * we replicate the data over the padded area.
1706 * For now, we take 2) + 3) but texelfetchers will be wrong!
1708 GLuint srcRowStride
= _mesa_compressed_row_stride(internalFormat
, width
);
1710 GLuint destRowStride
= _mesa_compressed_row_stride(internalFormat
,
1713 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1714 destRowStride
, (mml
->height
+3) / 4,
1715 1, data
, srcRowStride
,
1717 ti
->padded
= GL_TRUE
;
1719 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1722 ti
->info
.format
= mml
->glideFormat
;
1723 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1725 /* GL_SGIS_generate_mipmap */
1726 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1727 assert(!texImage
->IsCompressed
);
1730 fxTexInvalidate(ctx
, texObj
);
1735 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1736 GLint level
, GLint xoffset
,
1737 GLint yoffset
, GLsizei width
,
1738 GLint height
, GLenum format
,
1739 GLsizei imageSize
, const GLvoid
*data
,
1740 struct gl_texture_object
*texObj
,
1741 struct gl_texture_image
*texImage
)
1743 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1745 tfxMipMapLevel
*mml
;
1746 GLint destRowStride
, srcRowStride
;
1750 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1751 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1754 ti
= fxTMGetTexInfo(texObj
);
1756 mml
= FX_MIPMAP_DATA(texImage
);
1759 srcRowStride
= _mesa_compressed_row_stride(texImage
->InternalFormat
, width
);
1761 destRowStride
= _mesa_compressed_row_stride(texImage
->InternalFormat
,
1763 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1764 texImage
->InternalFormat
,
1766 (GLubyte
*) texImage
->Data
);
1768 rows
= height
/ 4; /* hardcoded 4, but works for FXT1/DXTC */
1770 for (i
= 0; i
< rows
; i
++) {
1771 MEMCPY(dest
, data
, srcRowStride
);
1772 dest
+= destRowStride
;
1773 data
= (GLvoid
*)((GLuint
)data
+ (GLuint
)srcRowStride
);
1776 /* [dBorca] Hack alert:
1777 * see fxDDCompressedTexImage2D for caveats
1779 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1780 srcRowStride
= _mesa_compressed_row_stride(texImage
->InternalFormat
, texImage
->Width
);
1782 destRowStride
= _mesa_compressed_row_stride(texImage
->InternalFormat
,
1784 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1785 destRowStride
, mml
->height
/ 4,
1786 1, texImage
->Data
, destRowStride
,
1790 /* GL_SGIS_generate_mipmap */
1791 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1792 assert(!texImage
->IsCompressed
);
1795 if (ti
->validated
&& ti
->isInTM
)
1796 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1798 fxTexInvalidate(ctx
, texObj
);
1803 fxDDTexImage1D (GLcontext
*ctx
, GLenum target
, GLint level
,
1804 GLint internalFormat
, GLint width
, GLint border
,
1805 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1806 const struct gl_pixelstore_attrib
*packing
,
1807 struct gl_texture_object
*texObj
,
1808 struct gl_texture_image
*texImage
)
1810 fxDDTexImage2D(ctx
, target
, level
,
1811 internalFormat
, width
, 1, border
,
1812 format
, type
, pixels
,
1820 fxDDTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1823 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1824 const struct gl_pixelstore_attrib
*packing
,
1825 struct gl_texture_object
*texObj
,
1826 struct gl_texture_image
*texImage
)
1828 fxDDTexSubImage2D(ctx
, target
, level
,
1829 xoffset
, 0, width
, 1,
1830 format
, type
, pixels
,
1838 fxDDTestProxyTexImage (GLcontext
*ctx
, GLenum target
,
1839 GLint level
, GLint internalFormat
,
1840 GLenum format
, GLenum type
,
1841 GLint width
, GLint height
,
1842 GLint depth
, GLint border
)
1844 /* XXX todo - maybe through fxTexValidate() */
1845 return _mesa_test_proxy_teximage(ctx
, target
,
1846 level
, internalFormat
,
1856 * Need this to provide at least one external definition.
1859 extern int gl_fx_dummy_function_ddtex(void);
1861 gl_fx_dummy_function_ddtex(void)