1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
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 (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
32 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
35 * Gareth Hughes <gareth@valinux.com>
36 * Brian Paul <brianp@valinux.com>
41 #include "main/enums.h"
42 #include "main/image.h"
43 #include "main/mipmap.h"
44 #include "main/texcompress.h"
45 #include "main/teximage.h"
46 #include "main/texstore.h"
47 #include "main/texobj.h"
48 #include "tdfx_context.h"
50 #include "tdfx_texman.h"
53 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
55 _mesa_halve2x2_teximage2d ( struct gl_context *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;
67 GLuint dstImageOffsets = 0;
74 if (texImage->TexFormat == MESA_FORMAT_RGB565) {
75 _t = GL_UNSIGNED_SHORT_5_6_5_REV;
77 } else if (texImage->TexFormat == MESA_FORMAT_ARGB4444) {
78 _t = GL_UNSIGNED_SHORT_4_4_4_4_REV;
80 } else if (texImage->TexFormat == MESA_FORMAT_ARGB1555) {
81 _t = GL_UNSIGNED_SHORT_1_5_5_5_REV;
86 srcRowStride = srcWidth * bytesPerPixel;
93 _s = src = MALLOC(srcRowStride * srcHeight);
94 _d = dst = MALLOC(dstWidth * bytesPerPixel * dstHeight);
95 _mesa_texstore(ctx, 2, GL_RGBA,
96 MESA_FORMAT_RGBA8888_REV, src,
97 0, 0, 0, /* dstX/Y/Zoffset */
98 srcRowStride, /* dstRowStride */
100 srcWidth, srcHeight, 1,
101 texImage->_BaseFormat, _t, 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 */
147 dstWidth, dstHeight, 1,
148 GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking);
179 tdfxGenerateMipmap(struct gl_context *ctx, GLenum target,
180 struct gl_texture_object *texObj)
182 GLint mipWidth, mipHeight;
183 tdfxMipMapLevel *mip;
184 struct gl_texture_image *mipImage; /* the new/next image */
185 struct gl_texture_image *texImage;
186 const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
187 GLint level = texObj->BaseLevel;
188 GLsizei width, height, texelBytes;
189 const tdfxMipMapLevel *mml;
191 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
192 texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
194 mml = TDFX_TEXIMAGE_DATA(texImage);
196 width = texImage->Width;
197 height = texImage->Height;
198 while (level < texObj->MaxLevel && level < maxLevels - 1) {
199 mipWidth = width / 2;
203 mipHeight = height / 2;
207 if ((mipWidth == width) && (mipHeight == height)) {
211 mipImage = _mesa_select_tex_image(ctx, texObj, target, level);
212 mip = TDFX_TEXIMAGE_DATA(mipImage);
213 _mesa_halve2x2_teximage2d(ctx,
216 mml->width, mml->height,
217 texImage->Data, mipImage->Data);
227 * Compute various texture image parameters.
228 * Input: w, h - source texture width and height
229 * Output: lodlevel - Glide lod level token for the larger texture dimension
230 * aspectratio - Glide aspect ratio token
231 * sscale - S scale factor used during triangle setup
232 * tscale - T scale factor used during triangle setup
233 * wscale - OpenGL -> Glide image width scale factor
234 * hscale - OpenGL -> Glide image height scale factor
237 * w h lodlevel aspectRatio
238 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
239 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
240 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
241 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
242 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
245 tdfxTexGetInfo(const struct gl_context *ctx, int w, int h,
246 GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,
247 float *sscale, float *tscale,
248 int *wscale, int *hscale)
250 int logw, logh, ar, lod, ws, hs;
258 ar = logw - logh; /* aspect ratio = difference in log dimensions */
262 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
263 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
267 if (ar <= GR_ASPECT_LOG2_8x1) {
271 /* have to stretch image height */
274 ar = GR_ASPECT_LOG2_8x1;
280 if (ar >= GR_ASPECT_LOG2_1x8) {
284 /* have to stretch image width */
287 ar = GR_ASPECT_LOG2_1x8;
292 *lodlevel = (GrLOD_t) lod;
294 *aspectratio = (GrAspectRatio_t) ar;
307 * We need to call this when a texture object's minification filter
308 * or texture image sizes change.
310 static void RevalidateTexture(struct gl_context *ctx, struct gl_texture_object *tObj)
312 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
318 minl = maxl = tObj->BaseLevel;
320 if (tObj->Image[0][minl]) {
321 maxl = MIN2(tObj->MaxLevel, tObj->Image[0][minl]->MaxLog2);
323 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
324 tdfxTexGetInfo(ctx, tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,
325 &ti->info.largeLodLog2,
326 &ti->info.aspectRatioLog2,
327 &(ti->sScale), &(ti->tScale), NULL, NULL);
330 if (tObj->Image[0][maxl] && (tObj->Sampler.MinFilter != GL_NEAREST) && (tObj->Sampler.MinFilter != GL_LINEAR)) {
331 /* mipmapping: need to compute smallLodLog2 */
332 tdfxTexGetInfo(ctx, tObj->Image[0][maxl]->Width,
333 tObj->Image[0][maxl]->Height,
334 &ti->info.smallLodLog2, NULL,
335 NULL, NULL, NULL, NULL);
338 /* not mipmapping: smallLodLog2 = largeLodLog2 */
339 ti->info.smallLodLog2 = ti->info.largeLodLog2;
345 ti->info.data = NULL;
347 /* this is necessary because of fxDDCompressedTexImage2D */
349 struct gl_texture_image *texImage = tObj->Image[0][minl];
350 tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
351 if (mml->wScale != 1 || mml->hScale != 1) {
352 ti->sScale /= mml->wScale;
353 ti->tScale /= mml->hScale;
360 fxAllocTexObjData(tdfxContextPtr fxMesa)
364 if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) {
365 _mesa_problem(NULL, "tdfx driver: out of memory");
369 ti->isInTM = GL_FALSE;
371 ti->whichTMU = TDFX_TMU_NONE;
373 ti->tm[TDFX_TMU0] = NULL;
374 ti->tm[TDFX_TMU1] = NULL;
376 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
377 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
379 ti->sClamp = GR_TEXTURECLAMP_WRAP;
380 ti->tClamp = GR_TEXTURECLAMP_WRAP;
382 ti->mmMode = GR_MIPMAP_NEAREST;
383 ti->LODblend = FXFALSE;
390 * Called via glBindTexture.
393 tdfxBindTexture(struct gl_context * ctx, GLenum target,
394 struct gl_texture_object *tObj)
396 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
399 if (MESA_VERBOSE & VERBOSE_DRIVER) {
400 fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,
404 if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D))
407 if (!tObj->DriverData) {
408 tObj->DriverData = fxAllocTexObjData(fxMesa);
411 ti = TDFX_TEXTURE_DATA(tObj);
412 ti->lastTimeUsed = fxMesa->texBindNumber++;
414 fxMesa->new_state |= TDFX_NEW_TEXTURE;
419 * Called via glTexEnv.
422 tdfxTexEnv(struct gl_context * ctx, GLenum target, GLenum pname,
423 const GLfloat * param)
425 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
427 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
429 fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,
432 fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
435 /* XXX this is a bit of a hack to force the Glide texture
436 * state to be updated.
438 fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit] = 0;
440 fxMesa->new_state |= TDFX_NEW_TEXTURE;
445 * Called via glTexParameter.
448 tdfxTexParameter(struct gl_context * ctx, GLenum target,
449 struct gl_texture_object *tObj,
450 GLenum pname, const GLfloat * params)
452 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
453 GLenum param = (GLenum) (GLint) params[0];
456 if (MESA_VERBOSE & VERBOSE_DRIVER) {
457 fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,
458 tObj->DriverData, pname, param);
461 if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D))
464 if (!tObj->DriverData)
465 tObj->DriverData = fxAllocTexObjData(fxMesa);
467 ti = TDFX_TEXTURE_DATA(tObj);
470 case GL_TEXTURE_MIN_FILTER:
473 ti->mmMode = GR_MIPMAP_DISABLE;
474 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
475 ti->LODblend = FXFALSE;
478 ti->mmMode = GR_MIPMAP_DISABLE;
479 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
480 ti->LODblend = FXFALSE;
482 case GL_NEAREST_MIPMAP_LINEAR:
483 if (!fxMesa->Glide.HaveCombineExt) {
484 if (fxMesa->haveTwoTMUs) {
485 ti->mmMode = GR_MIPMAP_NEAREST;
486 ti->LODblend = FXTRUE;
489 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
490 ti->LODblend = FXFALSE;
492 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
495 /* XXX Voodoo3/Banshee mipmap blending seems to produce
496 * incorrectly filtered colors for the smallest mipmap levels.
497 * To work-around we fall-through here and use a different filter.
499 case GL_NEAREST_MIPMAP_NEAREST:
500 ti->mmMode = GR_MIPMAP_NEAREST;
501 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
502 ti->LODblend = FXFALSE;
504 case GL_LINEAR_MIPMAP_LINEAR:
505 if (!fxMesa->Glide.HaveCombineExt) {
506 if (fxMesa->haveTwoTMUs) {
507 ti->mmMode = GR_MIPMAP_NEAREST;
508 ti->LODblend = FXTRUE;
511 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
512 ti->LODblend = FXFALSE;
514 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
517 /* XXX Voodoo3/Banshee mipmap blending seems to produce
518 * incorrectly filtered colors for the smallest mipmap levels.
519 * To work-around we fall-through here and use a different filter.
521 case GL_LINEAR_MIPMAP_NEAREST:
522 ti->mmMode = GR_MIPMAP_NEAREST;
523 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
524 ti->LODblend = FXFALSE;
529 ti->reloadImages = GL_TRUE;
530 RevalidateTexture(ctx, tObj);
531 fxMesa->new_state |= TDFX_NEW_TEXTURE;
534 case GL_TEXTURE_MAG_FILTER:
537 ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
540 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
545 fxMesa->new_state |= TDFX_NEW_TEXTURE;
548 case GL_TEXTURE_WRAP_S:
550 case GL_CLAMP_TO_BORDER:
551 case GL_CLAMP_TO_EDGE:
553 ti->sClamp = GR_TEXTURECLAMP_CLAMP;
556 ti->sClamp = GR_TEXTURECLAMP_WRAP;
558 case GL_MIRRORED_REPEAT:
559 ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT;
564 fxMesa->new_state |= TDFX_NEW_TEXTURE;
567 case GL_TEXTURE_WRAP_T:
569 case GL_CLAMP_TO_BORDER:
570 case GL_CLAMP_TO_EDGE:
572 ti->tClamp = GR_TEXTURECLAMP_CLAMP;
575 ti->tClamp = GR_TEXTURECLAMP_WRAP;
577 case GL_MIRRORED_REPEAT:
578 ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT;
583 fxMesa->new_state |= TDFX_NEW_TEXTURE;
586 case GL_TEXTURE_BORDER_COLOR:
589 case GL_TEXTURE_MIN_LOD:
592 case GL_TEXTURE_MAX_LOD:
595 case GL_TEXTURE_BASE_LEVEL:
596 RevalidateTexture(ctx, tObj);
598 case GL_TEXTURE_MAX_LEVEL:
599 RevalidateTexture(ctx, tObj);
609 * Called via glDeleteTextures to delete a texture object.
610 * Here, we delete the Glide data associated with the texture.
613 tdfxDeleteTexture(struct gl_context * ctx, struct gl_texture_object *tObj)
615 if (ctx && ctx->DriverCtx) {
616 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
617 tdfxTMFreeTexture(fxMesa, tObj);
618 fxMesa->new_state |= TDFX_NEW_TEXTURE;
619 /* Free mipmap images and the texture object itself */
620 _mesa_delete_texture_object(ctx, tObj);
626 * Return true if texture is resident, false otherwise.
629 tdfxIsTextureResident(struct gl_context *ctx, struct gl_texture_object *tObj)
631 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
632 return (GLboolean) (ti && ti->isInTM);
638 * Convert a gl_color_table texture palette to Glide's format.
641 convertPalette(FxU32 data[256], const struct gl_color_table *table)
643 const GLubyte *tableUB = table->TableUB;
644 GLint width = table->Size;
648 switch (table->_BaseFormat) {
650 for (i = 0; i < width; i++) {
655 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
657 return GR_TEXTABLE_PALETTE_6666_EXT;
659 for (i = 0; i < width; i++) {
664 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
666 return GR_TEXTABLE_PALETTE;
668 for (i = 0; i < width; i++) {
671 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
673 return GR_TEXTABLE_PALETTE_6666_EXT;
674 case GL_LUMINANCE_ALPHA:
675 for (i = 0; i < width; i++) {
676 r = g = b = tableUB[i * 2 + 0];
677 a = tableUB[i * 2 + 1];
678 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
680 return GR_TEXTABLE_PALETTE_6666_EXT;
682 for (i = 0; i < width; i++) {
683 r = tableUB[i * 3 + 0];
684 g = tableUB[i * 3 + 1];
685 b = tableUB[i * 3 + 2];
687 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
689 return GR_TEXTABLE_PALETTE;
691 for (i = 0; i < width; i++) {
692 r = tableUB[i * 4 + 0];
693 g = tableUB[i * 4 + 1];
694 b = tableUB[i * 4 + 2];
695 a = tableUB[i * 4 + 3];
696 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
698 return GR_TEXTABLE_PALETTE_6666_EXT;
700 /* XXX fixme: how can this happen? */
701 _mesa_error(NULL, GL_INVALID_ENUM, "convertPalette: table->_BaseFormat == %s",
702 _mesa_lookup_enum_by_nr(table->_BaseFormat));
703 return GR_TEXTABLE_PALETTE;
710 tdfxUpdateTexturePalette(struct gl_context * ctx, struct gl_texture_object *tObj)
712 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
715 /* per-texture palette */
718 /* This might be a proxy texture. */
719 if (!tObj->Palette.TableUB)
722 if (!tObj->DriverData)
723 tObj->DriverData = fxAllocTexObjData(fxMesa);
724 ti = TDFX_TEXTURE_DATA(tObj);
726 ti->paltype = convertPalette(ti->palette.data, &tObj->Palette);
727 /*tdfxTexInvalidate(ctx, tObj);*/
730 /* global texture palette */
731 fxMesa->TexPalette.Type = convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
732 fxMesa->TexPalette.Data = &(fxMesa->glbPalette.data);
733 fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
735 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */
739 /**********************************************************************/
740 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
741 /**********************************************************************/
744 static FxBool TexusFatalError = FXFALSE;
745 static FxBool TexusError = FXFALSE;
747 #define TX_DITHER_NONE 0x00000000
750 fxTexusError(const char *string, FxBool fatal)
752 _mesa_problem(NULL, string);
754 * Just propagate the fatal value up.
757 TexusFatalError = fatal;
763 tdfxChooseTextureFormat( struct gl_context *ctx, GLint internalFormat,
764 GLenum srcFormat, GLenum srcType )
766 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
767 const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
769 switch (internalFormat) {
775 case GL_COMPRESSED_ALPHA:
776 return MESA_FORMAT_A8;
783 case GL_COMPRESSED_LUMINANCE:
784 return MESA_FORMAT_L8;
786 case GL_LUMINANCE_ALPHA:
787 case GL_LUMINANCE4_ALPHA4:
788 case GL_LUMINANCE6_ALPHA2:
789 case GL_LUMINANCE8_ALPHA8:
790 case GL_LUMINANCE12_ALPHA4:
791 case GL_LUMINANCE12_ALPHA12:
792 case GL_LUMINANCE16_ALPHA16:
793 case GL_COMPRESSED_LUMINANCE_ALPHA:
794 return MESA_FORMAT_AL88;
800 case GL_COMPRESSED_INTENSITY:
801 return MESA_FORMAT_I8;
805 return MESA_FORMAT_RGB565;
806 case GL_COMPRESSED_RGB:
807 /* intentional fall-through */
810 if ( srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5 ) {
811 return MESA_FORMAT_RGB565;
813 /* intentional fall through */
818 return (allow32bpt) ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565;
821 return MESA_FORMAT_ARGB4444;
822 case GL_COMPRESSED_RGBA:
823 /* intentional fall-through */
826 if ( srcFormat == GL_BGRA ) {
827 if ( srcType == GL_UNSIGNED_INT_8_8_8_8_REV ) {
828 return MESA_FORMAT_ARGB8888;
830 else if ( srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
831 return MESA_FORMAT_ARGB4444;
833 else if ( srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
834 return MESA_FORMAT_ARGB1555;
837 /* intentional fall through */
842 return allow32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444;
844 return MESA_FORMAT_ARGB1555;
846 case GL_COLOR_INDEX1_EXT:
847 case GL_COLOR_INDEX2_EXT:
848 case GL_COLOR_INDEX4_EXT:
849 case GL_COLOR_INDEX8_EXT:
850 case GL_COLOR_INDEX12_EXT:
851 case GL_COLOR_INDEX16_EXT:
852 return MESA_FORMAT_CI8;
853 /* GL_EXT_texture_compression_s3tc */
855 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
858 return MESA_FORMAT_RGB_DXT1;
859 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
860 return MESA_FORMAT_RGBA_DXT1;
861 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
864 return MESA_FORMAT_RGBA_DXT3;
865 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
866 return MESA_FORMAT_RGBA_DXT5;
867 /* GL_3DFX_texture_compression_FXT1 */
868 case GL_COMPRESSED_RGB_FXT1_3DFX:
869 return MESA_FORMAT_RGB_FXT1;
870 case GL_COMPRESSED_RGBA_FXT1_3DFX:
871 return MESA_FORMAT_RGBA_FXT1;
873 _mesa_problem(ctx, "unexpected format in tdfxChooseTextureFormat");
874 return MESA_FORMAT_NONE;
880 * Return the Glide format for the given mesa texture format.
882 static GrTextureFormat_t
883 fxGlideFormat(GLint mesaFormat)
885 switch (mesaFormat) {
887 return GR_TEXFMT_ALPHA_8;
889 return GR_TEXFMT_ALPHA_8;
891 return GR_TEXFMT_INTENSITY_8;
892 case MESA_FORMAT_CI8:
893 return GR_TEXFMT_P_8;
894 case MESA_FORMAT_AL88:
895 return GR_TEXFMT_ALPHA_INTENSITY_88;
896 case MESA_FORMAT_RGB565:
897 return GR_TEXFMT_RGB_565;
898 case MESA_FORMAT_ARGB4444:
899 return GR_TEXFMT_ARGB_4444;
900 case MESA_FORMAT_ARGB1555:
901 return GR_TEXFMT_ARGB_1555;
902 case MESA_FORMAT_ARGB8888:
903 return GR_TEXFMT_ARGB_8888;
904 case MESA_FORMAT_RGB_FXT1:
905 case MESA_FORMAT_RGBA_FXT1:
906 return GR_TEXFMT_ARGB_CMP_FXT1;
907 case MESA_FORMAT_RGB_DXT1:
908 case MESA_FORMAT_RGBA_DXT1:
909 return GR_TEXFMT_ARGB_CMP_DXT1;
910 case MESA_FORMAT_RGBA_DXT3:
911 return GR_TEXFMT_ARGB_CMP_DXT3;
912 case MESA_FORMAT_RGBA_DXT5:
913 return GR_TEXFMT_ARGB_CMP_DXT5;
915 _mesa_problem(NULL, "Unexpected format in fxGlideFormat");
921 /* Texel-fetch functions for software texturing and glGetTexImage().
922 * We should have been able to use some "standard" fetch functions (which
923 * may get defined in texutil.c) but we have to account for scaled texture
924 * images on tdfx hardware (the 8:1 aspect ratio limit).
925 * Hence, we need special functions here.
928 fxt1_decode_1 (const void *texture, int width,
929 int i, int j, unsigned char *rgba);
932 fetch_intensity8(const struct gl_texture_image *texImage,
933 GLint i, GLint j, GLint k, GLchan * rgba)
935 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
936 const GLubyte *texel;
941 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
942 rgba[RCOMP] = *texel;
943 rgba[GCOMP] = *texel;
944 rgba[BCOMP] = *texel;
945 rgba[ACOMP] = *texel;
950 fetch_luminance8(const struct gl_texture_image *texImage,
951 GLint i, GLint j, GLint k, GLchan * rgba)
953 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
954 const GLubyte *texel;
959 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
960 rgba[RCOMP] = *texel;
961 rgba[GCOMP] = *texel;
962 rgba[BCOMP] = *texel;
968 fetch_alpha8(const struct gl_texture_image *texImage,
969 GLint i, GLint j, GLint k, GLchan * rgba)
971 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
972 const GLubyte *texel;
977 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
981 rgba[ACOMP] = *texel;
986 fetch_index8(const struct gl_texture_image *texImage,
987 GLint i, GLint j, GLint k, GLchan * indexOut)
989 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
990 const GLubyte *texel;
995 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
1001 fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
1002 GLint i, GLint j, GLint k, GLchan * rgba)
1004 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1005 const GLubyte *texel;
1007 i = i * mml->wScale;
1008 j = j * mml->hScale;
1010 texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2;
1011 rgba[RCOMP] = texel[0];
1012 rgba[GCOMP] = texel[0];
1013 rgba[BCOMP] = texel[0];
1014 rgba[ACOMP] = texel[1];
1019 fetch_r5g6b5(const struct gl_texture_image *texImage,
1020 GLint i, GLint j, GLint k, GLchan * rgba)
1022 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1023 const GLushort *texel;
1025 i = i * mml->wScale;
1026 j = j * mml->hScale;
1028 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
1029 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
1030 rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63;
1031 rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31;
1037 fetch_r4g4b4a4(const struct gl_texture_image *texImage,
1038 GLint i, GLint j, GLint k, GLchan * rgba)
1040 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1041 const GLushort *texel;
1043 i = i * mml->wScale;
1044 j = j * mml->hScale;
1046 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
1047 rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15;
1048 rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15;
1049 rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15;
1050 rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;
1055 fetch_r5g5b5a1(const struct gl_texture_image *texImage,
1056 GLint i, GLint j, GLint k, GLchan * rgba)
1058 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1059 const GLushort *texel;
1061 i = i * mml->wScale;
1062 j = j * mml->hScale;
1064 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
1065 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
1066 rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31;
1067 rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31;
1068 rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;
1073 fetch_a8r8g8b8(const struct gl_texture_image *texImage,
1074 GLint i, GLint j, GLint k, GLchan * rgba)
1076 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1077 const GLuint *texel;
1079 i = i * mml->wScale;
1080 j = j * mml->hScale;
1082 texel = ((GLuint *) texImage->Data) + j * mml->width + i;
1083 rgba[RCOMP] = (((*texel) >> 16) & 0xff);
1084 rgba[GCOMP] = (((*texel) >> 8) & 0xff);
1085 rgba[BCOMP] = (((*texel) ) & 0xff);
1086 rgba[ACOMP] = (((*texel) >> 24) & 0xff);
1091 fetch_rgb_fxt1(const struct gl_texture_image *texImage,
1092 GLint i, GLint j, GLint k, GLchan *rgba)
1094 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1096 i = i * mml->wScale;
1097 j = j * mml->hScale;
1099 fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);
1105 fetch_rgba_fxt1(const struct gl_texture_image *texImage,
1106 GLint i, GLint j, GLint k, GLchan *rgba)
1108 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1110 i = i * mml->wScale;
1111 j = j * mml->hScale;
1113 fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);
1118 fetch_rgb_dxt1(const struct gl_texture_image *texImage,
1119 GLint i, GLint j, GLint k, GLchan *rgba)
1121 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1123 i = i * mml->wScale;
1124 j = j * mml->hScale;
1126 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1127 _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
1133 fetch_rgba_dxt1(const struct gl_texture_image *texImage,
1134 GLint i, GLint j, GLint k, GLchan *rgba)
1136 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1138 i = i * mml->wScale;
1139 j = j * mml->hScale;
1141 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1142 _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
1148 fetch_rgba_dxt3(const struct gl_texture_image *texImage,
1149 GLint i, GLint j, GLint k, GLchan *rgba)
1151 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1153 i = i * mml->wScale;
1154 j = j * mml->hScale;
1156 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1157 _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba);
1163 fetch_rgba_dxt5(const struct gl_texture_image *texImage,
1164 GLint i, GLint j, GLint k, GLchan *rgba)
1166 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1168 i = i * mml->wScale;
1169 j = j * mml->hScale;
1171 /* XXX Get fetch func from _mesa_get_texel_fetch_func()
1172 _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba);
1177 static FetchTexelFuncC
1178 fxFetchFunction(GLint mesaFormat)
1180 switch (mesaFormat) {
1181 case MESA_FORMAT_I8:
1182 return &fetch_intensity8;
1183 case MESA_FORMAT_A8:
1184 return &fetch_alpha8;
1185 case MESA_FORMAT_L8:
1186 return &fetch_luminance8;
1187 case MESA_FORMAT_CI8:
1188 return &fetch_index8;
1189 case MESA_FORMAT_AL88:
1190 return &fetch_luminance8_alpha8;
1191 case MESA_FORMAT_RGB565:
1192 return &fetch_r5g6b5;
1193 case MESA_FORMAT_ARGB4444:
1194 return &fetch_r4g4b4a4;
1195 case MESA_FORMAT_ARGB1555:
1196 return &fetch_r5g5b5a1;
1197 case MESA_FORMAT_ARGB8888:
1198 return &fetch_a8r8g8b8;
1199 case MESA_FORMAT_RGB_FXT1:
1200 return &fetch_rgb_fxt1;
1201 case MESA_FORMAT_RGBA_FXT1:
1202 return &fetch_rgba_fxt1;
1203 case MESA_FORMAT_RGB_DXT1:
1204 return &fetch_rgb_dxt1;
1205 case MESA_FORMAT_RGBA_DXT1:
1206 return &fetch_rgba_dxt1;
1207 case MESA_FORMAT_RGBA_DXT3:
1208 return &fetch_rgba_dxt3;
1209 case MESA_FORMAT_RGBA_DXT5:
1210 return &fetch_rgba_dxt5;
1212 _mesa_problem(NULL, "Unexpected format in fxFetchFunction");
1219 adjust2DRatio (struct gl_context *ctx,
1220 GLint xoffset, GLint yoffset,
1221 GLint width, GLint height,
1222 GLenum format, GLenum type, const GLvoid *pixels,
1223 const struct gl_pixelstore_attrib *packing,
1224 tdfxMipMapLevel *mml,
1225 struct gl_texture_image *texImage,
1229 const GLint newWidth = width * mml->wScale;
1230 const GLint newHeight = height * mml->hScale;
1232 GLuint dstImageOffsets = 0;
1234 if (!_mesa_is_format_compressed(texImage->TexFormat)) {
1237 tempImage = MALLOC(width * height * texelBytes);
1242 _mesa_texstore(ctx, 2, texImage->_BaseFormat,
1243 texImage->TexFormat, tempImage,
1244 0, 0, 0, /* dstX/Y/Zoffset */
1245 width * texelBytes, /* dstRowStride */
1248 format, type, pixels, packing);
1251 /* compute address of dest subimage within the overal tex image */
1252 destAddr = (GLubyte *) texImage->Data
1253 + (yoffset * mml->hScale * mml->width
1254 + xoffset * mml->wScale) * texelBytes;
1256 _mesa_rescale_teximage2d(texelBytes,
1258 dstRowStride, /* dst stride */
1260 newWidth, newHeight,
1261 tempImage, destAddr);
1263 const GLint rawBytes = 4;
1264 GLvoid *rawImage = MALLOC(width * height * rawBytes);
1269 tempImage = MALLOC(newWidth * newHeight * rawBytes);
1274 /* unpack image, apply transfer ops and store in rawImage */
1275 _mesa_texstore(ctx, 2, GL_RGBA,
1276 MESA_FORMAT_RGBA8888_REV, rawImage,
1277 0, 0, 0, /* dstX/Y/Zoffset */
1278 width * rawBytes, /* dstRowStride */
1281 format, type, pixels, packing);
1282 _mesa_rescale_teximage2d(rawBytes,
1284 newWidth * rawBytes, /* dst stride */
1285 width, height, /* src */
1286 newWidth, newHeight, /* dst */
1287 rawImage /*src*/, tempImage /*dst*/ );
1288 _mesa_texstore(ctx, 2, texImage->_BaseFormat,
1289 texImage->TexFormat, texImage->Data,
1290 xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */
1293 newWidth, newHeight, 1,
1294 GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking);
1305 tdfxTexImage2D(struct gl_context *ctx, GLenum target, GLint level,
1306 GLint internalFormat, GLint width, GLint height, GLint border,
1307 GLenum format, GLenum type, const GLvoid *pixels,
1308 const struct gl_pixelstore_attrib *packing,
1309 struct gl_texture_object *texObj,
1310 struct gl_texture_image *texImage)
1312 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1314 tdfxMipMapLevel *mml;
1315 GLint texelBytes, dstRowStride;
1319 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1320 texObj->Name, texImage->InternalFormat, format, type,
1321 texImage->Width, texImage->Height);
1324 ti = TDFX_TEXTURE_DATA(texObj);
1326 texObj->DriverData = fxAllocTexObjData(fxMesa);
1327 if (!texObj->DriverData) {
1328 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1331 ti = TDFX_TEXTURE_DATA(texObj);
1335 mml = TDFX_TEXIMAGE_DATA(texImage);
1337 texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
1338 if (!texImage->DriverData) {
1339 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1342 mml = TDFX_TEXIMAGE_DATA(texImage);
1345 /* Determine width and height scale factors for texture.
1346 * Remember, Glide is limited to 8:1 aspect ratios.
1349 texImage->Width, texImage->Height,
1350 NULL, /* lod level */
1351 NULL, /* aspect ratio */
1352 NULL, NULL, /* sscale, tscale */
1353 &mml->wScale, &mml->hScale);
1355 /* rescaled size: */
1356 mml->width = width * mml->wScale;
1357 mml->height = height * mml->hScale;
1359 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1360 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1361 /* [dBorca] we should update texture's attribute, then,
1362 * because if the application asks us to decompress, we
1363 * have to know the REAL format! Also, DXT3/5 might not
1364 * be correct, since it would mess with "compressedSize".
1365 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1367 if (_mesa_is_format_compressed(texImage->TexFormat)) {
1368 switch (internalFormat) {
1369 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1372 internalFormat = GL_COMPRESSED_RGB_FXT1_3DFX;
1374 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1375 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1376 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1379 internalFormat = GL_COMPRESSED_RGBA_FXT1_3DFX;
1381 texImage->InternalFormat = internalFormat;
1385 if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
1386 GLenum texNapalm = 0;
1387 if (internalFormat == GL_COMPRESSED_RGB) {
1388 texNapalm = GL_COMPRESSED_RGB_FXT1_3DFX;
1389 } else if (internalFormat == GL_COMPRESSED_RGBA) {
1390 texNapalm = GL_COMPRESSED_RGBA_FXT1_3DFX;
1393 texImage->InternalFormat = internalFormat = texNapalm;
1394 _mesa_is_format_compressed(texImage->TexFormat) = GL_TRUE;
1399 mesaFormat = texImage->TexFormat;
1400 mml->glideFormat = fxGlideFormat(mesaFormat);
1401 ti->info.format = mml->glideFormat;
1402 texImage->FetchTexelc = fxFetchFunction(mesaFormat);
1403 texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
1405 if (_mesa_is_format_compressed(texImage->TexFormat)) {
1406 GLuint compressedSize = _mesa_format_image_size(mesaFormat, mml->width,
1408 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, mml->width);
1409 texImage->Data = _mesa_alloc_texmemory(compressedSize);
1411 dstRowStride = mml->width * texelBytes;
1412 texImage->Data = _mesa_alloc_texmemory(mml->width * mml->height * texelBytes);
1414 if (!texImage->Data) {
1415 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1419 if (pixels != NULL) {
1420 if (mml->wScale != 1 || mml->hScale != 1) {
1421 /* rescale image to overcome 1:8 aspect limitation */
1422 if (!adjust2DRatio(ctx,
1425 format, type, pixels,
1432 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1437 /* no rescaling needed */
1438 /* unpack image, apply transfer ops and store in texImage->Data */
1439 _mesa_texstore(ctx, 2, texImage->_BaseFormat,
1440 texImage->TexFormat, texImage->Data,
1441 0, 0, 0, /* dstX/Y/Zoffset */
1443 texImage->ImageOffsets,
1445 format, type, pixels, packing);
1449 RevalidateTexture(ctx, texObj);
1451 ti->reloadImages = GL_TRUE;
1452 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1457 tdfxTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
1458 GLint xoffset, GLint yoffset,
1459 GLsizei width, GLsizei height,
1460 GLenum format, GLenum type,
1461 const GLvoid *pixels,
1462 const struct gl_pixelstore_attrib *packing,
1463 struct gl_texture_object *texObj,
1464 struct gl_texture_image *texImage )
1466 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1468 tdfxMipMapLevel *mml;
1469 GLint texelBytes, dstRowStride;
1471 if (!texObj->DriverData) {
1472 _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
1476 ti = TDFX_TEXTURE_DATA(texObj);
1478 mml = TDFX_TEXIMAGE_DATA(texImage);
1481 assert(texImage->Data); /* must have an existing texture image! */
1482 assert(texImage->_BaseFormat);
1484 texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
1485 if (_mesa_is_format_compressed(texImage->TexFormat)) {
1486 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, mml->width);
1488 dstRowStride = mml->width * texelBytes;
1491 if (mml->wScale != 1 || mml->hScale != 1) {
1492 /* need to rescale subimage to match mipmap level's rescale factors */
1493 if (!adjust2DRatio(ctx,
1496 format, type, pixels,
1503 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1508 /* no rescaling needed */
1509 _mesa_texstore(ctx, 2, texImage->_BaseFormat,
1510 texImage->TexFormat, texImage->Data,
1511 xoffset, yoffset, 0,
1513 texImage->ImageOffsets,
1515 format, type, pixels, packing);
1518 ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
1519 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
1524 tdfxTexImage1D(struct gl_context *ctx, GLenum target, GLint level,
1525 GLint internalFormat, GLint width, GLint border,
1526 GLenum format, GLenum type, const GLvoid *pixels,
1527 const struct gl_pixelstore_attrib *packing,
1528 struct gl_texture_object *texObj,
1529 struct gl_texture_image *texImage)
1531 tdfxTexImage2D(ctx, target, level,
1532 internalFormat, width, 1, border,
1533 format, type, pixels,
1540 tdfxTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
1543 GLenum format, GLenum type,
1544 const GLvoid *pixels,
1545 const struct gl_pixelstore_attrib *packing,
1546 struct gl_texture_object *texObj,
1547 struct gl_texture_image *texImage )
1549 tdfxTexSubImage2D(ctx, target, level,
1559 /**********************************************************************/
1560 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1561 /**********************************************************************/
1564 tdfxCompressedTexImage2D (struct gl_context *ctx, GLenum target,
1565 GLint level, GLint internalFormat,
1566 GLsizei width, GLsizei height, GLint border,
1567 GLsizei imageSize, const GLvoid *data,
1568 struct gl_texture_object *texObj,
1569 struct gl_texture_image *texImage)
1571 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1573 tdfxMipMapLevel *mml;
1574 gl_format mesaFormat;
1575 GLuint compressedSize = 0;
1577 if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
1578 fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1579 texObj->Name, internalFormat,
1583 if ((target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) || texImage->Border > 0) {
1584 _mesa_problem(NULL, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
1588 ti = TDFX_TEXTURE_DATA(texObj);
1590 texObj->DriverData = fxAllocTexObjData(fxMesa);
1591 if (!texObj->DriverData) {
1592 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
1595 ti = TDFX_TEXTURE_DATA(texObj);
1599 mml = TDFX_TEXIMAGE_DATA(texImage);
1601 texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
1602 if (!texImage->DriverData) {
1603 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
1606 mml = TDFX_TEXIMAGE_DATA(texImage);
1609 tdfxTexGetInfo(ctx, width, height, NULL, NULL, NULL, NULL,
1610 &mml->wScale, &mml->hScale);
1612 mml->width = width * mml->wScale;
1613 mml->height = height * mml->hScale;
1616 /* Determine the appropriate Glide texel format,
1617 * given the user's internal texture format hint.
1619 mesaFormat = texImage->TexFormat;
1620 mml->glideFormat = fxGlideFormat(mesaFormat);
1621 ti->info.format = mml->glideFormat;
1622 texImage->FetchTexelc = fxFetchFunction(mesaFormat);
1624 /* allocate new storage for texture image, if needed */
1625 if (!texImage->Data) {
1626 compressedSize = _mesa_format_image_size(mesaFormat, mml->width,
1628 texImage->Data = _mesa_alloc_texmemory(compressedSize);
1629 if (!texImage->Data) {
1630 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
1635 /* save the texture data */
1636 if (mml->wScale != 1 || mml->hScale != 1) {
1637 /* [dBorca] Hack alert:
1638 * now we're screwed. We can't decompress,
1639 * unless we do it in HW (via textureBuffer).
1640 * We still have some chances:
1641 * 1) we got FXT1 textures - we CAN decompress, rescale for
1642 * aspectratio, then compress back.
1643 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1644 * Thus, we don't care about textureclamp and we could lower
1645 * MIN("uscale", "vscale") below 32. We still have to have
1646 * our data aligned inside a 8:1 rectangle.
1647 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1648 * we replicate the data over the padded area.
1649 * For now, we take 2) + 3) but texelfetchers will be wrong!
1651 const GLuint mesaFormat = texImage->TexFormat;
1652 GLuint srcRowStride = _mesa_format_row_stride(mesaFormat, width);
1654 GLuint destRowStride = _mesa_format_row_stride(mesaFormat,
1657 _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4,
1658 destRowStride, (mml->height+3) / 4,
1659 1, data, srcRowStride,
1661 ti->padded = GL_TRUE;
1663 memcpy(texImage->Data, data, compressedSize);
1666 RevalidateTexture(ctx, texObj);
1668 ti->reloadImages = GL_TRUE;
1669 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1674 tdfxCompressedTexSubImage2D( struct gl_context *ctx, GLenum target,
1675 GLint level, GLint xoffset,
1676 GLint yoffset, GLsizei width,
1677 GLint height, GLenum format,
1678 GLsizei imageSize, const GLvoid *data,
1679 struct gl_texture_object *texObj,
1680 struct gl_texture_image *texImage )
1682 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1684 tdfxMipMapLevel *mml;
1685 GLint destRowStride, srcRowStride;
1688 const GLuint mesaFormat = texImage->TexFormat;
1690 if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
1691 fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name);
1694 ti = TDFX_TEXTURE_DATA(texObj);
1696 mml = TDFX_TEXIMAGE_DATA(texImage);
1699 srcRowStride = _mesa_format_row_stride(mesaFormat, width);
1701 destRowStride = _mesa_format_row_stride(mesaFormat, mml->width);
1702 dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
1705 (GLubyte*) texImage->Data);
1707 rows = height / 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1709 for (i = 0; i < rows; i++) {
1710 memcpy(dest, data, srcRowStride);
1711 dest += destRowStride;
1712 data = (GLvoid *)((intptr_t)data + (intptr_t)srcRowStride);
1715 /* [dBorca] Hack alert:
1716 * see fxDDCompressedTexImage2D for caveats
1718 if (mml->wScale != 1 || mml->hScale != 1) {
1719 srcRowStride = _mesa_format_row_stride(mesaFormat, texImage->Width);
1721 destRowStride = _mesa_format_row_stride(mesaFormat, mml->width);
1722 _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4,
1723 destRowStride, mml->height / 4,
1724 1, texImage->Data, destRowStride,
1728 RevalidateTexture(ctx, texObj);
1730 ti->reloadImages = GL_TRUE;
1731 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1737 PrintTexture(int w, int h, int c, const GLubyte * data)
1740 for (i = 0; i < h; i++) {
1741 for (j = 0; j < w; j++) {
1743 printf("%02x %02x ", data[0], data[1]);
1745 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1755 tdfxTestProxyTexImage(struct gl_context *ctx, GLenum target,
1756 GLint level, GLint internalFormat,
1757 GLenum format, GLenum type,
1758 GLint width, GLint height,
1759 GLint depth, GLint border)
1761 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1762 struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
1763 struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
1766 case GL_PROXY_TEXTURE_1D:
1768 case GL_PROXY_TEXTURE_2D:
1770 struct gl_texture_object *tObj;
1774 tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
1775 if (!tObj->DriverData)
1776 tObj->DriverData = fxAllocTexObjData(fxMesa);
1777 ti = TDFX_TEXTURE_DATA(tObj);
1780 /* assign the parameters to test against */
1781 tObj->Image[0][level]->Width = width;
1782 tObj->Image[0][level]->Height = height;
1783 tObj->Image[0][level]->Border = border;
1785 tObj->Image[0][level]->InternalFormat = internalFormat;
1788 /* don't use mipmap levels > 0 */
1789 tObj->Sampler.MinFilter = tObj->Sampler.MagFilter = GL_NEAREST;
1792 /* test with all mipmap levels */
1793 tObj->Sampler.MinFilter = GL_LINEAR_MIPMAP_LINEAR;
1794 tObj->Sampler.MagFilter = GL_NEAREST;
1796 RevalidateTexture(ctx, tObj);
1799 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1800 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1801 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1802 printf("glide format 0x%x\n", ti->info.format);
1803 printf("data %p\n", ti->info.data);
1804 printf("lodblend %d\n", (int) ti->LODblend);
1807 /* determine where texture will reside */
1808 if (ti->LODblend && !shared->umaTexMemory) {
1809 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1810 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1811 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1814 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1815 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1816 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1819 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1821 if (memNeeded > shared->totalTexMem[0])
1826 case GL_PROXY_TEXTURE_3D:
1827 return GL_TRUE; /* software rendering */
1829 return GL_TRUE; /* never happens, silence compiler */
1835 * Allocate a new texture object.
1836 * Called via ctx->Driver.NewTextureObject.
1837 * Note: this function will be called during context creation to
1838 * allocate the default texture objects.
1839 * Note: we could use containment here to 'derive' the driver-specific
1840 * texture object from the core mesa gl_texture_object. Not done at this time.
1842 static struct gl_texture_object *
1843 tdfxNewTextureObject( struct gl_context *ctx, GLuint name, GLenum target )
1845 struct gl_texture_object *obj;
1846 obj = _mesa_new_texture_object(ctx, name, target);
1851 void tdfxInitTextureFuncs( struct dd_function_table *functions )
1853 functions->BindTexture = tdfxBindTexture;
1854 functions->NewTextureObject = tdfxNewTextureObject;
1855 functions->DeleteTexture = tdfxDeleteTexture;
1856 functions->TexEnv = tdfxTexEnv;
1857 functions->TexParameter = tdfxTexParameter;
1858 functions->ChooseTextureFormat = tdfxChooseTextureFormat;
1859 functions->TexImage1D = tdfxTexImage1D;
1860 functions->TexSubImage1D = tdfxTexSubImage1D;
1861 functions->TexImage2D = tdfxTexImage2D;
1862 functions->TexSubImage2D = tdfxTexSubImage2D;
1863 functions->IsTextureResident = tdfxIsTextureResident;
1864 functions->CompressedTexImage2D = tdfxCompressedTexImage2D;
1865 functions->CompressedTexSubImage2D = tdfxCompressedTexSubImage2D;
1866 functions->UpdateTexturePalette = tdfxUpdateTexturePalette;
1867 functions->GenerateMipmap = tdfxGenerateMipmap;