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/formats.h"
44 #include "main/image.h"
45 #include "main/teximage.h"
46 #include "main/texstore.h"
47 #include "main/texformat.h"
48 #include "main/texcompress.h"
49 #include "main/texobj.h"
50 #include "main/texstore.h"
53 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
55 _mesa_halve2x2_teximage2d ( GLcontext
*ctx
,
56 struct gl_texture_image
*texImage
,
58 GLint srcWidth
, GLint srcHeight
,
59 const GLvoid
*srcImage
, GLvoid
*dstImage
)
62 GLint dstWidth
= srcWidth
/ 2;
63 GLint dstHeight
= srcHeight
/ 2;
64 GLint srcRowStride
= srcWidth
* bytesPerPixel
;
65 GLubyte
*src
= (GLubyte
*)srcImage
;
66 GLubyte
*dst
= dstImage
;
73 if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_RGB565
) {
74 _t
= GL_UNSIGNED_SHORT_5_6_5_REV
;
76 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
77 _t
= GL_UNSIGNED_SHORT_4_4_4_4_REV
;
79 } else if (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
80 _t
= GL_UNSIGNED_SHORT_1_5_5_5_REV
;
85 srcRowStride
= srcWidth
* bytesPerPixel
;
92 _s
= src
= MALLOC(srcRowStride
* srcHeight
);
93 _d
= dst
= MALLOC(dstWidth
* bytesPerPixel
* dstHeight
);
94 _mesa_texstore(ctx
, 2, GL_RGBA
,
95 &_mesa_texformat_rgba8888_rev
, src
,
96 0, 0, 0, /* dstX/Y/Zoffset */
97 srcRowStride
, /* dstRowStride */
98 0, /* dstImageStride */
99 srcWidth
, srcHeight
, 1,
100 texImage
->_BaseFormat
, _t
,
101 srcImage
, &ctx
->DefaultPacking
);
104 if (srcHeight
== 1) {
105 for (i
= 0; i
< dstWidth
; i
++) {
106 for (k
= 0; k
< bytesPerPixel
; k
++) {
107 dst
[0] = (src
[0] + src
[bytesPerPixel
] + 1) / 2;
111 src
+= bytesPerPixel
;
113 } else if (srcWidth
== 1) {
114 for (j
= 0; j
< dstHeight
; j
++) {
115 for (k
= 0; k
< bytesPerPixel
; k
++) {
116 dst
[0] = (src
[0] + src
[srcRowStride
] + 1) / 2;
123 for (j
= 0; j
< dstHeight
; j
++) {
124 for (i
= 0; i
< dstWidth
; i
++) {
125 for (k
= 0; k
< bytesPerPixel
; k
++) {
129 src
[srcRowStride
+ bytesPerPixel
] + 2) / 4;
133 src
+= bytesPerPixel
;
142 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
143 texImage
->TexFormat
, dstImage
,
144 0, 0, 0, /* dstX/Y/Zoffset */
146 0, /* dstImageStride */
147 dstWidth
, dstHeight
, 1,
148 GL_BGRA
, CHAN_TYPE
, dst
, &ctx
->DefaultPacking
);
156 fxPrintTextureData(tfxTexInfo
* ti
)
158 fprintf(stderr
, "Texture Data:\n");
160 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
161 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
162 fprintf(stderr
, "\tSize: %d x %d\n",
163 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Width
,
164 ti
->tObj
->Image
[0][ti
->tObj
->BaseLevel
]->Height
);
167 fprintf(stderr
, "\tName: UNNAMED\n");
168 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
169 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
170 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
172 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
173 (unsigned) ti
->tm
[0]->endAddr
);
175 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
176 (unsigned) ti
->tm
[1]->endAddr
);
177 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
178 fprintf(stderr
, "\tFilters: min %d max %d\n",
179 (int) ti
->minFilt
, (int) ti
->maxFilt
);
180 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
182 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
183 fprintf(stderr
, "\t%s\n",
184 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
185 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
189 /************************************************************************/
190 /*************************** Texture Mapping ****************************/
191 /************************************************************************/
194 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
196 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
199 ti
= fxTMGetTexInfo(tObj
);
201 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
203 ti
->validated
= GL_FALSE
;
204 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
208 fxAllocTexObjData(fxMesaContext fxMesa
)
212 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
213 fprintf(stderr
, "fxAllocTexObjData: ERROR: out of memory !\n");
218 ti
->validated
= GL_FALSE
;
219 ti
->isInTM
= GL_FALSE
;
221 ti
->whichTMU
= FX_TMU_NONE
;
223 ti
->tm
[FX_TMU0
] = NULL
;
224 ti
->tm
[FX_TMU1
] = NULL
;
226 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
227 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
229 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
230 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
232 ti
->mmMode
= GR_MIPMAP_NEAREST
;
233 ti
->LODblend
= FXFALSE
;
239 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
241 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
244 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
245 fprintf(stderr
, "fxDDTexBind(%d, %x)\n", tObj
->Name
, (GLuint
)tObj
->DriverData
);
248 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
251 if (!tObj
->DriverData
) {
252 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
254 ti
= fxTMGetTexInfo(tObj
);
256 fxMesa
->texBindNumber
++;
257 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
259 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
263 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
264 const GLfloat
* param
)
266 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
268 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
270 fprintf(stderr
, "fxDDTexEnv(%x, %x)\n", pname
, (GLint
) (*param
));
272 fprintf(stderr
, "fxDDTexEnv(%x)\n", pname
);
275 /* apply any lod biasing right now */
276 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
277 GLfloat bias
= *param
;
279 -ctx
->Const
.MaxTextureLodBias
,
280 ctx
->Const
.MaxTextureLodBias
- 0.25);
282 grTexLodBiasValue(GR_TMU0
, bias
);
284 if (fxMesa
->haveTwoTMUs
) {
285 grTexLodBiasValue(GR_TMU1
, bias
);
290 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
294 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
295 GLenum pname
, const GLfloat
* params
)
297 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
298 GLenum param
= (GLenum
) (GLint
) params
[0];
301 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
302 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
303 tObj
->Name
, (GLuint
) tObj
->DriverData
,
304 _mesa_lookup_enum_by_nr(pname
),
305 _mesa_lookup_enum_by_nr(param
));
308 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
311 if (!tObj
->DriverData
)
312 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
313 ti
= fxTMGetTexInfo(tObj
);
316 case GL_TEXTURE_MIN_FILTER
:
319 ti
->mmMode
= GR_MIPMAP_DISABLE
;
320 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
321 ti
->LODblend
= FXFALSE
;
324 ti
->mmMode
= GR_MIPMAP_DISABLE
;
325 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
326 ti
->LODblend
= FXFALSE
;
328 case GL_NEAREST_MIPMAP_LINEAR
:
330 * currently Napalm can't do single-pass trilinear,
331 * because the way its combiners are set. So we fall back
332 * to GL_NEAREST_MIPMAP_NEAREST. We'll let true trilinear
333 * enabled for V2, V3.
335 if (!fxMesa
->HaveCmbExt
) {
336 if (fxMesa
->haveTwoTMUs
) {
337 ti
->mmMode
= GR_MIPMAP_NEAREST
;
338 ti
->LODblend
= FXTRUE
;
340 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
341 ti
->LODblend
= FXFALSE
;
343 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
346 case GL_NEAREST_MIPMAP_NEAREST
:
347 ti
->mmMode
= GR_MIPMAP_NEAREST
;
348 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
349 ti
->LODblend
= FXFALSE
;
351 case GL_LINEAR_MIPMAP_LINEAR
:
353 * currently Napalm can't do single-pass trilinear,
354 * because the way its combiners are set. So we fall back
355 * to GL_LINEAR_MIPMAP_NEAREST. We'll let true trilinear
356 * enabled for V2, V3.
358 if (!fxMesa
->HaveCmbExt
) {
359 if (fxMesa
->haveTwoTMUs
) {
360 ti
->mmMode
= GR_MIPMAP_NEAREST
;
361 ti
->LODblend
= FXTRUE
;
363 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
364 ti
->LODblend
= FXFALSE
;
366 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
369 case GL_LINEAR_MIPMAP_NEAREST
:
370 ti
->mmMode
= GR_MIPMAP_NEAREST
;
371 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
372 ti
->LODblend
= FXFALSE
;
377 fxTexInvalidate(ctx
, tObj
);
380 case GL_TEXTURE_MAG_FILTER
:
383 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
386 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
391 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
394 case GL_TEXTURE_WRAP_S
:
396 case GL_MIRRORED_REPEAT
:
397 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
399 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
400 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
402 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
405 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
410 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
413 case GL_TEXTURE_WRAP_T
:
415 case GL_MIRRORED_REPEAT
:
416 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
418 case GL_CLAMP_TO_BORDER
: /* no-no, but don't REPEAT, either */
419 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
421 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
424 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
429 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
432 case GL_TEXTURE_BORDER_COLOR
:
436 case GL_TEXTURE_MIN_LOD
:
439 case GL_TEXTURE_MAX_LOD
:
442 case GL_TEXTURE_BASE_LEVEL
:
443 fxTexInvalidate(ctx
, tObj
);
445 case GL_TEXTURE_MAX_LEVEL
:
446 fxTexInvalidate(ctx
, tObj
);
455 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
457 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
458 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
460 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
461 fprintf(stderr
, "fxDDTexDel(%d, %p)\n", tObj
->Name
, (void *) ti
);
467 fxTMFreeTexture(fxMesa
, tObj
);
470 tObj
->DriverData
= NULL
;
472 /* Free mipmap images and the texture object itself */
473 _mesa_delete_texture_object(ctx
, tObj
);
478 * Allocate a new texture object.
479 * Called via ctx->Driver.NewTextureObject.
480 * Note: this function will be called during context creation to
481 * allocate the default texture objects.
483 struct gl_texture_object
*
484 fxDDNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
486 struct gl_texture_object
*obj
;
487 obj
= _mesa_new_texture_object(ctx
, name
, target
);
493 * Return true if texture is resident, false otherwise.
496 fxDDIsTextureResident(GLcontext
*ctx
, struct gl_texture_object
*tObj
)
498 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
499 return (ti
&& ti
->isInTM
);
505 * Convert a gl_color_table texture palette to Glide's format.
508 convertPalette(const fxMesaContext fxMesa
, FxU32 data
[256], const struct gl_color_table
*table
)
510 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
511 GLint width
= table
->Size
;
515 ASSERT(table
->Type
== GL_UNSIGNED_BYTE
);
517 switch (table
->_BaseFormat
) {
519 for (i
= 0; i
< width
; i
++) {
524 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
526 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
528 for (i
= 0; i
< width
; i
++) {
533 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
535 return GR_TEXTABLE_PALETTE
;
537 for (i
= 0; i
< width
; i
++) {
540 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
542 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
543 case GL_LUMINANCE_ALPHA
:
544 for (i
= 0; i
< width
; i
++) {
545 r
= g
= b
= tableUB
[i
* 2 + 0];
546 a
= tableUB
[i
* 2 + 1];
547 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
549 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
552 for (i
= 0; i
< width
; i
++) {
553 r
= tableUB
[i
* 3 + 0];
554 g
= tableUB
[i
* 3 + 1];
555 b
= tableUB
[i
* 3 + 2];
557 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
559 return GR_TEXTABLE_PALETTE
;
561 for (i
= 0; i
< width
; i
++) {
562 r
= tableUB
[i
* 4 + 0];
563 g
= tableUB
[i
* 4 + 1];
564 b
= tableUB
[i
* 4 + 2];
565 a
= tableUB
[i
* 4 + 3];
566 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
568 return fxMesa
->HavePalExt
? GR_TEXTABLE_PALETTE_6666_EXT
: GR_TEXTABLE_PALETTE
;
574 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
576 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
579 /* per-texture palette */
581 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
582 fprintf(stderr
, "fxDDTexPalette(%d, %x)\n",
583 tObj
->Name
, (GLuint
) tObj
->DriverData
);
585 /* This might be a proxy texture. */
586 if (!tObj
->Palette
.Table
)
588 if (!tObj
->DriverData
)
589 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
590 ti
= fxTMGetTexInfo(tObj
);
591 ti
->paltype
= convertPalette(fxMesa
, ti
->palette
.data
, &tObj
->Palette
);
592 fxTexInvalidate(ctx
, tObj
);
595 /* global texture palette */
596 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
597 fprintf(stderr
, "fxDDTexPalette(global)\n");
599 fxMesa
->glbPalType
= convertPalette(fxMesa
, fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
600 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
602 grTexDownloadTable(fxMesa
->glbPalType
, &(fxMesa
->glbPalette
));
608 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
610 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
612 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
613 fprintf(stderr
, "fxDDTexUseGlbPalette(%d)\n", state
);
616 fxMesa
->haveGlobalPaletteTexture
= state
;
617 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
645 * w, h - source texture width and height
646 * lodlevel - Glide lod level token for the larger texture dimension
647 * ar - Glide aspect ratio token
648 * sscale - S scale factor used during triangle setup
649 * tscale - T scale factor used during triangle setup
650 * wscale - OpenGL -> Glide image width scale factor
651 * hscale - OpenGL -> Glide image height scale factor
654 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
655 float *sscale
, float *tscale
,
656 int *wscale
, int *hscale
)
658 int logw
, logh
, ws
, hs
;
660 GrAspectRatio_t aspectratio
;
666 l
= MAX2(logw
, logh
);
667 aspectratio
= logw
- logh
;
671 /* hardware only allows a maximum aspect ratio of 8x1, so handle
672 * |aspectratio| > 3 by scaling the image and using an 8x1 aspect
675 switch (aspectratio
) {
697 if (aspectratio
> 3) {
699 hs
= 1 << (aspectratio
- 3);
700 aspectratio
= GR_ASPECT_LOG2_8x1
;
701 } else /*if (aspectratio < -3)*/ {
703 ws
= 1 << (-aspectratio
- 3);
704 aspectratio
= GR_ASPECT_LOG2_1x8
;
731 fxIsTexSupported(GLenum target
, GLint internalFormat
,
732 const struct gl_texture_image
*image
)
734 if ((target
!= GL_TEXTURE_1D
) && (target
!= GL_TEXTURE_2D
))
738 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
742 if (image
->Border
> 0)
749 /**********************************************************************/
750 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
751 /**********************************************************************/
753 fxt1_decode_1 (const void *texture
, int width
,
754 int i
, int j
, unsigned char *rgba
);
756 /* Texel-fetch functions for software texturing and glGetTexImage().
757 * We should have been able to use some "standard" fetch functions (which
758 * may get defined in texutil.c) but we have to account for scaled texture
759 * images on tdfx hardware (the 8:1 aspect ratio limit).
760 * Hence, we need special functions here.
764 fetch_intensity8(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
;
774 rgba
[RCOMP
] = *texel
;
775 rgba
[GCOMP
] = *texel
;
776 rgba
[BCOMP
] = *texel
;
777 rgba
[ACOMP
] = *texel
;
782 fetch_luminance8(const struct gl_texture_image
*texImage
,
783 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
785 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
786 const GLubyte
*texel
;
791 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
792 rgba
[RCOMP
] = *texel
;
793 rgba
[GCOMP
] = *texel
;
794 rgba
[BCOMP
] = *texel
;
800 fetch_alpha8(const struct gl_texture_image
*texImage
,
801 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
803 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
804 const GLubyte
*texel
;
809 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
813 rgba
[ACOMP
] = *texel
;
818 fetch_index8(const struct gl_texture_image
*texImage
,
819 GLint i
, GLint j
, GLint k
, GLchan
*indexOut
)
821 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
822 const GLubyte
*texel
;
827 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
833 fetch_luminance8_alpha8(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 GLubyte
*texel
;
842 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
843 rgba
[RCOMP
] = texel
[0];
844 rgba
[GCOMP
] = texel
[0];
845 rgba
[BCOMP
] = texel
[0];
846 rgba
[ACOMP
] = texel
[1];
851 fetch_r5g6b5(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_6
[(*texel
>> 5) & 0x3F];
863 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
869 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
870 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
872 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
873 const GLushort
*texel
;
878 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
879 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
880 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
881 rgba
[BCOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
882 rgba
[ACOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
887 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
888 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
890 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
891 const GLushort
*texel
;
896 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
897 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 10) & 0x1F];
898 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 5) & 0x1F];
899 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
900 rgba
[ACOMP
] = (*texel
>> 15) * 255;
905 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
906 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
908 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
914 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
915 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
916 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
917 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
918 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
923 fetch_rgb_fxt1(const struct gl_texture_image
*texImage
,
924 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
926 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
931 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
937 fetch_rgba_fxt1(const struct gl_texture_image
*texImage
,
938 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
940 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
945 fxt1_decode_1(texImage
->Data
, mml
->width
, i
, j
, rgba
);
950 fetch_rgb_dxt1(const struct gl_texture_image
*texImage
,
951 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
953 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
958 _mesa_texformat_rgb_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
963 fetch_rgba_dxt1(const struct gl_texture_image
*texImage
,
964 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
966 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
971 _mesa_texformat_rgba_dxt1
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
976 fetch_rgba_dxt3(const struct gl_texture_image
*texImage
,
977 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
979 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
984 _mesa_texformat_rgba_dxt3
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
989 fetch_rgba_dxt5(const struct gl_texture_image
*texImage
,
990 GLint i
, GLint j
, GLint k
, GLchan
*rgba
)
992 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
997 _mesa_texformat_rgba_dxt5
.FetchTexel2D(texImage
, i
, j
, k
, rgba
);
1001 #if 0 /* break glass in case of emergency */
1003 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1006 for (i
= 0; i
< h
; i
++) {
1007 for (j
= 0; j
< w
; j
++) {
1009 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
1011 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
1014 fprintf(stderr
, "\n");
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
:
1033 /* intentional fall through */
1036 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1037 return MESA_FORMAT_RGB565
;
1039 /* intentional fall through */
1044 return (allow32bpt
) ? MESA_FORMAT_ARGB8888
1045 : MESA_FORMAT_RGB565
;
1048 return MESA_FORMAT_ARGB4444
;
1049 case GL_COMPRESSED_RGBA
:
1050 /* intentional fall through */
1053 if ( srcFormat
== GL_BGRA
) {
1054 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
1055 return MESA_FORMAT_ARGB8888
;
1057 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1058 return MESA_FORMAT_ARGB4444
;
1060 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1061 return MESA_FORMAT_ARGB1555
;
1064 /* intentional fall through */
1069 return (allow32bpt
) ? MESA_FORMAT_ARGB8888
1070 : MESA_FORMAT_ARGB4444
;
1074 case GL_INTENSITY12
:
1075 case GL_INTENSITY16
:
1076 case GL_COMPRESSED_INTENSITY
:
1077 return MESA_FORMAT_I8
;
1082 case GL_LUMINANCE12
:
1083 case GL_LUMINANCE16
:
1084 case GL_COMPRESSED_LUMINANCE
:
1085 return MESA_FORMAT_L8
;
1091 case GL_COMPRESSED_ALPHA
:
1092 return MESA_FORMAT_A8
;
1093 case GL_COLOR_INDEX
:
1094 case GL_COLOR_INDEX1_EXT
:
1095 case GL_COLOR_INDEX2_EXT
:
1096 case GL_COLOR_INDEX4_EXT
:
1097 case GL_COLOR_INDEX8_EXT
:
1098 case GL_COLOR_INDEX12_EXT
:
1099 case GL_COLOR_INDEX16_EXT
:
1100 return MESA_FORMAT_CI8
;
1102 case GL_LUMINANCE_ALPHA
:
1103 case GL_LUMINANCE4_ALPHA4
:
1104 case GL_LUMINANCE6_ALPHA2
:
1105 case GL_LUMINANCE8_ALPHA8
:
1106 case GL_LUMINANCE12_ALPHA4
:
1107 case GL_LUMINANCE12_ALPHA12
:
1108 case GL_LUMINANCE16_ALPHA16
:
1109 case GL_COMPRESSED_LUMINANCE_ALPHA
:
1110 return MESA_FORMAT_AL88
;
1114 return MESA_FORMAT_RGB565
;
1116 return MESA_FORMAT_ARGB1555
;
1117 /* GL_EXT_texture_compression_s3tc */
1119 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1122 return MESA_FORMAT_RGB_DXT1
;
1123 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1124 return MESA_FORMAT_RGBA_DXT1
;
1125 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1128 return MESA_FORMAT_RGBA_DXT3
;
1129 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1130 return MESA_FORMAT_RGBA_DXT5
;
1131 /* GL_3DFX_texture_compression_FXT1 */
1132 case GL_COMPRESSED_RGB_FXT1_3DFX
:
1133 return MESA_FORMAT_RGB_FXT1
;
1134 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
1135 return MESA_FORMAT_RGBA_FXT1
;
1137 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
1138 return MESA_FORMAT_NONE
;
1143 static GrTextureFormat_t
1144 fxGlideFormat(GLint mesaFormat
)
1146 switch (mesaFormat
) {
1147 case MESA_FORMAT_I8
:
1148 return GR_TEXFMT_ALPHA_8
;
1149 case MESA_FORMAT_A8
:
1150 return GR_TEXFMT_ALPHA_8
;
1151 case MESA_FORMAT_L8
:
1152 return GR_TEXFMT_INTENSITY_8
;
1153 case MESA_FORMAT_CI8
:
1154 return GR_TEXFMT_P_8
;
1155 case MESA_FORMAT_AL88
:
1156 return GR_TEXFMT_ALPHA_INTENSITY_88
;
1157 case MESA_FORMAT_RGB565
:
1158 return GR_TEXFMT_RGB_565
;
1159 case MESA_FORMAT_ARGB4444
:
1160 return GR_TEXFMT_ARGB_4444
;
1161 case MESA_FORMAT_ARGB1555
:
1162 return GR_TEXFMT_ARGB_1555
;
1163 case MESA_FORMAT_ARGB8888
:
1164 return GR_TEXFMT_ARGB_8888
;
1165 case MESA_FORMAT_RGB_FXT1
:
1166 case MESA_FORMAT_RGBA_FXT1
:
1167 return GR_TEXFMT_ARGB_CMP_FXT1
;
1168 case MESA_FORMAT_RGB_DXT1
:
1169 case MESA_FORMAT_RGBA_DXT1
:
1170 return GR_TEXFMT_ARGB_CMP_DXT1
;
1171 case MESA_FORMAT_RGBA_DXT3
:
1172 return GR_TEXFMT_ARGB_CMP_DXT3
;
1173 case MESA_FORMAT_RGBA_DXT5
:
1174 return GR_TEXFMT_ARGB_CMP_DXT5
;
1176 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1182 static FetchTexelFuncC
1183 fxFetchFunction(GLint mesaFormat
)
1185 switch (mesaFormat
) {
1186 case MESA_FORMAT_I8
:
1187 return &fetch_intensity8
;
1188 case MESA_FORMAT_A8
:
1189 return &fetch_alpha8
;
1190 case MESA_FORMAT_L8
:
1191 return &fetch_luminance8
;
1192 case MESA_FORMAT_CI8
:
1193 return &fetch_index8
;
1194 case MESA_FORMAT_AL88
:
1195 return &fetch_luminance8_alpha8
;
1196 case MESA_FORMAT_RGB565
:
1197 return &fetch_r5g6b5
;
1198 case MESA_FORMAT_ARGB4444
:
1199 return &fetch_r4g4b4a4
;
1200 case MESA_FORMAT_ARGB1555
:
1201 return &fetch_r5g5b5a1
;
1202 case MESA_FORMAT_ARGB8888
:
1203 return &fetch_a8r8g8b8
;
1204 case MESA_FORMAT_RGB_FXT1
:
1205 return &fetch_rgb_fxt1
;
1206 case MESA_FORMAT_RGBA_FXT1
:
1207 return &fetch_rgba_fxt1
;
1208 case MESA_FORMAT_RGB_DXT1
:
1209 return &fetch_rgb_dxt1
;
1210 case MESA_FORMAT_RGBA_DXT1
:
1211 return &fetch_rgba_dxt1
;
1212 case MESA_FORMAT_RGBA_DXT3
:
1213 return &fetch_rgba_dxt3
;
1214 case MESA_FORMAT_RGBA_DXT5
:
1215 return &fetch_rgba_dxt5
;
1217 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1224 adjust2DRatio (GLcontext
*ctx
,
1225 GLint xoffset
, GLint yoffset
,
1226 GLint width
, GLint height
,
1227 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1228 const struct gl_pixelstore_attrib
*packing
,
1229 tfxMipMapLevel
*mml
,
1230 struct gl_texture_image
*texImage
,
1234 const GLint newWidth
= width
* mml
->wScale
;
1235 const GLint newHeight
= height
* mml
->hScale
;
1238 if (!_mesa_is_format_compressed(texImage
->TexFormat
)) {
1241 tempImage
= MALLOC(width
* height
* texelBytes
);
1246 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1247 texImage
->TexFormat
, tempImage
,
1248 0, 0, 0, /* dstX/Y/Zoffset */
1249 width
* texelBytes
, /* dstRowStride */
1250 0, /* dstImageStride */
1252 format
, type
, pixels
, packing
);
1255 /* compute address of dest subimage within the overal tex image */
1256 destAddr
= (GLubyte
*) texImage
->Data
1257 + (yoffset
* mml
->hScale
* mml
->width
1258 + xoffset
* mml
->wScale
) * texelBytes
;
1260 _mesa_rescale_teximage2d(texelBytes
,
1262 dstRowStride
, /* dst stride */
1264 newWidth
, newHeight
,
1265 tempImage
, destAddr
);
1267 const GLint rawBytes
= 4;
1268 GLvoid
*rawImage
= MALLOC(width
* height
* rawBytes
);
1273 tempImage
= MALLOC(newWidth
* newHeight
* rawBytes
);
1277 /* unpack image, apply transfer ops and store in rawImage */
1278 _mesa_texstore(ctx
, 2, GL_RGBA
,
1279 &_mesa_texformat_rgba8888_rev
, rawImage
,
1280 0, 0, 0, /* dstX/Y/Zoffset */
1281 width
* rawBytes
, /* dstRowStride */
1282 0, /* dstImageStride */
1284 format
, type
, pixels
, packing
);
1285 _mesa_rescale_teximage2d(rawBytes
,
1287 newWidth
* rawBytes
, /* dst stride */
1288 width
, height
, /* src */
1289 newWidth
, newHeight
, /* dst */
1290 rawImage
/*src*/, tempImage
/*dst*/ );
1291 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1292 texImage
->TexFormat
, texImage
->Data
,
1293 xoffset
* mml
->wScale
, yoffset
* mml
->hScale
, 0, /* dstX/Y/Zoffset */
1295 0, /* dstImageStride */
1296 newWidth
, newHeight
, 1,
1297 GL_RGBA
, CHAN_TYPE
, tempImage
, &ctx
->DefaultPacking
);
1308 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1309 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1310 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1311 const struct gl_pixelstore_attrib
*packing
,
1312 struct gl_texture_object
*texObj
,
1313 struct gl_texture_image
*texImage
)
1315 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1317 tfxMipMapLevel
*mml
;
1318 GLint texelBytes
, dstRowStride
;
1320 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1321 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1322 texObj
->Name
, texImage
->InternalFormat
, format
, type
,
1323 texImage
->Width
, texImage
->Height
);
1326 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1327 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1331 if (!texObj
->DriverData
) {
1332 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1333 if (!texObj
->DriverData
) {
1334 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1338 ti
= fxTMGetTexInfo(texObj
);
1340 if (!texImage
->DriverData
) {
1341 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1342 if (!texImage
->DriverData
) {
1343 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1347 mml
= FX_MIPMAP_DATA(texImage
);
1349 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1350 &mml
->wScale
, &mml
->hScale
);
1352 mml
->width
= width
* mml
->wScale
;
1353 mml
->height
= height
* mml
->hScale
;
1355 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1356 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1357 if (!ctx
->Mesa_DXTn
&& _mesa_is_format_compressed(texImage
->TexFormat
)) {
1358 switch (internalFormat
) {
1359 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
1362 internalFormat
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1364 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
1365 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
1366 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
1369 internalFormat
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1371 texImage
->InternalFormat
= internalFormat
;
1375 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
) {
1376 GLenum texNapalm
= 0;
1377 if (internalFormat
== GL_COMPRESSED_RGB
) {
1378 texNapalm
= GL_COMPRESSED_RGB_FXT1_3DFX
;
1379 } else if (internalFormat
== GL_COMPRESSED_RGBA
) {
1380 texNapalm
= GL_COMPRESSED_RGBA_FXT1_3DFX
;
1383 texImage
->InternalFormat
= internalFormat
= texNapalm
;
1388 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
1389 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1391 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1393 /* allocate mipmap buffer */
1394 assert(!texImage
->Data
);
1395 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
1396 texImage
->CompressedSize
= _mesa_format_image_size(texImage
->TexFormat
,
1399 dstRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, mml
->width
);
1400 texImage
->Data
= _mesa_malloc(texImage
->CompressedSize
);
1402 dstRowStride
= mml
->width
* texelBytes
;
1403 texImage
->Data
= _mesa_malloc(mml
->width
* mml
->height
* texelBytes
);
1405 if (!texImage
->Data
) {
1406 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1410 if (pixels
!= NULL
) {
1411 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1412 /* rescale image to overcome 1:8 aspect limitation */
1413 if (!adjust2DRatio(ctx
,
1416 format
, type
, pixels
,
1423 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1428 /* no rescaling needed */
1429 /* unpack image, apply transfer ops and store in texImage->Data */
1430 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1431 texImage
->TexFormat
, texImage
->Data
,
1432 0, 0, 0, /* dstX/Y/Zoffset */
1434 0, /* dstImageStride */
1436 format
, type
, pixels
, packing
);
1439 /* GL_SGIS_generate_mipmap */
1440 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1441 GLint mipWidth
, mipHeight
;
1442 tfxMipMapLevel
*mip
;
1443 struct gl_texture_image
*mipImage
;
1444 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1445 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1447 assert(!_mesa_is_format_compressed(texImage
->TexFormat
));
1449 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1450 mipWidth
= width
/ 2;
1454 mipHeight
= height
/ 2;
1458 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1461 _mesa_TexImage2D(target
, ++level
, internalFormat
,
1462 mipWidth
, mipHeight
, border
,
1465 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1466 mip
= FX_MIPMAP_DATA(mipImage
);
1467 _mesa_halve2x2_teximage2d(ctx
,
1470 mml
->width
, mml
->height
,
1471 texImage
->Data
, mipImage
->Data
);
1472 texImage
= mipImage
;
1480 ti
->info
.format
= mml
->glideFormat
;
1481 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1483 fxTexInvalidate(ctx
, texObj
);
1488 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1489 GLint xoffset
, GLint yoffset
,
1490 GLsizei width
, GLsizei height
,
1491 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1492 const struct gl_pixelstore_attrib
*packing
,
1493 struct gl_texture_object
*texObj
,
1494 struct gl_texture_image
*texImage
)
1496 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1498 tfxMipMapLevel
*mml
;
1499 GLint texelBytes
, dstRowStride
;
1501 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1502 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1505 if (!texObj
->DriverData
) {
1506 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1510 ti
= fxTMGetTexInfo(texObj
);
1512 mml
= FX_MIPMAP_DATA(texImage
);
1515 assert(texImage
->Data
); /* must have an existing texture image! */
1516 assert(texImage
->_BaseFormat
);
1518 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
1519 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
1520 dstRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, mml
->width
);
1522 dstRowStride
= mml
->width
* texelBytes
;
1525 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1526 /* need to rescale subimage to match mipmap level's rescale factors */
1527 if (!adjust2DRatio(ctx
,
1530 format
, type
, pixels
,
1537 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1542 /* no rescaling needed */
1543 _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
1544 texImage
->TexFormat
, (GLubyte
*) texImage
->Data
,
1545 xoffset
, yoffset
, 0, /* dstX/Y/Zoffset */
1547 0, /* dstImageStride */
1549 format
, type
, pixels
, packing
);
1552 /* GL_SGIS_generate_mipmap */
1553 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1554 GLint mipWidth
, mipHeight
;
1555 tfxMipMapLevel
*mip
;
1556 struct gl_texture_image
*mipImage
;
1557 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1558 const GLint maxLevels
= _mesa_max_texture_levels(ctx
, texObj
->Target
);
1560 assert(!_mesa_is_format_compressed(texImage
->TexFormat
));
1562 width
= texImage
->Width
;
1563 height
= texImage
->Height
;
1564 while (level
< texObj
->MaxLevel
&& level
< maxLevels
- 1) {
1565 mipWidth
= width
/ 2;
1569 mipHeight
= height
/ 2;
1573 if ((mipWidth
== width
) && (mipHeight
== height
)) {
1577 mipImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1578 mip
= FX_MIPMAP_DATA(mipImage
);
1579 _mesa_halve2x2_teximage2d(ctx
,
1582 mml
->width
, mml
->height
,
1583 texImage
->Data
, mipImage
->Data
);
1584 texImage
= mipImage
;
1591 if (ti
->validated
&& ti
->isInTM
&& !texObj
->GenerateMipmap
)
1592 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1594 fxTexInvalidate(ctx
, texObj
);
1599 fxDDCompressedTexImage2D (GLcontext
*ctx
, GLenum target
,
1600 GLint level
, GLint internalFormat
,
1601 GLsizei width
, GLsizei height
, GLint border
,
1602 GLsizei imageSize
, const GLvoid
*data
,
1603 struct gl_texture_object
*texObj
,
1604 struct gl_texture_image
*texImage
)
1606 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1608 tfxMipMapLevel
*mml
;
1610 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1611 fprintf(stderr
, "fxDDCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1612 texObj
->Name
, internalFormat
,
1616 assert(_mesa_is_format_compressed(texImage
->TexFormat
));
1618 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1619 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDCompressedTexImg()\n");
1623 if (!texObj
->DriverData
) {
1624 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1625 if (!texObj
->DriverData
) {
1626 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1630 ti
= fxTMGetTexInfo(texObj
);
1632 if (!texImage
->DriverData
) {
1633 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1634 if (!texImage
->DriverData
) {
1635 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1639 mml
= FX_MIPMAP_DATA(texImage
);
1641 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1642 &mml
->wScale
, &mml
->hScale
);
1644 mml
->width
= width
* mml
->wScale
;
1645 mml
->height
= height
* mml
->hScale
;
1647 /* Determine the appropriate Glide texel format,
1648 * given the user's internal texture format hint.
1650 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1652 /* allocate new storage for texture image, if needed */
1653 if (!texImage
->Data
) {
1654 texImage
->CompressedSize
= _mesa_format_image_size(texImage
->TexFormat
,
1657 texImage
->Data
= _mesa_malloc(texImage
->CompressedSize
);
1658 if (!texImage
->Data
) {
1659 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
1664 /* save the texture data */
1665 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1666 /* [dBorca] Hack alert:
1667 * now we're screwed. We can't decompress,
1668 * unless we do it in HW (via textureBuffer).
1669 * We still have some chances:
1670 * 1) we got FXT1 textures - we CAN decompress, rescale for
1671 * aspectratio, then compress back.
1672 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1673 * Thus, we don't care about textureclamp and we could lower
1674 * MIN("uscale", "vscale") below 32. We still have to have
1675 * our data aligned inside a 8:1 rectangle.
1676 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1677 * we replicate the data over the padded area.
1678 * For now, we take 2) + 3) but texelfetchers will be wrong!
1680 GLuint srcRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
1682 GLuint destRowStride
= _mesa_format_row_stride(texImage
->TexFormat
,
1685 _mesa_upscale_teximage2d(srcRowStride
, (height
+3) / 4,
1686 destRowStride
, (mml
->height
+3) / 4,
1687 1, data
, srcRowStride
,
1689 ti
->padded
= GL_TRUE
;
1691 MEMCPY(texImage
->Data
, data
, texImage
->CompressedSize
);
1694 ti
->info
.format
= mml
->glideFormat
;
1695 texImage
->FetchTexelc
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1697 /* GL_SGIS_generate_mipmap */
1698 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1699 assert(!_mesa_is_format_compressed(texImage
->TexFormat
));
1702 fxTexInvalidate(ctx
, texObj
);
1707 fxDDCompressedTexSubImage2D( GLcontext
*ctx
, GLenum target
,
1708 GLint level
, GLint xoffset
,
1709 GLint yoffset
, GLsizei width
,
1710 GLint height
, GLenum format
,
1711 GLsizei imageSize
, const GLvoid
*data
,
1712 struct gl_texture_object
*texObj
,
1713 struct gl_texture_image
*texImage
)
1715 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1717 tfxMipMapLevel
*mml
;
1718 GLint destRowStride
, srcRowStride
;
1722 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1723 fprintf(stderr
, "fxDDCompressedTexSubImage2D: id=%d\n", texObj
->Name
);
1726 ti
= fxTMGetTexInfo(texObj
);
1728 mml
= FX_MIPMAP_DATA(texImage
);
1731 srcRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, width
);
1733 destRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, mml
->width
);
1734 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
1735 texImage
->InternalFormat
,
1737 (GLubyte
*) texImage
->Data
);
1739 rows
= height
/ 4; /* hardcoded 4, but works for FXT1/DXTC */
1741 for (i
= 0; i
< rows
; i
++) {
1742 MEMCPY(dest
, data
, srcRowStride
);
1743 dest
+= destRowStride
;
1744 data
= (GLvoid
*)((GLuint
)data
+ (GLuint
)srcRowStride
);
1747 /* [dBorca] Hack alert:
1748 * see fxDDCompressedTexImage2D for caveats
1750 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1751 srcRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, texImage
->Width
);
1753 destRowStride
= _mesa_format_row_stride(texImage
->TexFormat
, mml
->width
);
1754 _mesa_upscale_teximage2d(srcRowStride
, texImage
->Height
/ 4,
1755 destRowStride
, mml
->height
/ 4,
1756 1, texImage
->Data
, destRowStride
,
1760 /* GL_SGIS_generate_mipmap */
1761 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
1762 assert(!_mesa_is_format_compressed(texImage
->TexFormat
));
1765 if (ti
->validated
&& ti
->isInTM
)
1766 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1768 fxTexInvalidate(ctx
, texObj
);
1773 fxDDTexImage1D (GLcontext
*ctx
, GLenum target
, GLint level
,
1774 GLint internalFormat
, GLint width
, GLint border
,
1775 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1776 const struct gl_pixelstore_attrib
*packing
,
1777 struct gl_texture_object
*texObj
,
1778 struct gl_texture_image
*texImage
)
1780 fxDDTexImage2D(ctx
, target
, level
,
1781 internalFormat
, width
, 1, border
,
1782 format
, type
, pixels
,
1790 fxDDTexSubImage1D(GLcontext
* ctx
, GLenum target
, GLint level
,
1793 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1794 const struct gl_pixelstore_attrib
*packing
,
1795 struct gl_texture_object
*texObj
,
1796 struct gl_texture_image
*texImage
)
1798 fxDDTexSubImage2D(ctx
, target
, level
,
1799 xoffset
, 0, width
, 1,
1800 format
, type
, pixels
,
1808 fxDDTestProxyTexImage (GLcontext
*ctx
, GLenum target
,
1809 GLint level
, GLint internalFormat
,
1810 GLenum format
, GLenum type
,
1811 GLint width
, GLint height
,
1812 GLint depth
, GLint border
)
1814 /* XXX todo - maybe through fxTexValidate() */
1815 return _mesa_test_proxy_teximage(ctx
, target
,
1816 level
, internalFormat
,
1826 * Need this to provide at least one external definition.
1829 extern int gl_fx_dummy_function_ddtex(void);
1831 gl_fx_dummy_function_ddtex(void)