1 /* $Id: fxddtex.c,v 1.49 2003/10/09 15:12:21 dborca Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47 #include "texformat.h"
53 fxPrintTextureData(tfxTexInfo
* ti
)
55 fprintf(stderr
, "Texture Data:\n");
57 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
58 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
59 fprintf(stderr
, "\tSize: %d x %d\n",
60 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Width
,
61 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Height
);
64 fprintf(stderr
, "\tName: UNNAMED\n");
65 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
66 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
67 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
69 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
70 (unsigned) ti
->tm
[0]->endAddr
);
72 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
73 (unsigned) ti
->tm
[1]->endAddr
);
74 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
75 fprintf(stderr
, "\tFilters: min %d min %d\n",
76 (int) ti
->minFilt
, (int) ti
->maxFilt
);
77 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
79 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
80 fprintf(stderr
, "\t%s\n",
81 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
82 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
86 /************************************************************************/
87 /*************************** Texture Mapping ****************************/
88 /************************************************************************/
91 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
93 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
96 ti
= fxTMGetTexInfo(tObj
);
98 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
100 ti
->validated
= GL_FALSE
;
101 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
105 fxAllocTexObjData(fxMesaContext fxMesa
)
109 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
110 fprintf(stderr
, "%s: ERROR: out of memory !\n", __FUNCTION__
);
115 ti
->validated
= GL_FALSE
;
116 ti
->isInTM
= GL_FALSE
;
118 ti
->whichTMU
= FX_TMU_NONE
;
120 ti
->tm
[FX_TMU0
] = NULL
;
121 ti
->tm
[FX_TMU1
] = NULL
;
123 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
124 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
126 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
127 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
129 ti
->mmMode
= GR_MIPMAP_NEAREST
;
130 ti
->LODblend
= FXFALSE
;
136 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
138 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
141 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
142 fprintf(stderr
, "%s(%d, %x)\n", __FUNCTION__
, tObj
->Name
,
143 (GLuint
) tObj
->DriverData
);
146 if (target
!= GL_TEXTURE_2D
)
149 if (!tObj
->DriverData
) {
150 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
153 ti
= fxTMGetTexInfo(tObj
);
155 fxMesa
->texBindNumber
++;
156 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
158 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
162 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
163 const GLfloat
* param
)
165 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
167 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
169 fprintf(stderr
, "%s(%x, %x)\n", __FUNCTION__
, pname
, (GLint
) (*param
));
171 fprintf(stderr
, "%s(%x)\n", __FUNCTION__
, pname
);
174 /* apply any lod biasing right now */
175 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
176 grTexLodBiasValue(GR_TMU0
, *param
);
178 if (fxMesa
->haveTwoTMUs
) {
179 grTexLodBiasValue(GR_TMU1
, *param
);
184 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
188 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
189 GLenum pname
, const GLfloat
* params
)
191 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
192 GLenum param
= (GLenum
) (GLint
) params
[0];
195 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
196 fprintf(stderr
, "fxDDTexParam(%d, %x, %s, %s)\n",
197 tObj
->Name
, (GLuint
) tObj
->DriverData
,
198 _mesa_lookup_enum_by_nr(pname
),
199 _mesa_lookup_enum_by_nr(param
));
202 if (target
!= GL_TEXTURE_2D
)
205 if (!tObj
->DriverData
)
206 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
208 ti
= fxTMGetTexInfo(tObj
);
212 case GL_TEXTURE_MIN_FILTER
:
215 ti
->mmMode
= GR_MIPMAP_DISABLE
;
216 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
217 ti
->LODblend
= FXFALSE
;
220 ti
->mmMode
= GR_MIPMAP_DISABLE
;
221 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
222 ti
->LODblend
= FXFALSE
;
224 case GL_NEAREST_MIPMAP_LINEAR
:
225 if (fxMesa
->haveTwoTMUs
) {
226 ti
->mmMode
= GR_MIPMAP_NEAREST
;
227 ti
->LODblend
= FXTRUE
;
230 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
231 ti
->LODblend
= FXFALSE
;
233 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
234 break; /* ZZZ: we may have to fall through here for V3 */
235 case GL_NEAREST_MIPMAP_NEAREST
:
236 ti
->mmMode
= GR_MIPMAP_NEAREST
;
237 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
238 ti
->LODblend
= FXFALSE
;
240 case GL_LINEAR_MIPMAP_LINEAR
:
241 /* ZZZ: HACK ALERT! trilinear is bugged! mipmap blending produce
242 incorrect filtered colors for the smallest mipmap levels. */
244 if (fxMesa
->haveTwoTMUs
) {
245 ti
->mmMode
= GR_MIPMAP_NEAREST
;
246 ti
->LODblend
= FXTRUE
;
249 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
250 ti
->LODblend
= FXFALSE
;
252 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
253 break; /* ZZZ: we may have to fall through here for V3 */
255 case GL_LINEAR_MIPMAP_NEAREST
:
256 ti
->mmMode
= GR_MIPMAP_NEAREST
;
257 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
258 ti
->LODblend
= FXFALSE
;
263 fxTexInvalidate(ctx
, tObj
);
266 case GL_TEXTURE_MAG_FILTER
:
269 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
272 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
277 fxTexInvalidate(ctx
, tObj
);
280 case GL_TEXTURE_WRAP_S
:
282 case GL_MIRRORED_REPEAT
:
283 ti
->sClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
285 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
287 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
290 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
295 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
298 case GL_TEXTURE_WRAP_T
:
300 case GL_MIRRORED_REPEAT
:
301 ti
->tClamp
= GR_TEXTURECLAMP_MIRROR_EXT
;
303 case GL_CLAMP_TO_EDGE
: /* CLAMP discarding border */
305 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
308 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
313 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
316 case GL_TEXTURE_BORDER_COLOR
:
320 case GL_TEXTURE_MIN_LOD
:
323 case GL_TEXTURE_MAX_LOD
:
326 case GL_TEXTURE_BASE_LEVEL
:
327 fxTexInvalidate(ctx
, tObj
);
329 case GL_TEXTURE_MAX_LEVEL
:
330 fxTexInvalidate(ctx
, tObj
);
339 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
341 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
342 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
344 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
345 fprintf(stderr
, "%s(%d, %p)\n", __FUNCTION__
, tObj
->Name
, (void *) ti
);
351 fxTMFreeTexture(fxMesa
, tObj
);
354 tObj
->DriverData
= NULL
;
360 * Convert a gl_color_table texture palette to Glide's format.
363 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
365 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
366 GLint width
= table
->Size
;
370 ASSERT(!table
->FloatTable
);
372 switch (table
->Format
) {
374 for (i
= 0; i
< width
; i
++) {
379 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
383 for (i
= 0; i
< width
; i
++) {
388 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
392 for (i
= 0; i
< width
; i
++) {
395 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
398 case GL_LUMINANCE_ALPHA
:
399 for (i
= 0; i
< width
; i
++) {
400 r
= g
= b
= tableUB
[i
* 2 + 0];
401 a
= tableUB
[i
* 2 + 1];
402 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
406 for (i
= 0; i
< width
; i
++) {
407 r
= tableUB
[i
* 3 + 0];
408 g
= tableUB
[i
* 3 + 1];
409 b
= tableUB
[i
* 3 + 2];
411 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
415 for (i
= 0; i
< width
; i
++) {
416 r
= tableUB
[i
* 4 + 0];
417 g
= tableUB
[i
* 4 + 1];
418 b
= tableUB
[i
* 4 + 2];
419 a
= tableUB
[i
* 4 + 3];
420 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
428 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
430 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
433 /* per-texture palette */
435 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
436 fprintf(stderr
, "%s(%d, %x)\n", __FUNCTION__
,
437 tObj
->Name
, (GLuint
) tObj
->DriverData
);
439 if (!tObj
->DriverData
)
440 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
441 ti
= fxTMGetTexInfo(tObj
);
442 convertPalette(ti
->palette
.data
, &tObj
->Palette
);
443 fxTexInvalidate(ctx
, tObj
);
446 /* global texture palette */
447 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
448 fprintf(stderr
, "%s(global)\n", __FUNCTION__
);
450 convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
451 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
457 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
459 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
461 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
462 fprintf(stderr
, "%s(%d)\n", __FUNCTION__
, state
);
466 fxMesa
->haveGlobalPaletteTexture
= 1;
468 grTexDownloadTable(GR_TEXTABLE_PALETTE
, &(fxMesa
->glbPalette
));
471 fxMesa
->haveGlobalPaletteTexture
= 0;
473 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
474 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
475 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
477 if (!tObj
->DriverData
)
478 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
480 fxTexInvalidate(ctx
, tObj
);
510 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
511 float *sscale
, float *tscale
,
512 int *wscale
, int *hscale
)
515 static GrLOD_t lod
[12] = {
530 int logw
, logh
, ws
, hs
;
532 GrAspectRatio_t aspectratio
;
538 switch (logw
- logh
) {
540 aspectratio
= GR_ASPECT_LOG2_1x1
;
546 aspectratio
= GR_ASPECT_LOG2_2x1
;
554 aspectratio
= GR_ASPECT_LOG2_4x1
;
562 aspectratio
= GR_ASPECT_LOG2_8x1
;
570 aspectratio
= GR_ASPECT_LOG2_1x2
;
578 aspectratio
= GR_ASPECT_LOG2_1x4
;
586 aspectratio
= GR_ASPECT_LOG2_1x8
;
594 if ((logw
- logh
) > 3) {
595 aspectratio
= GR_ASPECT_LOG2_8x1
;
600 hs
= 1 << (logw
- logh
- 3);
601 } else /*if ((logw - logh) < -3)*/ {
602 aspectratio
= GR_ASPECT_LOG2_1x8
;
606 ws
= 1 << (logh
- logw
- 3);
634 fxIsTexSupported(GLenum target
, GLint internalFormat
,
635 const struct gl_texture_image
*image
)
637 if (target
!= GL_TEXTURE_2D
)
640 if (!fxTexGetInfo(image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
643 if (image
->Border
> 0)
650 /**********************************************************************/
651 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
652 /**********************************************************************/
654 /* Texel-fetch functions for software texturing and glGetTexImage().
655 * We should have been able to use some "standard" fetch functions (which
656 * may get defined in texutil.c) but we have to account for scaled texture
657 * images on tdfx hardware (the 8:1 aspect ratio limit).
658 * Hence, we need special functions here.
662 fetch_intensity8(const struct gl_texture_image
*texImage
,
663 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
665 GLchan
*rgba
= (GLchan
*) texelOut
;
666 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
667 const GLubyte
*texel
;
672 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
673 rgba
[RCOMP
] = *texel
;
674 rgba
[GCOMP
] = *texel
;
675 rgba
[BCOMP
] = *texel
;
676 rgba
[ACOMP
] = *texel
;
681 fetch_luminance8(const struct gl_texture_image
*texImage
,
682 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
684 GLchan
*rgba
= (GLchan
*) texelOut
;
685 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
686 const GLubyte
*texel
;
691 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
692 rgba
[RCOMP
] = *texel
;
693 rgba
[GCOMP
] = *texel
;
694 rgba
[BCOMP
] = *texel
;
700 fetch_alpha8(const struct gl_texture_image
*texImage
,
701 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
703 GLchan
*rgba
= (GLchan
*) texelOut
;
704 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
705 const GLubyte
*texel
;
709 i
= i
* mml
->width
/ texImage
->Width
;
710 j
= j
* mml
->height
/ texImage
->Height
;
712 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
716 rgba
[ACOMP
] = *texel
;
721 fetch_index8(const struct gl_texture_image
*texImage
,
722 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
724 GLchan
*indexOut
= (GLchan
*) texelOut
;
725 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
726 const GLubyte
*texel
;
730 i
= i
* mml
->width
/ texImage
->Width
;
731 j
= j
* mml
->height
/ texImage
->Height
;
733 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
739 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
740 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
742 GLchan
*rgba
= (GLchan
*) texelOut
;
743 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
744 const GLubyte
*texel
;
749 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
750 rgba
[RCOMP
] = texel
[0];
751 rgba
[GCOMP
] = texel
[0];
752 rgba
[BCOMP
] = texel
[0];
753 rgba
[ACOMP
] = texel
[1];
758 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
759 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
761 GLchan
*rgba
= (GLchan
*) texelOut
;
762 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
763 const GLushort
*texel
;
768 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
769 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
770 rgba
[GCOMP
] = FX_rgb_scale_6
[(*texel
>> 5) & 0x3F];
771 rgba
[BCOMP
] = FX_rgb_scale_5
[ *texel
& 0x1F];
777 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
778 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
780 GLchan
*rgba
= (GLchan
*) texelOut
;
781 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
782 const GLushort
*texel
;
787 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
788 rgba
[RCOMP
] = FX_rgb_scale_4
[(*texel
>> 12) & 0xF];
789 rgba
[GCOMP
] = FX_rgb_scale_4
[(*texel
>> 8) & 0xF];
790 rgba
[BCOMP
] = FX_rgb_scale_4
[(*texel
>> 4) & 0xF];
791 rgba
[ACOMP
] = FX_rgb_scale_4
[ *texel
& 0xF];
796 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
797 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
799 GLchan
*rgba
= (GLchan
*) texelOut
;
800 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
801 const GLushort
*texel
;
806 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
807 rgba
[RCOMP
] = FX_rgb_scale_5
[(*texel
>> 11) & 0x1F];
808 rgba
[GCOMP
] = FX_rgb_scale_5
[(*texel
>> 6) & 0x1F];
809 rgba
[BCOMP
] = FX_rgb_scale_5
[(*texel
>> 1) & 0x1F];
810 rgba
[ACOMP
] = ((*texel
) & 0x01) * 255;
815 fetch_a8r8g8b8(const struct gl_texture_image
*texImage
,
816 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
818 GLchan
*rgba
= (GLchan
*) texelOut
;
819 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
825 texel
= ((GLuint
*) texImage
->Data
) + j
* mml
->width
+ i
;
826 rgba
[RCOMP
] = (((*texel
) >> 16) & 0xff);
827 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xff);
828 rgba
[BCOMP
] = (((*texel
) ) & 0xff);
829 rgba
[ACOMP
] = (((*texel
) >> 24) & 0xff);
834 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
837 for (i
= 0; i
< h
; i
++) {
838 for (j
= 0; j
< w
; j
++) {
840 fprintf(stderr
, "%02x %02x ", data
[0], data
[1]);
842 fprintf(stderr
, "%02x %02x %02x ", data
[0], data
[1], data
[2]);
845 fprintf(stderr
, "\n");
850 const struct gl_texture_format
*
851 fxDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
852 GLenum srcFormat
, GLenum srcType
)
854 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
855 GLboolean allow32bpt
= fxMesa
->HaveTexFmt
;
857 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
858 fprintf(stderr
, "fxDDChooseTextureFormat(...)\n");
861 switch (internalFormat
) {
867 case GL_COMPRESSED_INTENSITY
:
868 return &_mesa_texformat_i8
;
875 case GL_COMPRESSED_LUMINANCE
:
876 return &_mesa_texformat_l8
;
882 case GL_COMPRESSED_ALPHA
:
883 return &_mesa_texformat_a8
;
885 case GL_COLOR_INDEX1_EXT
:
886 case GL_COLOR_INDEX2_EXT
:
887 case GL_COLOR_INDEX4_EXT
:
888 case GL_COLOR_INDEX8_EXT
:
889 case GL_COLOR_INDEX12_EXT
:
890 case GL_COLOR_INDEX16_EXT
:
891 return &_mesa_texformat_ci8
;
893 case GL_LUMINANCE_ALPHA
:
894 case GL_LUMINANCE4_ALPHA4
:
895 case GL_LUMINANCE6_ALPHA2
:
896 case GL_LUMINANCE8_ALPHA8
:
897 case GL_LUMINANCE12_ALPHA4
:
898 case GL_LUMINANCE12_ALPHA12
:
899 case GL_LUMINANCE16_ALPHA16
:
900 case GL_COMPRESSED_LUMINANCE_ALPHA
:
901 return &_mesa_texformat_al88
;
905 return &_mesa_texformat_rgb565
;
908 case GL_COMPRESSED_RGB
:
909 if ( srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
910 return &_mesa_texformat_rgb565
;
912 /* intentional fall through */
917 return (allow32bpt
) ? &_mesa_texformat_argb8888
918 : &_mesa_texformat_rgb565
;
921 return &_mesa_texformat_argb4444
;
924 case GL_COMPRESSED_RGBA
:
925 if ( srcFormat
== GL_BGRA
) {
926 if ( srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
927 return &_mesa_texformat_argb8888
;
929 else if ( srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
930 return &_mesa_texformat_argb4444
;
932 else if ( srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
933 return &_mesa_texformat_argb1555
;
936 /* intentional fall through */
941 return (allow32bpt
) ? &_mesa_texformat_argb8888
942 : &_mesa_texformat_argb4444
;
944 return &_mesa_texformat_argb1555
;
946 /* GL_EXT_texture_compression_s3tc */
947 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
948 return &_mesa_texformat_rgb_dxt1
;
949 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
950 return &_mesa_texformat_rgba_dxt1
;
951 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
952 return &_mesa_texformat_rgba_dxt3
;
953 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
954 return &_mesa_texformat_rgba_dxt5
;
955 /*case GL_COMPRESSED_RGB_FXT1_3DFX:
956 case GL_COMPRESSED_RGBA_FXT1_3DFX:
960 _mesa_problem(NULL
, "unexpected format in fxDDChooseTextureFormat");
966 static GrTextureFormat_t
967 fxGlideFormat(GLint mesaFormat
)
969 switch (mesaFormat
) {
971 return GR_TEXFMT_ALPHA_8
;
973 return GR_TEXFMT_ALPHA_8
;
975 return GR_TEXFMT_INTENSITY_8
;
976 case MESA_FORMAT_CI8
:
977 return GR_TEXFMT_P_8
;
978 case MESA_FORMAT_AL88
:
979 return GR_TEXFMT_ALPHA_INTENSITY_88
;
980 case MESA_FORMAT_RGB565
:
981 return GR_TEXFMT_RGB_565
;
982 case MESA_FORMAT_ARGB4444
:
983 return GR_TEXFMT_ARGB_4444
;
984 case MESA_FORMAT_ARGB1555
:
985 return GR_TEXFMT_ARGB_1555
;
986 #if 1 /* [koolsmoky] getting ready for 32bpp textures */
987 case MESA_FORMAT_ARGB8888
:
988 return GR_TEXFMT_ARGB_8888
;
991 case MESA_FORMAT_RGB_DXT1
:
992 case MESA_FORMAT_RGBA_DXT1
:
993 return GR_TEXFMT_ARGB_CMP_DXT1
;
994 case MESA_FORMAT_RGBA_DXT3
:
995 return GR_TEXFMT_ARGB_CMP_DXT3
;
996 case MESA_FORMAT_RGBA_DXT5
:
997 return GR_TEXFMT_ARGB_CMP_DXT5
;
998 /*case MESA_FORMAT_ARGB_CMP_FXT1:
999 return GR_TEXFMT_ARGB_CMP_FXT1;
1000 case MESA_FORMAT_RGB_CMP_FXT1:
1001 return GL_COMPRESSED_RGBA_FXT1_3DFX;*/
1004 _mesa_problem(NULL
, "Unexpected format in fxGlideFormat");
1010 static FetchTexelFunc
1011 fxFetchFunction(GLint mesaFormat
)
1013 switch (mesaFormat
) {
1014 case MESA_FORMAT_I8
:
1015 return fetch_intensity8
;
1016 case MESA_FORMAT_A8
:
1017 return fetch_alpha8
;
1018 case MESA_FORMAT_L8
:
1019 return fetch_luminance8
;
1020 case MESA_FORMAT_CI8
:
1021 return fetch_index8
;
1022 case MESA_FORMAT_AL88
:
1023 return fetch_luminance8_alpha8
;
1024 case MESA_FORMAT_RGB565
:
1025 return fetch_r5g6b5
;
1026 case MESA_FORMAT_ARGB4444
:
1027 return fetch_r4g4b4a4
;
1028 case MESA_FORMAT_ARGB1555
:
1029 return fetch_r5g5b5a1
;
1030 #if 1 /* [koolsmoky] getting ready for 32bpp textures */
1031 case MESA_FORMAT_ARGB8888
:
1032 return fetch_a8r8g8b8
;
1035 case MESA_FORMAT_RGB_DXT1
:
1036 case MESA_FORMAT_RGBA_DXT1
:
1037 case MESA_FORMAT_RGBA_DXT3
:
1038 case MESA_FORMAT_RGBA_DXT5
:
1039 return fetch_r4g4b4a4
;
1042 _mesa_problem(NULL
, "Unexpected format in fxFetchFunction");
1048 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1049 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1050 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1051 const struct gl_pixelstore_attrib
*packing
,
1052 struct gl_texture_object
*texObj
,
1053 struct gl_texture_image
*texImage
)
1055 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1057 tfxMipMapLevel
*mml
;
1060 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1061 fprintf(stderr
, "fxDDTexImage2D: id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1062 texObj
->Name
, texImage
->IntFormat
, format
, type
,
1063 texImage
->Width
, texImage
->Height
);
1066 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1067 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1071 if (!texObj
->DriverData
) {
1072 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1073 if (!texObj
->DriverData
) {
1074 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1078 ti
= fxTMGetTexInfo(texObj
);
1080 if (!texImage
->DriverData
) {
1081 texImage
->DriverData
= CALLOC(sizeof(tfxMipMapLevel
));
1082 if (!texImage
->DriverData
) {
1083 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1087 mml
= FX_MIPMAP_DATA(texImage
);
1089 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1090 &mml
->wScale
, &mml
->hScale
);
1092 mml
->width
= width
* mml
->wScale
;
1093 mml
->height
= height
* mml
->hScale
;
1096 /* choose the texture format */
1097 assert(ctx
->Driver
.ChooseTextureFormat
);
1098 texImage
->TexFormat
= (*ctx
->Driver
.ChooseTextureFormat
)(ctx
,
1099 internalFormat
, format
, type
);
1100 assert(texImage
->TexFormat
);
1101 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1102 /*if (!fxMesa->HaveTexFmt) assert(texelBytes == 1 || texelBytes == 2);*/
1104 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1105 /* rescale image to overcome 1:8 aspect limitation */
1107 tempImage
= MALLOC(width
* height
* texelBytes
);
1109 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1112 /* unpack image, apply transfer ops and store in tempImage */
1113 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1114 texImage
->TexFormat
,
1116 width
, height
, 1, 0, 0, 0,
1118 0, /* dstImageStride */
1119 format
, type
, pixels
, packing
);
1120 assert(!texImage
->Data
);
1121 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1122 if (!texImage
->Data
) {
1123 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1127 _mesa_rescale_teximage2d(texelBytes
,
1128 mml
->width
* texelBytes
, /* dst stride */
1130 mml
->width
, mml
->height
,
1131 tempImage
/*src*/, texImage
->Data
/*dst*/ );
1135 /* no rescaling needed */
1136 assert(!texImage
->Data
);
1137 texImage
->Data
= MESA_PBUFFER_ALLOC(mml
->width
* mml
->height
* texelBytes
);
1138 if (!texImage
->Data
) {
1139 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1142 /* unpack image, apply transfer ops and store in texImage->Data */
1143 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,
1144 texImage
->TexFormat
, texImage
->Data
,
1145 width
, height
, 1, 0, 0, 0,
1146 texImage
->Width
* texelBytes
,
1147 0, /* dstImageStride */
1148 format
, type
, pixels
, packing
);
1151 mml
->glideFormat
= fxGlideFormat(texImage
->TexFormat
->MesaFormat
);
1152 ti
->info
.format
= mml
->glideFormat
;
1153 texImage
->FetchTexel
= fxFetchFunction(texImage
->TexFormat
->MesaFormat
);
1156 * Hack alert: unsure...
1158 if (!(fxMesa
->new_state
& FX_NEW_TEXTURING
) && ti
->validated
&& ti
->isInTM
) {
1159 /*fprintf(stderr, "reloadmipmaplevels\n"); */
1160 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1163 /*fprintf(stderr, "invalidate2\n"); */
1164 fxTexInvalidate(ctx
, texObj
);
1170 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1171 GLint xoffset
, GLint yoffset
,
1172 GLsizei width
, GLsizei height
,
1173 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1174 const struct gl_pixelstore_attrib
*packing
,
1175 struct gl_texture_object
*texObj
,
1176 struct gl_texture_image
*texImage
)
1178 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1180 tfxMipMapLevel
*mml
;
1183 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
1184 fprintf(stderr
, "fxDDTexSubImage2D: id=%d\n", texObj
->Name
);
1187 if (!texObj
->DriverData
) {
1188 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1192 ti
= fxTMGetTexInfo(texObj
);
1194 mml
= FX_MIPMAP_DATA(texImage
);
1197 assert(texImage
->Data
); /* must have an existing texture image! */
1198 assert(texImage
->Format
);
1200 texelBytes
= texImage
->TexFormat
->TexelBytes
;
1202 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
1203 /* need to rescale subimage to match mipmap level's rescale factors */
1204 const GLint newWidth
= width
* mml
->wScale
;
1205 const GLint newHeight
= height
* mml
->hScale
;
1208 tempImage
= MALLOC(width
* height
* texelBytes
);
1210 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1214 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
,/* Tex int format */
1215 texImage
->TexFormat
, /* dest format */
1216 (GLubyte
*) tempImage
, /* dest */
1217 width
, height
, 1, /* subimage size */
1218 0, 0, 0, /* subimage pos */
1219 width
* texelBytes
, /* dest row stride */
1220 0, /* dst image stride */
1221 format
, type
, pixels
, packing
);
1224 /* compute address of dest subimage within the overal tex image */
1225 destAddr
= (GLubyte
*) texImage
->Data
1226 + (yoffset
* mml
->hScale
* mml
->width
1227 + xoffset
* mml
->wScale
) * texelBytes
;
1229 _mesa_rescale_teximage2d(texelBytes
,
1230 mml
->width
* texelBytes
, /* dst stride */
1232 newWidth
, newHeight
,
1233 tempImage
, destAddr
);
1238 /* no rescaling needed */
1239 _mesa_transfer_teximage(ctx
, 2, texImage
->Format
, /* Tex int format */
1240 texImage
->TexFormat
, /* dest format */
1241 (GLubyte
*) texImage
->Data
,/* dest */
1242 width
, height
, 1, /* subimage size */
1243 xoffset
, yoffset
, 0, /* subimage pos */
1244 mml
->width
* texelBytes
, /* dest row stride */
1245 0, /* dst image stride */
1246 format
, type
, pixels
, packing
);
1250 * Hack alert: unsure...
1252 if (!(fxMesa
->new_state
& FX_NEW_TEXTURING
) && ti
->validated
&& ti
->isInTM
)
1253 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1255 fxTexInvalidate(ctx
, texObj
);
1262 * Need this to provide at least one external definition.
1265 extern int gl_fx_dummy_function_ddtex(void);
1267 gl_fx_dummy_function_ddtex(void)