3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
29 * Thank you for your contribution, David!
31 * Please make note of the above copyright/license statement. If you
32 * contributed code or bug fixes to this code under the previous (GNU
33 * Library) license and object to the new license, your code will be
34 * removed at your request. Please see the Mesa docs/COPYRIGHT file
35 * for more information.
37 * Additional Mesa/3Dfx driver developers:
38 * Daryll Strauss <daryll@precisioninsight.com>
39 * Keith Whitwell <keith@precisioninsight.com>
41 * See fxapi.h for more revision/author details.
54 #include "texformat.h"
60 fxPrintTextureData(tfxTexInfo
* ti
)
62 fprintf(stderr
, "Texture Data:\n");
64 fprintf(stderr
, "\tName: %d\n", ti
->tObj
->Name
);
65 fprintf(stderr
, "\tBaseLevel: %d\n", ti
->tObj
->BaseLevel
);
66 fprintf(stderr
, "\tSize: %d x %d\n",
67 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Width
,
68 ti
->tObj
->Image
[ti
->tObj
->BaseLevel
]->Height
);
71 fprintf(stderr
, "\tName: UNNAMED\n");
72 fprintf(stderr
, "\tLast used: %d\n", ti
->lastTimeUsed
);
73 fprintf(stderr
, "\tTMU: %ld\n", ti
->whichTMU
);
74 fprintf(stderr
, "\t%s\n", (ti
->isInTM
) ? "In TMU" : "Not in TMU");
76 fprintf(stderr
, "\tMem0: %x-%x\n", (unsigned) ti
->tm
[0]->startAddr
,
77 (unsigned) ti
->tm
[0]->endAddr
);
79 fprintf(stderr
, "\tMem1: %x-%x\n", (unsigned) ti
->tm
[1]->startAddr
,
80 (unsigned) ti
->tm
[1]->endAddr
);
81 fprintf(stderr
, "\tMipmaps: %d-%d\n", ti
->minLevel
, ti
->maxLevel
);
82 fprintf(stderr
, "\tFilters: min %d min %d\n",
83 (int) ti
->minFilt
, (int) ti
->maxFilt
);
84 fprintf(stderr
, "\tClamps: s %d t %d\n", (int) ti
->sClamp
,
86 fprintf(stderr
, "\tScales: s %f t %f\n", ti
->sScale
, ti
->tScale
);
87 fprintf(stderr
, "\tInt Scales: s %d t %d\n",
88 ti
->int_sScale
/ 0x800000, ti
->int_tScale
/ 0x800000);
89 fprintf(stderr
, "\t%s\n",
90 (ti
->fixedPalette
) ? "Fixed palette" : "Non fixed palette");
91 fprintf(stderr
, "\t%s\n", (ti
->validated
) ? "Validated" : "Not validated");
95 /************************************************************************/
96 /*************************** Texture Mapping ****************************/
97 /************************************************************************/
100 fxTexInvalidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
102 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
105 ti
= fxTMGetTexInfo(tObj
);
107 fxTMMoveOutTM(fxMesa
, tObj
); /* TO DO: SLOW but easy to write */
109 ti
->validated
= GL_FALSE
;
110 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
114 fxAllocTexObjData(fxMesaContext fxMesa
)
118 if (!(ti
= CALLOC(sizeof(tfxTexInfo
)))) {
119 fprintf(stderr
, "fx Driver: out of memory !\n");
124 ti
->validated
= GL_FALSE
;
125 ti
->isInTM
= GL_FALSE
;
127 ti
->whichTMU
= FX_TMU_NONE
;
129 ti
->tm
[FX_TMU0
] = NULL
;
130 ti
->tm
[FX_TMU1
] = NULL
;
132 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
133 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
135 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
136 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
138 ti
->mmMode
= GR_MIPMAP_NEAREST
;
139 ti
->LODblend
= FXFALSE
;
145 fxDDTexBind(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
)
147 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
150 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
151 fprintf(stderr
, "fxmesa: fxDDTexBind(%d,%x)\n", tObj
->Name
,
152 (GLuint
) tObj
->DriverData
);
155 if (target
!= GL_TEXTURE_2D
)
158 if (!tObj
->DriverData
) {
159 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
162 ti
= fxTMGetTexInfo(tObj
);
164 fxMesa
->texBindNumber
++;
165 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
167 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
171 fxDDTexEnv(GLcontext
* ctx
, GLenum target
, GLenum pname
,
172 const GLfloat
* param
)
174 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
176 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
178 fprintf(stderr
, "fxmesa: texenv(%x,%x)\n", pname
, (GLint
) (*param
));
180 fprintf(stderr
, "fxmesa: texenv(%x)\n", pname
);
183 /* apply any lod biasing right now */
184 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
185 FX_grTexLodBiasValue(GR_TMU0
, *param
);
187 if (fxMesa
->haveTwoTMUs
) {
188 FX_grTexLodBiasValue(GR_TMU1
, *param
);
193 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
197 fxDDTexParam(GLcontext
* ctx
, GLenum target
, struct gl_texture_object
*tObj
,
198 GLenum pname
, const GLfloat
* params
)
200 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
201 GLenum param
= (GLenum
) (GLint
) params
[0];
204 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
205 fprintf(stderr
, "fxmesa: fxDDTexParam(%d,%x,%x,%x)\n", tObj
->Name
,
206 (GLuint
) tObj
->DriverData
, pname
, param
);
209 if (target
!= GL_TEXTURE_2D
)
212 if (!tObj
->DriverData
)
213 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
215 ti
= fxTMGetTexInfo(tObj
);
219 case GL_TEXTURE_MIN_FILTER
:
222 ti
->mmMode
= GR_MIPMAP_DISABLE
;
223 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
224 ti
->LODblend
= FXFALSE
;
227 ti
->mmMode
= GR_MIPMAP_DISABLE
;
228 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
229 ti
->LODblend
= FXFALSE
;
231 case GL_NEAREST_MIPMAP_NEAREST
:
232 ti
->mmMode
= GR_MIPMAP_NEAREST
;
233 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
234 ti
->LODblend
= FXFALSE
;
236 case GL_LINEAR_MIPMAP_NEAREST
:
237 ti
->mmMode
= GR_MIPMAP_NEAREST
;
238 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
239 ti
->LODblend
= FXFALSE
;
241 case GL_NEAREST_MIPMAP_LINEAR
:
242 if (fxMesa
->haveTwoTMUs
) {
243 ti
->mmMode
= GR_MIPMAP_NEAREST
;
244 ti
->LODblend
= FXTRUE
;
247 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
248 ti
->LODblend
= FXFALSE
;
250 ti
->minFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
252 case GL_LINEAR_MIPMAP_LINEAR
:
253 if (fxMesa
->haveTwoTMUs
) {
254 ti
->mmMode
= GR_MIPMAP_NEAREST
;
255 ti
->LODblend
= FXTRUE
;
258 ti
->mmMode
= GR_MIPMAP_NEAREST_DITHER
;
259 ti
->LODblend
= FXFALSE
;
261 ti
->minFilt
= GR_TEXTUREFILTER_BILINEAR
;
266 fxTexInvalidate(ctx
, tObj
);
269 case GL_TEXTURE_MAG_FILTER
:
272 ti
->maxFilt
= GR_TEXTUREFILTER_POINT_SAMPLED
;
275 ti
->maxFilt
= GR_TEXTUREFILTER_BILINEAR
;
280 fxTexInvalidate(ctx
, tObj
);
283 case GL_TEXTURE_WRAP_S
:
286 ti
->sClamp
= GR_TEXTURECLAMP_CLAMP
;
289 ti
->sClamp
= GR_TEXTURECLAMP_WRAP
;
294 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
297 case GL_TEXTURE_WRAP_T
:
300 ti
->tClamp
= GR_TEXTURECLAMP_CLAMP
;
303 ti
->tClamp
= GR_TEXTURECLAMP_WRAP
;
308 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
311 case GL_TEXTURE_BORDER_COLOR
:
315 case GL_TEXTURE_MIN_LOD
:
318 case GL_TEXTURE_MAX_LOD
:
321 case GL_TEXTURE_BASE_LEVEL
:
322 fxTexInvalidate(ctx
, tObj
);
324 case GL_TEXTURE_MAX_LEVEL
:
325 fxTexInvalidate(ctx
, tObj
);
334 fxDDTexDel(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
336 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
337 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
339 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
340 fprintf(stderr
, "fxmesa: fxDDTexDel(%d,%p)\n", tObj
->Name
, ti
);
346 fxTMFreeTexture(fxMesa
, tObj
);
349 tObj
->DriverData
= NULL
;
355 * Convert a gl_color_table texture palette to Glide's format.
358 convertPalette(FxU32 data
[256], const struct gl_color_table
*table
)
360 const GLubyte
*tableUB
= (const GLubyte
*) table
->Table
;
361 GLint width
= table
->Size
;
365 ASSERT(!table
->FloatTable
);
367 switch (table
->Format
) {
369 for (i
= 0; i
< width
; i
++) {
374 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
378 for (i
= 0; i
< width
; i
++) {
383 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
387 for (i
= 0; i
< width
; i
++) {
390 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
393 case GL_LUMINANCE_ALPHA
:
394 for (i
= 0; i
< width
; i
++) {
395 r
= g
= b
= tableUB
[i
* 2 + 0];
396 a
= tableUB
[i
* 2 + 1];
397 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
401 for (i
= 0; i
< width
; i
++) {
402 r
= tableUB
[i
* 3 + 0];
403 g
= tableUB
[i
* 3 + 1];
404 b
= tableUB
[i
* 3 + 2];
406 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
410 for (i
= 0; i
< width
; i
++) {
411 r
= tableUB
[i
* 4 + 0];
412 g
= tableUB
[i
* 4 + 1];
413 b
= tableUB
[i
* 4 + 2];
414 a
= tableUB
[i
* 4 + 3];
415 data
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
423 fxDDTexPalette(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
425 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
428 /* per-texture palette */
430 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
431 fprintf(stderr
, "fxmesa: fxDDTexPalette(%d,%x)\n",
432 tObj
->Name
, (GLuint
) tObj
->DriverData
);
434 if (!tObj
->DriverData
)
435 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
436 ti
= fxTMGetTexInfo(tObj
);
437 convertPalette(ti
->palette
.data
, &tObj
->Palette
);
438 fxTexInvalidate(ctx
, tObj
);
441 /* global texture palette */
442 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
443 fprintf(stderr
, "fxmesa: fxDDTexPalette(global)\n");
445 convertPalette(fxMesa
->glbPalette
.data
, &ctx
->Texture
.Palette
);
446 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
452 fxDDTexUseGlbPalette(GLcontext
* ctx
, GLboolean state
)
454 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
456 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
457 fprintf(stderr
, "fxmesa: fxDDTexUseGlbPalette(%d)\n", state
);
461 fxMesa
->haveGlobalPaletteTexture
= 1;
463 FX_grTexDownloadTable(GR_TMU0
, GR_TEXTABLE_PALETTE
,
464 &(fxMesa
->glbPalette
));
465 if (fxMesa
->haveTwoTMUs
)
466 FX_grTexDownloadTable(GR_TMU1
, GR_TEXTABLE_PALETTE
,
467 &(fxMesa
->glbPalette
));
470 fxMesa
->haveGlobalPaletteTexture
= 0;
472 if ((ctx
->Texture
.Unit
[0]._Current
== ctx
->Texture
.Unit
[0].Current2D
) &&
473 (ctx
->Texture
.Unit
[0]._Current
!= NULL
)) {
474 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[0]._Current
;
476 if (!tObj
->DriverData
)
477 tObj
->DriverData
= fxAllocTexObjData(fxMesa
);
479 fxTexInvalidate(ctx
, tObj
);
507 /* Need different versions for different cpus.
509 #define INT_TRICK(l2) (0x800000 * l2)
513 fxTexGetInfo(int w
, int h
, GrLOD_t
* lodlevel
, GrAspectRatio_t
* ar
,
514 float *sscale
, float *tscale
,
515 int *i_sscale
, int *i_tscale
, int *wscale
, int *hscale
)
518 static GrLOD_t lod
[9] = { GR_LOD_256
, GR_LOD_128
, GR_LOD_64
, GR_LOD_32
,
519 GR_LOD_16
, GR_LOD_8
, GR_LOD_4
, GR_LOD_2
, GR_LOD_1
522 int logw
, logh
, ws
, hs
;
524 GrAspectRatio_t aspectratio
;
531 switch (logw
- logh
) {
533 aspectratio
= GR_ASPECT_1x1
;
536 is
= it
= INT_TRICK(8);
540 aspectratio
= GR_ASPECT_2x1
;
550 aspectratio
= GR_ASPECT_4x1
;
560 aspectratio
= GR_ASPECT_8x1
;
570 aspectratio
= GR_ASPECT_8x1
;
580 aspectratio
= GR_ASPECT_8x1
;
590 aspectratio
= GR_ASPECT_8x1
;
600 aspectratio
= GR_ASPECT_8x1
;
610 aspectratio
= GR_ASPECT_8x1
;
620 aspectratio
= GR_ASPECT_1x2
;
630 aspectratio
= GR_ASPECT_1x4
;
640 aspectratio
= GR_ASPECT_1x8
;
650 aspectratio
= GR_ASPECT_1x8
;
660 aspectratio
= GR_ASPECT_1x8
;
670 aspectratio
= GR_ASPECT_1x8
;
680 aspectratio
= GR_ASPECT_1x8
;
690 aspectratio
= GR_ASPECT_1x8
;
733 * Given an OpenGL internal texture format, return the corresponding
734 * Glide internal texture format and base texture format.
737 fxTexGetFormat(GLenum glformat
, GrTextureFormat_t
* tfmt
, GLint
* ifmt
)
747 (*tfmt
) = GR_TEXFMT_INTENSITY_8
;
749 (*ifmt
) = GL_LUMINANCE
;
752 case GL_LUMINANCE_ALPHA
:
753 case GL_LUMINANCE4_ALPHA4
:
754 case GL_LUMINANCE6_ALPHA2
:
755 case GL_LUMINANCE8_ALPHA8
:
756 case GL_LUMINANCE12_ALPHA4
:
757 case GL_LUMINANCE12_ALPHA12
:
758 case GL_LUMINANCE16_ALPHA16
:
760 (*tfmt
) = GR_TEXFMT_ALPHA_INTENSITY_88
;
762 (*ifmt
) = GL_LUMINANCE_ALPHA
;
770 (*tfmt
) = GR_TEXFMT_ALPHA_8
;
772 (*ifmt
) = GL_INTENSITY
;
780 (*tfmt
) = GR_TEXFMT_ALPHA_8
;
794 (*tfmt
) = GR_TEXFMT_RGB_565
;
807 (*tfmt
) = GR_TEXFMT_ARGB_4444
;
813 (*tfmt
) = GR_TEXFMT_ARGB_1555
;
818 case GL_COLOR_INDEX1_EXT
:
819 case GL_COLOR_INDEX2_EXT
:
820 case GL_COLOR_INDEX4_EXT
:
821 case GL_COLOR_INDEX8_EXT
:
822 case GL_COLOR_INDEX12_EXT
:
823 case GL_COLOR_INDEX16_EXT
:
825 (*tfmt
) = GR_TEXFMT_P_8
;
827 (*ifmt
) = GL_RGBA
; /* XXX why is this RGBA? */
831 "fx Driver: unsupported internalFormat (0x%x) in fxTexGetFormat()\n",
840 fxIsTexSupported(GLenum target
, GLint internalFormat
,
841 const struct gl_texture_image
*image
)
843 if (target
!= GL_TEXTURE_2D
)
847 (image
->Width
, image
->Height
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
848 NULL
)) return GL_FALSE
;
850 if (image
->Border
> 0)
857 /**********************************************************************/
858 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
859 /**********************************************************************/
861 /* Texel-fetch functions for software texturing and glGetTexImage().
862 * We should have been able to use some "standard" fetch functions (which
863 * may get defined in texutil.c) but we have to account for scaled texture
864 * images on tdfx hardware (the 8:1 aspect ratio limit).
865 * Hence, we need special functions here.
869 fetch_intensity8(const struct gl_texture_image
*texImage
,
870 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
872 GLchan
*rgba
= (GLchan
*) texelOut
;
873 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
874 const GLubyte
*texel
;
879 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
880 rgba
[RCOMP
] = *texel
;
881 rgba
[GCOMP
] = *texel
;
882 rgba
[BCOMP
] = *texel
;
883 rgba
[ACOMP
] = *texel
;
888 fetch_luminance8(const struct gl_texture_image
*texImage
,
889 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
891 GLchan
*rgba
= (GLchan
*) texelOut
;
892 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
893 const GLubyte
*texel
;
898 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
899 rgba
[RCOMP
] = *texel
;
900 rgba
[GCOMP
] = *texel
;
901 rgba
[BCOMP
] = *texel
;
907 fetch_alpha8(const struct gl_texture_image
*texImage
,
908 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
910 GLchan
*rgba
= (GLchan
*) texelOut
;
911 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
912 const GLubyte
*texel
;
916 i
= i
* mml
->width
/ texImage
->Width
;
917 j
= j
* mml
->height
/ texImage
->Height
;
919 texel
= ((GLubyte
*) texImage
->Data
) + j
* mml
->width
+ i
;
923 rgba
[ACOMP
] = *texel
;
928 fetch_index8(const struct gl_texture_image
*texImage
,
929 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
936 fetch_luminance8_alpha8(const struct gl_texture_image
*texImage
,
937 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
939 GLchan
*rgba
= (GLchan
*) texelOut
;
940 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
941 const GLubyte
*texel
;
946 texel
= ((GLubyte
*) texImage
->Data
) + (j
* mml
->width
+ i
) * 2;
947 rgba
[RCOMP
] = texel
[0];
948 rgba
[GCOMP
] = texel
[0];
949 rgba
[BCOMP
] = texel
[0];
950 rgba
[ACOMP
] = texel
[1];
955 fetch_r5g6b5(const struct gl_texture_image
*texImage
,
956 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
958 GLchan
*rgba
= (GLchan
*) texelOut
;
959 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
960 const GLushort
*texel
;
965 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
966 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
967 rgba
[GCOMP
] = (((*texel
) >> 5) & 0x3f) * 255 / 63;
968 rgba
[BCOMP
] = (((*texel
) >> 0) & 0x1f) * 255 / 31;
974 fetch_r4g4b4a4(const struct gl_texture_image
*texImage
,
975 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
977 GLchan
*rgba
= (GLchan
*) texelOut
;
978 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
979 const GLushort
*texel
;
984 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
985 rgba
[RCOMP
] = (((*texel
) >> 12) & 0xf) * 255 / 15;
986 rgba
[GCOMP
] = (((*texel
) >> 8) & 0xf) * 255 / 15;
987 rgba
[BCOMP
] = (((*texel
) >> 4) & 0xf) * 255 / 15;
988 rgba
[ACOMP
] = (((*texel
) >> 0) & 0xf) * 255 / 15;
993 fetch_r5g5b5a1(const struct gl_texture_image
*texImage
,
994 GLint i
, GLint j
, GLint k
, GLvoid
* texelOut
)
996 GLchan
*rgba
= (GLchan
*) texelOut
;
997 const tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
998 const GLushort
*texel
;
1000 i
= i
* mml
->wScale
;
1001 j
= j
* mml
->hScale
;
1003 texel
= ((GLushort
*) texImage
->Data
) + j
* mml
->width
+ i
;
1004 rgba
[RCOMP
] = (((*texel
) >> 11) & 0x1f) * 255 / 31;
1005 rgba
[GCOMP
] = (((*texel
) >> 6) & 0x1f) * 255 / 31;
1006 rgba
[BCOMP
] = (((*texel
) >> 1) & 0x1f) * 255 / 31;
1007 rgba
[ACOMP
] = (((*texel
) >> 0) & 0x01) * 255;
1012 PrintTexture(int w
, int h
, int c
, const GLubyte
* data
)
1015 for (i
= 0; i
< h
; i
++) {
1016 for (j
= 0; j
< w
; j
++) {
1018 printf("%02x %02x ", data
[0], data
[1]);
1020 printf("%02x %02x %02x ", data
[0], data
[1], data
[2]);
1028 static const struct gl_texture_format
*
1029 choose_format(GLenum format
, GLenum type
)
1031 if (type
== CHAN_TYPE
) {
1034 return &_mesa_texformat_alpha
;
1036 return &_mesa_texformat_luminance
;
1037 case GL_LUMINANCE_ALPHA
:
1038 return &_mesa_texformat_luminance_alpha
;
1040 return &_mesa_texformat_intensity
;
1042 return &_mesa_texformat_rgb
;
1044 return &_mesa_texformat_rgba
;
1045 case GL_COLOR_INDEX
:
1046 return &_mesa_texformat_color_index
;
1048 _mesa_problem(NULL
, "Unexpected CHAN format in choose_format\n");
1052 else if (format
== GL_DEPTH_COMPONENT
&& type
== GL_FLOAT
) {
1053 return &_mesa_texformat_depth_component
;
1056 _mesa_problem(NULL
, "Unexpected format/type in choose_format\n");
1063 fxDDTexImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1064 GLint internalFormat
, GLint width
, GLint height
, GLint border
,
1065 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1066 const struct gl_pixelstore_attrib
*packing
,
1067 struct gl_texture_object
*texObj
,
1068 struct gl_texture_image
*texImage
)
1070 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1071 GrTextureFormat_t gldformat
;
1073 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
1074 const struct gl_texture_format
*mesaTexFormat
;
1078 if (!fxIsTexSupported(target
, internalFormat
, texImage
)) {
1079 _mesa_problem(NULL
, "fx Driver: unsupported texture in fxDDTexImg()\n");
1083 if (!texObj
->DriverData
)
1084 texObj
->DriverData
= fxAllocTexObjData(fxMesa
);
1085 ti
= fxTMGetTexInfo(texObj
);
1088 texImage
->DriverData
= MALLOC(sizeof(tfxMipMapLevel
));
1089 mml
= FX_MIPMAP_DATA(texImage
);
1092 fxTexGetFormat(internalFormat
, &gldformat
, NULL
);
1094 fxTexGetInfo(width
, height
, NULL
, NULL
, NULL
, NULL
,
1095 NULL
, NULL
, &mml
->wScale
, &mml
->hScale
);
1097 mml
->width
= width
* mml
->wScale
;
1098 mml
->height
= height
* mml
->hScale
;
1100 switch (internalFormat
) {
1104 case GL_INTENSITY12
:
1105 case GL_INTENSITY16
:
1106 texImage
->Format
= GL_INTENSITY
;
1107 texImage
->FetchTexel
= fetch_intensity8
;
1109 mesaTexFormat
= &_mesa_texformat_i8
;
1115 case GL_LUMINANCE12
:
1116 case GL_LUMINANCE16
:
1117 texImage
->Format
= GL_LUMINANCE
;
1118 texImage
->FetchTexel
= fetch_luminance8
;
1120 mesaTexFormat
= &_mesa_texformat_l8
;
1127 texImage
->Format
= GL_ALPHA
;
1128 texImage
->FetchTexel
= fetch_alpha8
;
1130 mesaTexFormat
= &_mesa_texformat_a8
;
1132 case GL_COLOR_INDEX
:
1133 case GL_COLOR_INDEX1_EXT
:
1134 case GL_COLOR_INDEX2_EXT
:
1135 case GL_COLOR_INDEX4_EXT
:
1136 case GL_COLOR_INDEX8_EXT
:
1137 case GL_COLOR_INDEX12_EXT
:
1138 case GL_COLOR_INDEX16_EXT
:
1139 texImage
->Format
= GL_COLOR_INDEX
;
1140 texImage
->FetchTexel
= fetch_index8
;
1142 mesaTexFormat
= &_mesa_texformat_ci8
;
1145 case GL_LUMINANCE_ALPHA
:
1146 case GL_LUMINANCE4_ALPHA4
:
1147 case GL_LUMINANCE6_ALPHA2
:
1148 case GL_LUMINANCE8_ALPHA8
:
1149 case GL_LUMINANCE12_ALPHA4
:
1150 case GL_LUMINANCE12_ALPHA12
:
1151 case GL_LUMINANCE16_ALPHA16
:
1152 texImage
->Format
= GL_LUMINANCE_ALPHA
;
1153 texImage
->FetchTexel
= fetch_luminance8_alpha8
;
1155 mesaTexFormat
= &_mesa_texformat_al88
;
1166 texImage
->Format
= GL_RGB
;
1167 texImage
->FetchTexel
= fetch_r5g6b5
;
1169 mesaTexFormat
= &_mesa_texformat_rgb565
;
1179 texImage
->Format
= GL_RGBA
;
1180 texImage
->FetchTexel
= fetch_r4g4b4a4
;
1182 mesaTexFormat
= &_mesa_texformat_argb4444
;
1185 texImage
->Format
= GL_RGBA
;
1186 texImage
->FetchTexel
= fetch_r5g5b5a1
;
1188 mesaTexFormat
= &_mesa_texformat_argb1555
;
1191 _mesa_problem(NULL
, "tdfx driver: texbuildimagemap() bad format");
1195 texImage
->TexFormat
= mesaTexFormat
;
1197 /* allocate storage for texture image */
1198 texImage
->Data
= MALLOC(mml
->width
* mml
->height
* texelSize
);
1199 if (!texImage
->Data
)
1202 mml
->glideFormat
= gldformat
;
1203 fxTexInvalidate(ctx
, texObj
);
1205 /* store the texture image */
1206 if (ctx
->_ImageTransferState
||
1207 mml
->width
!= width
||
1208 mml
->height
!= height
) {
1209 /* Need to image transfer ops or image rescale */
1213 success
= _mesa_convert_texsubimage2d(mesaTexFormat
->MesaFormat
,
1214 0, 0, /* xoffset, yoffset */
1215 mml
->width
, mml
->height
,
1216 mml
->width
, /* destImageWidth */
1217 format
, type
, /* user fmt/type */
1218 packing
, /* user packing params */
1219 pixels
, texImage
->Data
);
1223 /* First attempt at texture conversion failed. We may need to
1224 * do fancy pixel transfer ops or convert from an obscure texture
1227 GLenum simpleFormat
= _mesa_base_tex_format(ctx
, internalFormat
);
1228 GLint comps
= _mesa_components_in_format(simpleFormat
);
1231 tempImage
= MALLOC(width
* height
* comps
* sizeof(GLubyte
));
1233 /* Apply pixel transfer ops and convert image format to something
1234 * simple (format = simpleFormat, type = CHAN_TYPE).
1236 _mesa_transfer_teximage(ctx
, 2, /* dimensions */
1237 simpleFormat
, /* base int format */
1238 simpleFormat
, /* dest format */
1239 tempImage
, /* dest addr */
1240 width
, height
, 1, /* src size */
1241 0, 0, 0, /* dst offsets */
1242 width
* comps
, /* dstRowStride */
1243 0, /* dstImageStride */
1244 format
, type
, pixels
, packing
/* src info */ );
1246 if (mml
->width
!= width
|| mml
->height
!= height
) {
1247 /* Upscale image to accomodate Glide's image aspect limitations. */
1248 const struct gl_texture_format
*texFormat
1249 = choose_format(simpleFormat
, CHAN_TYPE
);
1250 GLvoid
*rescaledImage
= MALLOC(mml
->width
* mml
->height
1251 * texFormat
->TexelBytes
);
1252 if (!rescaledImage
) {
1253 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1256 _mesa_rescale_teximage2d(texFormat
,
1257 width
, height
, mml
->width
, mml
->height
,
1258 tempImage
, rescaledImage
);
1259 success
= _mesa_convert_texsubimage2d(mesaTexFormat
->MesaFormat
,
1260 0, 0, /* xoffset, yoffset */
1261 mml
->width
, mml
->height
,
1262 mml
->width
, /* destImageWidth */
1263 simpleFormat
, /* source format */
1264 CHAN_TYPE
, /* source type */
1265 &_mesa_native_packing
,
1266 rescaledImage
, texImage
->Data
);
1267 FREE(rescaledImage
);
1270 success
= _mesa_convert_texsubimage2d(mesaTexFormat
->MesaFormat
,
1271 0, 0, /* xoffset, yoffset */
1272 mml
->width
, mml
->height
,
1273 mml
->width
, /* destImageWidth */
1274 simpleFormat
, /* source format */
1275 CHAN_TYPE
, /* source type */
1276 &_mesa_native_packing
,
1277 tempImage
, texImage
->Data
);
1279 /* the conversion had better of worked! */
1284 if (ti
->validated
&& ti
->isInTM
) {
1285 /*printf("reloadmipmaplevels\n"); */
1286 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1289 /*printf("invalidate2\n"); */
1290 fxTexInvalidate(ctx
, texObj
);
1296 fxDDTexSubImage2D(GLcontext
* ctx
, GLenum target
, GLint level
,
1297 GLint xoffset
, GLint yoffset
,
1298 GLsizei width
, GLsizei height
,
1299 GLenum format
, GLenum type
, const GLvoid
* pixels
,
1300 const struct gl_pixelstore_attrib
*packing
,
1301 struct gl_texture_object
*texObj
,
1302 struct gl_texture_image
*texImage
)
1304 fxMesaContext fxMesa
= (fxMesaContext
) ctx
->DriverCtx
;
1306 tfxMipMapLevel
*mml
;
1309 if (!texObj
->DriverData
) {
1310 _mesa_problem(ctx
, "problem in fxDDTexSubImage2D");
1314 ti
= fxTMGetTexInfo(texObj
);
1316 mml
= FX_MIPMAP_DATA(texImage
);
1319 assert(texImage
->Data
); /* must have an existing texture image! */
1320 assert(texImage
->Format
);
1322 /* XXX check for image rescale */
1323 if (ctx
->_ImageTransferState
||
1324 texImage
->Width
!= mml
->width
||
1325 texImage
->Height
!= mml
->height
) {
1329 success
= _mesa_convert_texsubimage2d(texImage
->TexFormat
->MesaFormat
,
1333 format
, type
, packing
,
1334 pixels
, texImage
->Data
);
1338 /* Incoming image might need scale/bias or is in an uncommon format
1339 * that _mesa_convert_texsubimage() can't deal with. Convert it to
1340 * a simpler format now.
1343 GLenum simpleFormat
= texImage
->TexFormat
->BaseFormat
;
1344 GLint comps
= _mesa_components_in_format(simpleFormat
);
1348 tempImage
= MALLOC(width
* height
* comps
* sizeof(GLubyte
));
1350 /* Apply pixel transfer ops and convert image format to something
1351 * simple (format = simpleFormat, type = CHAN_TYPE).
1353 _mesa_transfer_teximage(ctx
, 2, /* dimensions */
1354 simpleFormat
, /* base int format */
1355 simpleFormat
, /* dest format */
1356 tempImage
, /* dest addr */
1357 width
, height
, 1, /* src size */
1358 0, 0, 0, /* dst offsets */
1359 width
* comps
, /* dstRowStride */
1360 0, /* dstImageStride */
1361 format
, type
, pixels
, packing
/* src info */ );
1363 if (texImage
->Width
!= mml
->width
|| texImage
->Height
!= mml
->height
) {
1364 /* Upscale image to accomodate Glide's image aspect limitations. */
1365 const GLint wScale
= mml
->width
/ texImage
->Width
;
1366 const GLint hScale
= mml
->height
/ texImage
->Height
;
1367 const GLint newWidth
= width
* wScale
;
1368 const GLint newHeight
= height
*hScale
;
1369 GLvoid
*rescaledImage
= MALLOC(newWidth
* newHeight
1370 * texImage
->TexFormat
->TexelBytes
);
1371 assert(mml
->width
>= texImage
->Width
);
1372 assert(mml
->height
>= texImage
->Height
);
1373 if (!rescaledImage
) {
1374 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
1377 _mesa_rescale_teximage2d(texImage
->TexFormat
,
1378 width
, height
, newWidth
, newHeight
,
1379 tempImage
, rescaledImage
);
1380 success
= _mesa_convert_texsubimage2d(texImage
->TexFormat
->MesaFormat
,
1381 xoffset
* wScale
, yoffset
* hScale
,
1382 newWidth
, newHeight
,
1383 mml
->width
, /* destImageWidth */
1384 simpleFormat
, /* source format */
1385 CHAN_TYPE
, /* source type */
1386 &_mesa_native_packing
,
1387 rescaledImage
, texImage
->Data
);
1388 FREE(rescaledImage
);
1391 success
= _mesa_convert_texsubimage2d(texImage
->TexFormat
->MesaFormat
,
1395 simpleFormat
, CHAN_TYPE
,
1396 &_mesa_native_packing
,
1397 tempImage
, texImage
->Data
);
1399 /* the conversion had better of worked! */
1404 if (ti
->validated
&& ti
->isInTM
)
1405 fxTMReloadMipMapLevel(fxMesa
, texObj
, level
);
1407 fxTexInvalidate(ctx
, texObj
);
1415 * Need this to provide at least one external definition.
1418 extern int gl_fx_dummy_function_ddtex(void);
1420 gl_fx_dummy_function_ddtex(void)