Move mipmap generation functions, texture scaling functions into new
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_tex.c
1 /* -*- mode: c; c-basic-offset: 3 -*-
2 *
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
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:
13 *
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
16 * Software.
17 *
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
24 * SOFTWARE.
25 */
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.7 2002/11/05 17:46:10 tsi Exp $ */
27
28 /*
29 * New fixes:
30 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
31 *
32 * Original rewrite:
33 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
34 *
35 * Authors:
36 * Gareth Hughes <gareth@valinux.com>
37 * Brian Paul <brianp@valinux.com>
38 *
39 */
40
41
42 #include "enums.h"
43 #include "image.h"
44 #include "mipmap.h"
45 #include "texcompress.h"
46 #include "texformat.h"
47 #include "teximage.h"
48 #include "texstore.h"
49 #include "texobj.h"
50 #include "tdfx_context.h"
51 #include "tdfx_tex.h"
52 #include "tdfx_texman.h"
53
54
55 /* no borders! can't halve 1x1! (stride > width * comp) not allowed */
56 static void
57 _mesa_halve2x2_teximage2d ( GLcontext *ctx,
58 struct gl_texture_image *texImage,
59 GLuint bytesPerPixel,
60 GLint srcWidth, GLint srcHeight,
61 const GLvoid *srcImage, GLvoid *dstImage )
62 {
63 GLint i, j, k;
64 GLint dstWidth = srcWidth / 2;
65 GLint dstHeight = srcHeight / 2;
66 GLint srcRowStride = srcWidth * bytesPerPixel;
67 GLubyte *src = (GLubyte *)srcImage;
68 GLubyte *dst = dstImage;
69 GLuint dstImageOffsets = 0;
70
71 GLuint bpt = 0;
72 GLubyte *_s = NULL;
73 GLubyte *_d = NULL;
74 GLenum _t = 0;
75
76 if (texImage->TexFormat->MesaFormat == MESA_FORMAT_RGB565) {
77 _t = GL_UNSIGNED_SHORT_5_6_5_REV;
78 bpt = bytesPerPixel;
79 } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) {
80 _t = GL_UNSIGNED_SHORT_4_4_4_4_REV;
81 bpt = bytesPerPixel;
82 } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) {
83 _t = GL_UNSIGNED_SHORT_1_5_5_5_REV;
84 bpt = bytesPerPixel;
85 }
86 if (bpt) {
87 bytesPerPixel = 4;
88 srcRowStride = srcWidth * bytesPerPixel;
89 if (dstWidth == 0) {
90 dstWidth = 1;
91 }
92 if (dstHeight == 0) {
93 dstHeight = 1;
94 }
95 _s = src = MALLOC(srcRowStride * srcHeight);
96 _d = dst = MALLOC(dstWidth * bytesPerPixel * dstHeight);
97 _mesa_texstore_rgba8888(ctx, 2, GL_RGBA,
98 &_mesa_texformat_rgba8888_rev, src,
99 0, 0, 0, /* dstX/Y/Zoffset */
100 srcRowStride, /* dstRowStride */
101 &dstImageOffsets,
102 srcWidth, srcHeight, 1,
103 texImage->_BaseFormat, _t, srcImage, &ctx->DefaultPacking);
104 }
105
106 if (srcHeight == 1) {
107 for (i = 0; i < dstWidth; i++) {
108 for (k = 0; k < bytesPerPixel; k++) {
109 dst[0] = (src[0] + src[bytesPerPixel] + 1) / 2;
110 src++;
111 dst++;
112 }
113 src += bytesPerPixel;
114 }
115 } else if (srcWidth == 1) {
116 for (j = 0; j < dstHeight; j++) {
117 for (k = 0; k < bytesPerPixel; k++) {
118 dst[0] = (src[0] + src[srcRowStride] + 1) / 2;
119 src++;
120 dst++;
121 }
122 src += srcRowStride;
123 }
124 } else {
125 for (j = 0; j < dstHeight; j++) {
126 for (i = 0; i < dstWidth; i++) {
127 for (k = 0; k < bytesPerPixel; k++) {
128 dst[0] = (src[0] +
129 src[bytesPerPixel] +
130 src[srcRowStride] +
131 src[srcRowStride + bytesPerPixel] + 2) / 4;
132 src++;
133 dst++;
134 }
135 src += bytesPerPixel;
136 }
137 src += srcRowStride;
138 }
139 }
140
141 if (bpt) {
142 src = _s;
143 dst = _d;
144 texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
145 texImage->TexFormat, dstImage,
146 0, 0, 0, /* dstX/Y/Zoffset */
147 dstWidth * bpt,
148 &dstImageOffsets,
149 dstWidth, dstHeight, 1,
150 GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking);
151 FREE(dst);
152 FREE(src);
153 }
154 }
155
156
157 static int
158 logbase2(int n)
159 {
160 GLint i = 1;
161 GLint log2 = 0;
162
163 if (n < 0) {
164 return -1;
165 }
166
167 while (n > i) {
168 i *= 2;
169 log2++;
170 }
171 if (i != n) {
172 return -1;
173 }
174 else {
175 return log2;
176 }
177 }
178
179
180 /*
181 * Compute various texture image parameters.
182 * Input: w, h - source texture width and height
183 * Output: lodlevel - Glide lod level token for the larger texture dimension
184 * aspectratio - Glide aspect ratio token
185 * sscale - S scale factor used during triangle setup
186 * tscale - T scale factor used during triangle setup
187 * wscale - OpenGL -> Glide image width scale factor
188 * hscale - OpenGL -> Glide image height scale factor
189 *
190 * Sample results:
191 * w h lodlevel aspectRatio
192 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
193 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
194 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
195 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
196 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
197 */
198 static void
199 tdfxTexGetInfo(const GLcontext *ctx, int w, int h,
200 GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,
201 float *sscale, float *tscale,
202 int *wscale, int *hscale)
203 {
204 int logw, logh, ar, lod, ws, hs;
205 float s, t;
206
207 ASSERT(w >= 1);
208 ASSERT(h >= 1);
209
210 logw = logbase2(w);
211 logh = logbase2(h);
212 ar = logw - logh; /* aspect ratio = difference in log dimensions */
213 s = t = 256.0;
214 ws = hs = 1;
215
216 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
217 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
218 if (ar >= 0) {
219 ASSERT(w >= h);
220 lod = logw;
221 if (ar <= GR_ASPECT_LOG2_8x1) {
222 t = 256 >> ar;
223 }
224 else {
225 /* have to stretch image height */
226 t = 32.0;
227 hs = 1 << (ar - 3);
228 ar = GR_ASPECT_LOG2_8x1;
229 }
230 }
231 else {
232 ASSERT(w < h);
233 lod = logh;
234 if (ar >= GR_ASPECT_LOG2_1x8) {
235 s = 256 >> -ar;
236 }
237 else {
238 /* have to stretch image width */
239 s = 32.0;
240 ws = 1 << (-ar - 3);
241 ar = GR_ASPECT_LOG2_1x8;
242 }
243 }
244
245 if (lodlevel)
246 *lodlevel = (GrLOD_t) lod;
247 if (aspectratio)
248 *aspectratio = (GrAspectRatio_t) ar;
249 if (sscale)
250 *sscale = s;
251 if (tscale)
252 *tscale = t;
253 if (wscale)
254 *wscale = ws;
255 if (hscale)
256 *hscale = hs;
257 }
258
259
260 /*
261 * We need to call this when a texture object's minification filter
262 * or texture image sizes change.
263 */
264 static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj)
265 {
266 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
267 GLint minl, maxl;
268
269 if (!ti)
270 return;
271
272 minl = maxl = tObj->BaseLevel;
273
274 if (tObj->Image[0][minl]) {
275 maxl = MIN2(tObj->MaxLevel, tObj->Image[0][minl]->MaxLog2);
276
277 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
278 tdfxTexGetInfo(ctx, tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,
279 &ti->info.largeLodLog2,
280 &ti->info.aspectRatioLog2,
281 &(ti->sScale), &(ti->tScale), NULL, NULL);
282 }
283
284 if (tObj->Image[0][maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
285 /* mipmapping: need to compute smallLodLog2 */
286 tdfxTexGetInfo(ctx, tObj->Image[0][maxl]->Width,
287 tObj->Image[0][maxl]->Height,
288 &ti->info.smallLodLog2, NULL,
289 NULL, NULL, NULL, NULL);
290 }
291 else {
292 /* not mipmapping: smallLodLog2 = largeLodLog2 */
293 ti->info.smallLodLog2 = ti->info.largeLodLog2;
294 maxl = minl;
295 }
296
297 ti->minLevel = minl;
298 ti->maxLevel = maxl;
299 ti->info.data = NULL;
300
301 /* this is necessary because of fxDDCompressedTexImage2D */
302 if (ti->padded) {
303 struct gl_texture_image *texImage = tObj->Image[0][minl];
304 tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
305 if (mml->wScale != 1 || mml->hScale != 1) {
306 ti->sScale /= mml->wScale;
307 ti->tScale /= mml->hScale;
308 }
309 }
310 }
311
312
313 static tdfxTexInfo *
314 fxAllocTexObjData(tdfxContextPtr fxMesa)
315 {
316 tdfxTexInfo *ti;
317
318 if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) {
319 _mesa_problem(NULL, "tdfx driver: out of memory");
320 return NULL;
321 }
322
323 ti->isInTM = GL_FALSE;
324
325 ti->whichTMU = TDFX_TMU_NONE;
326
327 ti->tm[TDFX_TMU0] = NULL;
328 ti->tm[TDFX_TMU1] = NULL;
329
330 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
331 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
332
333 ti->sClamp = GR_TEXTURECLAMP_WRAP;
334 ti->tClamp = GR_TEXTURECLAMP_WRAP;
335
336 ti->mmMode = GR_MIPMAP_NEAREST;
337 ti->LODblend = FXFALSE;
338
339 return ti;
340 }
341
342
343 /*
344 * Called via glBindTexture.
345 */
346 static void
347 tdfxBindTexture(GLcontext * ctx, GLenum target,
348 struct gl_texture_object *tObj)
349 {
350 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
351 tdfxTexInfo *ti;
352
353 if (MESA_VERBOSE & VERBOSE_DRIVER) {
354 fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,
355 tObj->DriverData);
356 }
357
358 if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D))
359 return;
360
361 if (!tObj->DriverData) {
362 tObj->DriverData = fxAllocTexObjData(fxMesa);
363 }
364
365 ti = TDFX_TEXTURE_DATA(tObj);
366 ti->lastTimeUsed = fxMesa->texBindNumber++;
367
368 fxMesa->new_state |= TDFX_NEW_TEXTURE;
369 }
370
371
372 /*
373 * Called via glTexEnv.
374 */
375 static void
376 tdfxTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
377 const GLfloat * param)
378 {
379 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
380
381 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
382 if (param)
383 fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,
384 (GLint) (*param));
385 else
386 fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
387 }
388
389 /* XXX this is a bit of a hack to force the Glide texture
390 * state to be updated.
391 */
392 fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit] = 0;
393
394 fxMesa->new_state |= TDFX_NEW_TEXTURE;
395 }
396
397
398 /*
399 * Called via glTexParameter.
400 */
401 static void
402 tdfxTexParameter(GLcontext * ctx, GLenum target,
403 struct gl_texture_object *tObj,
404 GLenum pname, const GLfloat * params)
405 {
406 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
407 GLenum param = (GLenum) (GLint) params[0];
408 tdfxTexInfo *ti;
409
410 if (MESA_VERBOSE & VERBOSE_DRIVER) {
411 fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,
412 tObj->DriverData, pname, param);
413 }
414
415 if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D))
416 return;
417
418 if (!tObj->DriverData)
419 tObj->DriverData = fxAllocTexObjData(fxMesa);
420
421 ti = TDFX_TEXTURE_DATA(tObj);
422
423 switch (pname) {
424 case GL_TEXTURE_MIN_FILTER:
425 switch (param) {
426 case GL_NEAREST:
427 ti->mmMode = GR_MIPMAP_DISABLE;
428 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
429 ti->LODblend = FXFALSE;
430 break;
431 case GL_LINEAR:
432 ti->mmMode = GR_MIPMAP_DISABLE;
433 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
434 ti->LODblend = FXFALSE;
435 break;
436 case GL_NEAREST_MIPMAP_LINEAR:
437 if (!fxMesa->Glide.HaveCombineExt) {
438 if (fxMesa->haveTwoTMUs) {
439 ti->mmMode = GR_MIPMAP_NEAREST;
440 ti->LODblend = FXTRUE;
441 }
442 else {
443 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
444 ti->LODblend = FXFALSE;
445 }
446 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
447 break;
448 }
449 /* XXX Voodoo3/Banshee mipmap blending seems to produce
450 * incorrectly filtered colors for the smallest mipmap levels.
451 * To work-around we fall-through here and use a different filter.
452 */
453 case GL_NEAREST_MIPMAP_NEAREST:
454 ti->mmMode = GR_MIPMAP_NEAREST;
455 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
456 ti->LODblend = FXFALSE;
457 break;
458 case GL_LINEAR_MIPMAP_LINEAR:
459 if (!fxMesa->Glide.HaveCombineExt) {
460 if (fxMesa->haveTwoTMUs) {
461 ti->mmMode = GR_MIPMAP_NEAREST;
462 ti->LODblend = FXTRUE;
463 }
464 else {
465 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
466 ti->LODblend = FXFALSE;
467 }
468 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
469 break;
470 }
471 /* XXX Voodoo3/Banshee mipmap blending seems to produce
472 * incorrectly filtered colors for the smallest mipmap levels.
473 * To work-around we fall-through here and use a different filter.
474 */
475 case GL_LINEAR_MIPMAP_NEAREST:
476 ti->mmMode = GR_MIPMAP_NEAREST;
477 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
478 ti->LODblend = FXFALSE;
479 break;
480 default:
481 break;
482 }
483 ti->reloadImages = GL_TRUE;
484 RevalidateTexture(ctx, tObj);
485 fxMesa->new_state |= TDFX_NEW_TEXTURE;
486 break;
487
488 case GL_TEXTURE_MAG_FILTER:
489 switch (param) {
490 case GL_NEAREST:
491 ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
492 break;
493 case GL_LINEAR:
494 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
495 break;
496 default:
497 break;
498 }
499 fxMesa->new_state |= TDFX_NEW_TEXTURE;
500 break;
501
502 case GL_TEXTURE_WRAP_S:
503 switch (param) {
504 case GL_CLAMP_TO_BORDER:
505 case GL_CLAMP_TO_EDGE:
506 case GL_CLAMP:
507 ti->sClamp = GR_TEXTURECLAMP_CLAMP;
508 break;
509 case GL_REPEAT:
510 ti->sClamp = GR_TEXTURECLAMP_WRAP;
511 break;
512 case GL_MIRRORED_REPEAT:
513 ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT;
514 break;
515 default:
516 break;
517 }
518 fxMesa->new_state |= TDFX_NEW_TEXTURE;
519 break;
520
521 case GL_TEXTURE_WRAP_T:
522 switch (param) {
523 case GL_CLAMP_TO_BORDER:
524 case GL_CLAMP_TO_EDGE:
525 case GL_CLAMP:
526 ti->tClamp = GR_TEXTURECLAMP_CLAMP;
527 break;
528 case GL_REPEAT:
529 ti->tClamp = GR_TEXTURECLAMP_WRAP;
530 break;
531 case GL_MIRRORED_REPEAT:
532 ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT;
533 break;
534 default:
535 break;
536 }
537 fxMesa->new_state |= TDFX_NEW_TEXTURE;
538 break;
539
540 case GL_TEXTURE_BORDER_COLOR:
541 /* TO DO */
542 break;
543 case GL_TEXTURE_MIN_LOD:
544 /* TO DO */
545 break;
546 case GL_TEXTURE_MAX_LOD:
547 /* TO DO */
548 break;
549 case GL_TEXTURE_BASE_LEVEL:
550 RevalidateTexture(ctx, tObj);
551 break;
552 case GL_TEXTURE_MAX_LEVEL:
553 RevalidateTexture(ctx, tObj);
554 break;
555
556 default:
557 break;
558 }
559 }
560
561
562 /*
563 * Called via glDeleteTextures to delete a texture object.
564 * Here, we delete the Glide data associated with the texture.
565 */
566 static void
567 tdfxDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj)
568 {
569 if (ctx && ctx->DriverCtx) {
570 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
571 tdfxTMFreeTexture(fxMesa, tObj);
572 fxMesa->new_state |= TDFX_NEW_TEXTURE;
573 /* Free mipmap images and the texture object itself */
574 _mesa_delete_texture_object(ctx, tObj);
575 }
576 }
577
578
579 /*
580 * Return true if texture is resident, false otherwise.
581 */
582 static GLboolean
583 tdfxIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj)
584 {
585 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
586 return (GLboolean) (ti && ti->isInTM);
587 }
588
589
590
591 /*
592 * Convert a gl_color_table texture palette to Glide's format.
593 */
594 static GrTexTable_t
595 convertPalette(FxU32 data[256], const struct gl_color_table *table)
596 {
597 const GLubyte *tableUB = (const GLubyte *) table->Table;
598 GLint width = table->Size;
599 FxU32 r, g, b, a;
600 GLint i;
601
602 ASSERT(table->Type == GL_UNSIGNED_BYTE);
603
604 switch (table->_BaseFormat) {
605 case GL_INTENSITY:
606 for (i = 0; i < width; i++) {
607 r = tableUB[i];
608 g = tableUB[i];
609 b = tableUB[i];
610 a = tableUB[i];
611 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
612 }
613 return GR_TEXTABLE_PALETTE_6666_EXT;
614 case GL_LUMINANCE:
615 for (i = 0; i < width; i++) {
616 r = tableUB[i];
617 g = tableUB[i];
618 b = tableUB[i];
619 a = 255;
620 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
621 }
622 return GR_TEXTABLE_PALETTE;
623 case GL_ALPHA:
624 for (i = 0; i < width; i++) {
625 r = g = b = 255;
626 a = tableUB[i];
627 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
628 }
629 return GR_TEXTABLE_PALETTE_6666_EXT;
630 case GL_LUMINANCE_ALPHA:
631 for (i = 0; i < width; i++) {
632 r = g = b = tableUB[i * 2 + 0];
633 a = tableUB[i * 2 + 1];
634 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
635 }
636 return GR_TEXTABLE_PALETTE_6666_EXT;
637 case GL_RGB:
638 for (i = 0; i < width; i++) {
639 r = tableUB[i * 3 + 0];
640 g = tableUB[i * 3 + 1];
641 b = tableUB[i * 3 + 2];
642 a = 255;
643 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
644 }
645 return GR_TEXTABLE_PALETTE;
646 case GL_RGBA:
647 for (i = 0; i < width; i++) {
648 r = tableUB[i * 4 + 0];
649 g = tableUB[i * 4 + 1];
650 b = tableUB[i * 4 + 2];
651 a = tableUB[i * 4 + 3];
652 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
653 }
654 return GR_TEXTABLE_PALETTE_6666_EXT;
655 default:
656 /* XXX fixme: how can this happen? */
657 _mesa_error(NULL, GL_INVALID_ENUM, "convertPalette: table->Format == %s",
658 _mesa_lookup_enum_by_nr(table->Format));
659 return GR_TEXTABLE_PALETTE;
660 }
661 }
662
663
664
665 static void
666 tdfxUpdateTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj)
667 {
668 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
669
670 if (tObj) {
671 /* per-texture palette */
672 tdfxTexInfo *ti;
673
674 /* This might be a proxy texture. */
675 if (!tObj->Palette.Table)
676 return;
677
678 if (!tObj->DriverData)
679 tObj->DriverData = fxAllocTexObjData(fxMesa);
680 ti = TDFX_TEXTURE_DATA(tObj);
681 assert(ti);
682 ti->paltype = convertPalette(ti->palette.data, &tObj->Palette);
683 /*tdfxTexInvalidate(ctx, tObj);*/
684 }
685 else {
686 /* global texture palette */
687 fxMesa->TexPalette.Type = convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
688 fxMesa->TexPalette.Data = &(fxMesa->glbPalette.data);
689 fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
690 }
691 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */
692 }
693
694
695 /**********************************************************************/
696 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
697 /**********************************************************************/
698
699 #if 000
700 static FxBool TexusFatalError = FXFALSE;
701 static FxBool TexusError = FXFALSE;
702
703 #define TX_DITHER_NONE 0x00000000
704
705 static void
706 fxTexusError(const char *string, FxBool fatal)
707 {
708 _mesa_problem(NULL, string);
709 /*
710 * Just propagate the fatal value up.
711 */
712 TexusError = FXTRUE;
713 TexusFatalError = fatal;
714 }
715 #endif
716
717
718 static const struct gl_texture_format *
719 tdfxChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
720 GLenum srcFormat, GLenum srcType )
721 {
722 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
723 const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
724
725 switch (internalFormat) {
726 case GL_ALPHA:
727 case GL_ALPHA4:
728 case GL_ALPHA8:
729 case GL_ALPHA12:
730 case GL_ALPHA16:
731 case GL_COMPRESSED_ALPHA:
732 return &_mesa_texformat_a8;
733 case 1:
734 case GL_LUMINANCE:
735 case GL_LUMINANCE4:
736 case GL_LUMINANCE8:
737 case GL_LUMINANCE12:
738 case GL_LUMINANCE16:
739 case GL_COMPRESSED_LUMINANCE:
740 return &_mesa_texformat_l8;
741 case 2:
742 case GL_LUMINANCE_ALPHA:
743 case GL_LUMINANCE4_ALPHA4:
744 case GL_LUMINANCE6_ALPHA2:
745 case GL_LUMINANCE8_ALPHA8:
746 case GL_LUMINANCE12_ALPHA4:
747 case GL_LUMINANCE12_ALPHA12:
748 case GL_LUMINANCE16_ALPHA16:
749 case GL_COMPRESSED_LUMINANCE_ALPHA:
750 return &_mesa_texformat_al88;
751 case GL_INTENSITY:
752 case GL_INTENSITY4:
753 case GL_INTENSITY8:
754 case GL_INTENSITY12:
755 case GL_INTENSITY16:
756 case GL_COMPRESSED_INTENSITY:
757 return &_mesa_texformat_i8;
758 case GL_R3_G3_B2:
759 case GL_RGB4:
760 case GL_RGB5:
761 return &_mesa_texformat_rgb565;
762 case GL_COMPRESSED_RGB:
763 /* intentional fall-through */
764 case 3:
765 case GL_RGB:
766 if ( srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5 ) {
767 return &_mesa_texformat_rgb565;
768 }
769 /* intentional fall through */
770 case GL_RGB8:
771 case GL_RGB10:
772 case GL_RGB12:
773 case GL_RGB16:
774 return (allow32bpt) ? &_mesa_texformat_argb8888
775 : &_mesa_texformat_rgb565;
776 case GL_RGBA2:
777 case GL_RGBA4:
778 return &_mesa_texformat_argb4444;
779 case GL_COMPRESSED_RGBA:
780 /* intentional fall-through */
781 case 4:
782 case GL_RGBA:
783 if ( srcFormat == GL_BGRA ) {
784 if ( srcType == GL_UNSIGNED_INT_8_8_8_8_REV ) {
785 return &_mesa_texformat_argb8888;
786 }
787 else if ( srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
788 return &_mesa_texformat_argb4444;
789 }
790 else if ( srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
791 return &_mesa_texformat_argb1555;
792 }
793 }
794 /* intentional fall through */
795 case GL_RGBA8:
796 case GL_RGB10_A2:
797 case GL_RGBA12:
798 case GL_RGBA16:
799 return allow32bpt ? &_mesa_texformat_argb8888
800 : &_mesa_texformat_argb4444;
801 case GL_RGB5_A1:
802 return &_mesa_texformat_argb1555;
803 case GL_COLOR_INDEX:
804 case GL_COLOR_INDEX1_EXT:
805 case GL_COLOR_INDEX2_EXT:
806 case GL_COLOR_INDEX4_EXT:
807 case GL_COLOR_INDEX8_EXT:
808 case GL_COLOR_INDEX12_EXT:
809 case GL_COLOR_INDEX16_EXT:
810 return &_mesa_texformat_ci8;
811 /* GL_EXT_texture_compression_s3tc */
812 /* GL_S3_s3tc */
813 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
814 case GL_RGB_S3TC:
815 case GL_RGB4_S3TC:
816 return &_mesa_texformat_rgb_dxt1;
817 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
818 return &_mesa_texformat_rgba_dxt1;
819 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
820 case GL_RGBA_S3TC:
821 case GL_RGBA4_S3TC:
822 return &_mesa_texformat_rgba_dxt3;
823 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
824 return &_mesa_texformat_rgba_dxt5;
825 /* GL_3DFX_texture_compression_FXT1 */
826 case GL_COMPRESSED_RGB_FXT1_3DFX:
827 return &_mesa_texformat_rgb_fxt1;
828 case GL_COMPRESSED_RGBA_FXT1_3DFX:
829 return &_mesa_texformat_rgba_fxt1;
830 default:
831 _mesa_problem(ctx, "unexpected format in tdfxChooseTextureFormat");
832 return NULL;
833 }
834 }
835
836
837 /*
838 * Return the Glide format for the given mesa texture format.
839 */
840 static GrTextureFormat_t
841 fxGlideFormat(GLint mesaFormat)
842 {
843 switch (mesaFormat) {
844 case MESA_FORMAT_I8:
845 return GR_TEXFMT_ALPHA_8;
846 case MESA_FORMAT_A8:
847 return GR_TEXFMT_ALPHA_8;
848 case MESA_FORMAT_L8:
849 return GR_TEXFMT_INTENSITY_8;
850 case MESA_FORMAT_CI8:
851 return GR_TEXFMT_P_8;
852 case MESA_FORMAT_AL88:
853 return GR_TEXFMT_ALPHA_INTENSITY_88;
854 case MESA_FORMAT_RGB565:
855 return GR_TEXFMT_RGB_565;
856 case MESA_FORMAT_ARGB4444:
857 return GR_TEXFMT_ARGB_4444;
858 case MESA_FORMAT_ARGB1555:
859 return GR_TEXFMT_ARGB_1555;
860 case MESA_FORMAT_ARGB8888:
861 return GR_TEXFMT_ARGB_8888;
862 case MESA_FORMAT_RGB_FXT1:
863 case MESA_FORMAT_RGBA_FXT1:
864 return GR_TEXFMT_ARGB_CMP_FXT1;
865 case MESA_FORMAT_RGB_DXT1:
866 case MESA_FORMAT_RGBA_DXT1:
867 return GR_TEXFMT_ARGB_CMP_DXT1;
868 case MESA_FORMAT_RGBA_DXT3:
869 return GR_TEXFMT_ARGB_CMP_DXT3;
870 case MESA_FORMAT_RGBA_DXT5:
871 return GR_TEXFMT_ARGB_CMP_DXT5;
872 default:
873 _mesa_problem(NULL, "Unexpected format in fxGlideFormat");
874 return 0;
875 }
876 }
877
878
879 /* Texel-fetch functions for software texturing and glGetTexImage().
880 * We should have been able to use some "standard" fetch functions (which
881 * may get defined in texutil.c) but we have to account for scaled texture
882 * images on tdfx hardware (the 8:1 aspect ratio limit).
883 * Hence, we need special functions here.
884 */
885 extern void
886 fxt1_decode_1 (const void *texture, int width,
887 int i, int j, unsigned char *rgba);
888
889 static void
890 fetch_intensity8(const struct gl_texture_image *texImage,
891 GLint i, GLint j, GLint k, GLchan * rgba)
892 {
893 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
894 const GLubyte *texel;
895
896 i = i * mml->wScale;
897 j = j * mml->hScale;
898
899 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
900 rgba[RCOMP] = *texel;
901 rgba[GCOMP] = *texel;
902 rgba[BCOMP] = *texel;
903 rgba[ACOMP] = *texel;
904 }
905
906
907 static void
908 fetch_luminance8(const struct gl_texture_image *texImage,
909 GLint i, GLint j, GLint k, GLchan * rgba)
910 {
911 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
912 const GLubyte *texel;
913
914 i = i * mml->wScale;
915 j = j * mml->hScale;
916
917 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
918 rgba[RCOMP] = *texel;
919 rgba[GCOMP] = *texel;
920 rgba[BCOMP] = *texel;
921 rgba[ACOMP] = 255;
922 }
923
924
925 static void
926 fetch_alpha8(const struct gl_texture_image *texImage,
927 GLint i, GLint j, GLint k, GLchan * rgba)
928 {
929 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
930 const GLubyte *texel;
931
932 i = i * mml->wScale;
933 j = j * mml->hScale;
934
935 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
936 rgba[RCOMP] = 255;
937 rgba[GCOMP] = 255;
938 rgba[BCOMP] = 255;
939 rgba[ACOMP] = *texel;
940 }
941
942
943 static void
944 fetch_index8(const struct gl_texture_image *texImage,
945 GLint i, GLint j, GLint k, GLchan * indexOut)
946 {
947 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
948 const GLubyte *texel;
949
950 i = i * mml->wScale;
951 j = j * mml->hScale;
952
953 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
954 *indexOut = *texel;
955 }
956
957
958 static void
959 fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
960 GLint i, GLint j, GLint k, GLchan * rgba)
961 {
962 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
963 const GLubyte *texel;
964
965 i = i * mml->wScale;
966 j = j * mml->hScale;
967
968 texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2;
969 rgba[RCOMP] = texel[0];
970 rgba[GCOMP] = texel[0];
971 rgba[BCOMP] = texel[0];
972 rgba[ACOMP] = texel[1];
973 }
974
975
976 static void
977 fetch_r5g6b5(const struct gl_texture_image *texImage,
978 GLint i, GLint j, GLint k, GLchan * rgba)
979 {
980 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
981 const GLushort *texel;
982
983 i = i * mml->wScale;
984 j = j * mml->hScale;
985
986 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
987 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
988 rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63;
989 rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31;
990 rgba[ACOMP] = 255;
991 }
992
993
994 static void
995 fetch_r4g4b4a4(const struct gl_texture_image *texImage,
996 GLint i, GLint j, GLint k, GLchan * rgba)
997 {
998 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
999 const GLushort *texel;
1000
1001 i = i * mml->wScale;
1002 j = j * mml->hScale;
1003
1004 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
1005 rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15;
1006 rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15;
1007 rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15;
1008 rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;
1009 }
1010
1011
1012 static void
1013 fetch_r5g5b5a1(const struct gl_texture_image *texImage,
1014 GLint i, GLint j, GLint k, GLchan * rgba)
1015 {
1016 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1017 const GLushort *texel;
1018
1019 i = i * mml->wScale;
1020 j = j * mml->hScale;
1021
1022 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
1023 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
1024 rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31;
1025 rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31;
1026 rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;
1027 }
1028
1029
1030 static void
1031 fetch_a8r8g8b8(const struct gl_texture_image *texImage,
1032 GLint i, GLint j, GLint k, GLchan * rgba)
1033 {
1034 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1035 const GLuint *texel;
1036
1037 i = i * mml->wScale;
1038 j = j * mml->hScale;
1039
1040 texel = ((GLuint *) texImage->Data) + j * mml->width + i;
1041 rgba[RCOMP] = (((*texel) >> 16) & 0xff);
1042 rgba[GCOMP] = (((*texel) >> 8) & 0xff);
1043 rgba[BCOMP] = (((*texel) ) & 0xff);
1044 rgba[ACOMP] = (((*texel) >> 24) & 0xff);
1045 }
1046
1047
1048 static void
1049 fetch_rgb_fxt1(const struct gl_texture_image *texImage,
1050 GLint i, GLint j, GLint k, GLchan *rgba)
1051 {
1052 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1053
1054 i = i * mml->wScale;
1055 j = j * mml->hScale;
1056
1057 fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);
1058 rgba[ACOMP] = 255;
1059 }
1060
1061
1062 static void
1063 fetch_rgba_fxt1(const struct gl_texture_image *texImage,
1064 GLint i, GLint j, GLint k, GLchan *rgba)
1065 {
1066 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1067
1068 i = i * mml->wScale;
1069 j = j * mml->hScale;
1070
1071 fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);
1072 }
1073
1074
1075 static void
1076 fetch_rgb_dxt1(const struct gl_texture_image *texImage,
1077 GLint i, GLint j, GLint k, GLchan *rgba)
1078 {
1079 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1080
1081 i = i * mml->wScale;
1082 j = j * mml->hScale;
1083
1084 _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
1085 }
1086
1087
1088 static void
1089 fetch_rgba_dxt1(const struct gl_texture_image *texImage,
1090 GLint i, GLint j, GLint k, GLchan *rgba)
1091 {
1092 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1093
1094 i = i * mml->wScale;
1095 j = j * mml->hScale;
1096
1097 _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
1098 }
1099
1100
1101 static void
1102 fetch_rgba_dxt3(const struct gl_texture_image *texImage,
1103 GLint i, GLint j, GLint k, GLchan *rgba)
1104 {
1105 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1106
1107 i = i * mml->wScale;
1108 j = j * mml->hScale;
1109
1110 _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba);
1111 }
1112
1113
1114 static void
1115 fetch_rgba_dxt5(const struct gl_texture_image *texImage,
1116 GLint i, GLint j, GLint k, GLchan *rgba)
1117 {
1118 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
1119
1120 i = i * mml->wScale;
1121 j = j * mml->hScale;
1122
1123 _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba);
1124 }
1125
1126
1127 static FetchTexelFuncC
1128 fxFetchFunction(GLint mesaFormat)
1129 {
1130 switch (mesaFormat) {
1131 case MESA_FORMAT_I8:
1132 return &fetch_intensity8;
1133 case MESA_FORMAT_A8:
1134 return &fetch_alpha8;
1135 case MESA_FORMAT_L8:
1136 return &fetch_luminance8;
1137 case MESA_FORMAT_CI8:
1138 return &fetch_index8;
1139 case MESA_FORMAT_AL88:
1140 return &fetch_luminance8_alpha8;
1141 case MESA_FORMAT_RGB565:
1142 return &fetch_r5g6b5;
1143 case MESA_FORMAT_ARGB4444:
1144 return &fetch_r4g4b4a4;
1145 case MESA_FORMAT_ARGB1555:
1146 return &fetch_r5g5b5a1;
1147 case MESA_FORMAT_ARGB8888:
1148 return &fetch_a8r8g8b8;
1149 case MESA_FORMAT_RGB_FXT1:
1150 return &fetch_rgb_fxt1;
1151 case MESA_FORMAT_RGBA_FXT1:
1152 return &fetch_rgba_fxt1;
1153 case MESA_FORMAT_RGB_DXT1:
1154 return &fetch_rgb_dxt1;
1155 case MESA_FORMAT_RGBA_DXT1:
1156 return &fetch_rgba_dxt1;
1157 case MESA_FORMAT_RGBA_DXT3:
1158 return &fetch_rgba_dxt3;
1159 case MESA_FORMAT_RGBA_DXT5:
1160 return &fetch_rgba_dxt5;
1161 default:
1162 _mesa_problem(NULL, "Unexpected format in fxFetchFunction");
1163 return NULL;
1164 }
1165 }
1166
1167
1168 static GLboolean
1169 adjust2DRatio (GLcontext *ctx,
1170 GLint xoffset, GLint yoffset,
1171 GLint width, GLint height,
1172 GLenum format, GLenum type, const GLvoid *pixels,
1173 const struct gl_pixelstore_attrib *packing,
1174 tdfxMipMapLevel *mml,
1175 struct gl_texture_image *texImage,
1176 GLint texelBytes,
1177 GLint dstRowStride)
1178 {
1179 const GLint newWidth = width * mml->wScale;
1180 const GLint newHeight = height * mml->hScale;
1181 GLvoid *tempImage;
1182 GLuint dstImageOffsets = 0;
1183
1184 if (!texImage->IsCompressed) {
1185 GLubyte *destAddr;
1186 tempImage = MALLOC(width * height * texelBytes);
1187 if (!tempImage) {
1188 return GL_FALSE;
1189 }
1190
1191 texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
1192 texImage->TexFormat, tempImage,
1193 0, 0, 0, /* dstX/Y/Zoffset */
1194 width * texelBytes, /* dstRowStride */
1195 &dstImageOffsets,
1196 width, height, 1,
1197 format, type, pixels, packing);
1198
1199 /* now rescale */
1200 /* compute address of dest subimage within the overal tex image */
1201 destAddr = (GLubyte *) texImage->Data
1202 + (yoffset * mml->hScale * mml->width
1203 + xoffset * mml->wScale) * texelBytes;
1204
1205 _mesa_rescale_teximage2d(texelBytes,
1206 width,
1207 dstRowStride, /* dst stride */
1208 width, height,
1209 newWidth, newHeight,
1210 tempImage, destAddr);
1211 } else {
1212 const GLint rawBytes = 4;
1213 GLvoid *rawImage = MALLOC(width * height * rawBytes);
1214 if (!rawImage) {
1215 return GL_FALSE;
1216 }
1217 tempImage = MALLOC(newWidth * newHeight * rawBytes);
1218 if (!tempImage) {
1219 FREE(rawImage);
1220 return GL_FALSE;
1221 }
1222 /* unpack image, apply transfer ops and store in rawImage */
1223 _mesa_texstore_rgba8888(ctx, 2, GL_RGBA,
1224 &_mesa_texformat_rgba8888_rev, rawImage,
1225 0, 0, 0, /* dstX/Y/Zoffset */
1226 width * rawBytes, /* dstRowStride */
1227 &dstImageOffsets,
1228 width, height, 1,
1229 format, type, pixels, packing);
1230 _mesa_rescale_teximage2d(rawBytes,
1231 width,
1232 newWidth * rawBytes, /* dst stride */
1233 width, height, /* src */
1234 newWidth, newHeight, /* dst */
1235 rawImage /*src*/, tempImage /*dst*/ );
1236 texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
1237 texImage->TexFormat, texImage->Data,
1238 xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */
1239 dstRowStride,
1240 &dstImageOffsets,
1241 newWidth, newHeight, 1,
1242 GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking);
1243 FREE(rawImage);
1244 }
1245
1246 FREE(tempImage);
1247
1248 return GL_TRUE;
1249 }
1250
1251
1252 static void
1253 tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
1254 GLint internalFormat, GLint width, GLint height, GLint border,
1255 GLenum format, GLenum type, const GLvoid *pixels,
1256 const struct gl_pixelstore_attrib *packing,
1257 struct gl_texture_object *texObj,
1258 struct gl_texture_image *texImage)
1259 {
1260 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1261 tdfxTexInfo *ti;
1262 tdfxMipMapLevel *mml;
1263 GLint texelBytes, dstRowStride;
1264 GLuint mesaFormat;
1265
1266 /*
1267 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
1268 texObj->Name, texImage->InternalFormat, format, type,
1269 texImage->Width, texImage->Height);
1270 */
1271
1272 ti = TDFX_TEXTURE_DATA(texObj);
1273 if (!ti) {
1274 texObj->DriverData = fxAllocTexObjData(fxMesa);
1275 if (!texObj->DriverData) {
1276 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1277 return;
1278 }
1279 ti = TDFX_TEXTURE_DATA(texObj);
1280 }
1281 assert(ti);
1282
1283 mml = TDFX_TEXIMAGE_DATA(texImage);
1284 if (!mml) {
1285 texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
1286 if (!texImage->DriverData) {
1287 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1288 return;
1289 }
1290 mml = TDFX_TEXIMAGE_DATA(texImage);
1291 }
1292
1293 /* Determine width and height scale factors for texture.
1294 * Remember, Glide is limited to 8:1 aspect ratios.
1295 */
1296 tdfxTexGetInfo(ctx,
1297 texImage->Width, texImage->Height,
1298 NULL, /* lod level */
1299 NULL, /* aspect ratio */
1300 NULL, NULL, /* sscale, tscale */
1301 &mml->wScale, &mml->hScale);
1302
1303 /* rescaled size: */
1304 mml->width = width * mml->wScale;
1305 mml->height = height * mml->hScale;
1306
1307 #if FX_COMPRESS_S3TC_AS_FXT1_HACK
1308 /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
1309 /* [dBorca] we should update texture's attribute, then,
1310 * because if the application asks us to decompress, we
1311 * have to know the REAL format! Also, DXT3/5 might not
1312 * be correct, since it would mess with "compressedSize".
1313 * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
1314 */
1315 if (texImage->IsCompressed) {
1316 switch (internalFormat) {
1317 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1318 case GL_RGB_S3TC:
1319 case GL_RGB4_S3TC:
1320 internalFormat = GL_COMPRESSED_RGB_FXT1_3DFX;
1321 break;
1322 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1323 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1324 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1325 case GL_RGBA_S3TC:
1326 case GL_RGBA4_S3TC:
1327 internalFormat = GL_COMPRESSED_RGBA_FXT1_3DFX;
1328 }
1329 texImage->InternalFormat = internalFormat;
1330 }
1331 #endif
1332 #if FX_TC_NAPALM
1333 if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
1334 GLenum texNapalm = 0;
1335 if (internalFormat == GL_COMPRESSED_RGB) {
1336 texNapalm = GL_COMPRESSED_RGB_FXT1_3DFX;
1337 } else if (internalFormat == GL_COMPRESSED_RGBA) {
1338 texNapalm = GL_COMPRESSED_RGBA_FXT1_3DFX;
1339 }
1340 if (texNapalm) {
1341 texImage->InternalFormat = internalFormat = texNapalm;
1342 texImage->IsCompressed = GL_TRUE;
1343 }
1344 }
1345 #endif
1346
1347 /* choose the texture format */
1348 assert(ctx->Driver.ChooseTextureFormat);
1349 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
1350 internalFormat, format, type);
1351 assert(texImage->TexFormat);
1352 mesaFormat = texImage->TexFormat->MesaFormat;
1353 mml->glideFormat = fxGlideFormat(mesaFormat);
1354 ti->info.format = mml->glideFormat;
1355 texImage->FetchTexelc = fxFetchFunction(mesaFormat);
1356 texelBytes = texImage->TexFormat->TexelBytes;
1357
1358 if (texImage->IsCompressed) {
1359 texImage->CompressedSize = _mesa_compressed_texture_size(ctx,
1360 mml->width,
1361 mml->height,
1362 1,
1363 mesaFormat);
1364 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width);
1365 texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize);
1366 } else {
1367 dstRowStride = mml->width * texelBytes;
1368 texImage->Data = _mesa_alloc_texmemory(mml->width * mml->height * texelBytes);
1369 }
1370 if (!texImage->Data) {
1371 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1372 return;
1373 }
1374
1375 if (pixels != NULL) {
1376 if (mml->wScale != 1 || mml->hScale != 1) {
1377 /* rescale image to overcome 1:8 aspect limitation */
1378 if (!adjust2DRatio(ctx,
1379 0, 0,
1380 width, height,
1381 format, type, pixels,
1382 packing,
1383 mml,
1384 texImage,
1385 texelBytes,
1386 dstRowStride)
1387 ) {
1388 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1389 return;
1390 }
1391 }
1392 else {
1393 /* no rescaling needed */
1394 /* unpack image, apply transfer ops and store in texImage->Data */
1395 texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
1396 texImage->TexFormat, texImage->Data,
1397 0, 0, 0, /* dstX/Y/Zoffset */
1398 dstRowStride,
1399 texImage->ImageOffsets,
1400 width, height, 1,
1401 format, type, pixels, packing);
1402 }
1403
1404 /* GL_SGIS_generate_mipmap */
1405 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1406 GLint mipWidth, mipHeight;
1407 tdfxMipMapLevel *mip;
1408 struct gl_texture_image *mipImage;
1409 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1410 const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
1411
1412 assert(!texImage->IsCompressed);
1413
1414 while (level < texObj->MaxLevel && level < maxLevels - 1) {
1415 mipWidth = width / 2;
1416 if (!mipWidth) {
1417 mipWidth = 1;
1418 }
1419 mipHeight = height / 2;
1420 if (!mipHeight) {
1421 mipHeight = 1;
1422 }
1423 if ((mipWidth == width) && (mipHeight == height)) {
1424 break;
1425 }
1426 _mesa_TexImage2D(target, ++level, internalFormat,
1427 mipWidth, mipHeight, border,
1428 format, type,
1429 NULL);
1430 mipImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1431 mip = TDFX_TEXIMAGE_DATA(mipImage);
1432 _mesa_halve2x2_teximage2d(ctx,
1433 texImage,
1434 texelBytes,
1435 mml->width, mml->height,
1436 texImage->Data, mipImage->Data);
1437 texImage = mipImage;
1438 mml = mip;
1439 width = mipWidth;
1440 height = mipHeight;
1441 }
1442 }
1443 }
1444
1445 RevalidateTexture(ctx, texObj);
1446
1447 ti->reloadImages = GL_TRUE;
1448 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1449 }
1450
1451
1452 static void
1453 tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
1454 GLint xoffset, GLint yoffset,
1455 GLsizei width, GLsizei height,
1456 GLenum format, GLenum type,
1457 const GLvoid *pixels,
1458 const struct gl_pixelstore_attrib *packing,
1459 struct gl_texture_object *texObj,
1460 struct gl_texture_image *texImage )
1461 {
1462 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1463 tdfxTexInfo *ti;
1464 tdfxMipMapLevel *mml;
1465 GLint texelBytes, dstRowStride;
1466
1467 if (!texObj->DriverData) {
1468 _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
1469 return;
1470 }
1471
1472 ti = TDFX_TEXTURE_DATA(texObj);
1473 assert(ti);
1474 mml = TDFX_TEXIMAGE_DATA(texImage);
1475 assert(mml);
1476
1477 assert(texImage->Data); /* must have an existing texture image! */
1478 assert(texImage->_BaseFormat);
1479
1480 texelBytes = texImage->TexFormat->TexelBytes;
1481 if (texImage->IsCompressed) {
1482 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width);
1483 } else {
1484 dstRowStride = mml->width * texelBytes;
1485 }
1486
1487 if (mml->wScale != 1 || mml->hScale != 1) {
1488 /* need to rescale subimage to match mipmap level's rescale factors */
1489 if (!adjust2DRatio(ctx,
1490 xoffset, yoffset,
1491 width, height,
1492 format, type, pixels,
1493 packing,
1494 mml,
1495 texImage,
1496 texelBytes,
1497 dstRowStride)
1498 ) {
1499 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1500 return;
1501 }
1502 }
1503 else {
1504 /* no rescaling needed */
1505 texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
1506 texImage->TexFormat, texImage->Data,
1507 xoffset, yoffset, 0,
1508 dstRowStride,
1509 texImage->ImageOffsets,
1510 width, height, 1,
1511 format, type, pixels, packing);
1512 }
1513
1514 /* GL_SGIS_generate_mipmap */
1515 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1516 GLint mipWidth, mipHeight;
1517 tdfxMipMapLevel *mip;
1518 struct gl_texture_image *mipImage;
1519 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1520 const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
1521
1522 assert(!texImage->IsCompressed);
1523
1524 width = texImage->Width;
1525 height = texImage->Height;
1526 while (level < texObj->MaxLevel && level < maxLevels - 1) {
1527 mipWidth = width / 2;
1528 if (!mipWidth) {
1529 mipWidth = 1;
1530 }
1531 mipHeight = height / 2;
1532 if (!mipHeight) {
1533 mipHeight = 1;
1534 }
1535 if ((mipWidth == width) && (mipHeight == height)) {
1536 break;
1537 }
1538 ++level;
1539 mipImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1540 mip = TDFX_TEXIMAGE_DATA(mipImage);
1541 _mesa_halve2x2_teximage2d(ctx,
1542 texImage,
1543 texelBytes,
1544 mml->width, mml->height,
1545 texImage->Data, mipImage->Data);
1546 texImage = mipImage;
1547 mml = mip;
1548 width = mipWidth;
1549 height = mipHeight;
1550 }
1551 }
1552
1553 ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
1554 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
1555 }
1556
1557
1558 static void
1559 tdfxTexImage1D(GLcontext *ctx, GLenum target, GLint level,
1560 GLint internalFormat, GLint width, GLint border,
1561 GLenum format, GLenum type, const GLvoid *pixels,
1562 const struct gl_pixelstore_attrib *packing,
1563 struct gl_texture_object *texObj,
1564 struct gl_texture_image *texImage)
1565 {
1566 tdfxTexImage2D(ctx, target, level,
1567 internalFormat, width, 1, border,
1568 format, type, pixels,
1569 packing,
1570 texObj,
1571 texImage);
1572 }
1573
1574 static void
1575 tdfxTexSubImage1D(GLcontext *ctx, GLenum target, GLint level,
1576 GLint xoffset,
1577 GLsizei width,
1578 GLenum format, GLenum type,
1579 const GLvoid *pixels,
1580 const struct gl_pixelstore_attrib *packing,
1581 struct gl_texture_object *texObj,
1582 struct gl_texture_image *texImage )
1583 {
1584 tdfxTexSubImage2D(ctx, target, level,
1585 xoffset, 0,
1586 width, 1,
1587 format, type,
1588 pixels,
1589 packing,
1590 texObj,
1591 texImage);
1592 }
1593
1594 /**********************************************************************/
1595 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1596 /**********************************************************************/
1597
1598 static void
1599 tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
1600 GLint level, GLint internalFormat,
1601 GLsizei width, GLsizei height, GLint border,
1602 GLsizei imageSize, const GLvoid *data,
1603 struct gl_texture_object *texObj,
1604 struct gl_texture_image *texImage)
1605 {
1606 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1607 tdfxTexInfo *ti;
1608 tdfxMipMapLevel *mml;
1609 GLuint mesaFormat;
1610
1611 if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
1612 fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n",
1613 texObj->Name, internalFormat,
1614 width, height);
1615 }
1616
1617 if ((target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) || texImage->Border > 0) {
1618 _mesa_problem(NULL, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
1619 return;
1620 }
1621
1622 assert(texImage->IsCompressed);
1623
1624 ti = TDFX_TEXTURE_DATA(texObj);
1625 if (!ti) {
1626 texObj->DriverData = fxAllocTexObjData(fxMesa);
1627 if (!texObj->DriverData) {
1628 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
1629 return;
1630 }
1631 ti = TDFX_TEXTURE_DATA(texObj);
1632 }
1633 assert(ti);
1634
1635 mml = TDFX_TEXIMAGE_DATA(texImage);
1636 if (!mml) {
1637 texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
1638 if (!texImage->DriverData) {
1639 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
1640 return;
1641 }
1642 mml = TDFX_TEXIMAGE_DATA(texImage);
1643 }
1644
1645 tdfxTexGetInfo(ctx, width, height, NULL, NULL, NULL, NULL,
1646 &mml->wScale, &mml->hScale);
1647
1648 mml->width = width * mml->wScale;
1649 mml->height = height * mml->hScale;
1650
1651
1652 /* choose the texture format */
1653 assert(ctx->Driver.ChooseTextureFormat);
1654 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
1655 internalFormat, -1/*format*/, -1/*type*/);
1656 assert(texImage->TexFormat);
1657
1658 /* Determine the appropriate Glide texel format,
1659 * given the user's internal texture format hint.
1660 */
1661 mesaFormat = texImage->TexFormat->MesaFormat;
1662 mml->glideFormat = fxGlideFormat(mesaFormat);
1663 ti->info.format = mml->glideFormat;
1664 texImage->FetchTexelc = fxFetchFunction(mesaFormat);
1665
1666 /* allocate new storage for texture image, if needed */
1667 if (!texImage->Data) {
1668 texImage->CompressedSize = _mesa_compressed_texture_size(ctx,
1669 mml->width,
1670 mml->height,
1671 1,
1672 mesaFormat);
1673 texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize);
1674 if (!texImage->Data) {
1675 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
1676 return;
1677 }
1678 }
1679
1680 /* save the texture data */
1681 if (mml->wScale != 1 || mml->hScale != 1) {
1682 /* [dBorca] Hack alert:
1683 * now we're screwed. We can't decompress,
1684 * unless we do it in HW (via textureBuffer).
1685 * We still have some chances:
1686 * 1) we got FXT1 textures - we CAN decompress, rescale for
1687 * aspectratio, then compress back.
1688 * 2) there is a chance that MIN("s", "t") won't be overflowed.
1689 * Thus, we don't care about textureclamp and we could lower
1690 * MIN("uscale", "vscale") below 32. We still have to have
1691 * our data aligned inside a 8:1 rectangle.
1692 * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
1693 * we replicate the data over the padded area.
1694 * For now, we take 2) + 3) but texelfetchers will be wrong!
1695 */
1696 const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
1697 GLuint srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
1698
1699 GLuint destRowStride = _mesa_compressed_row_stride(mesaFormat,
1700 mml->width);
1701
1702 _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4,
1703 destRowStride, (mml->height+3) / 4,
1704 1, data, srcRowStride,
1705 texImage->Data);
1706 ti->padded = GL_TRUE;
1707 } else {
1708 MEMCPY(texImage->Data, data, texImage->CompressedSize);
1709 }
1710
1711 /* GL_SGIS_generate_mipmap */
1712 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1713 assert(!texImage->IsCompressed);
1714 }
1715
1716 RevalidateTexture(ctx, texObj);
1717
1718 ti->reloadImages = GL_TRUE;
1719 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1720 }
1721
1722
1723 static void
1724 tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
1725 GLint level, GLint xoffset,
1726 GLint yoffset, GLsizei width,
1727 GLint height, GLenum format,
1728 GLsizei imageSize, const GLvoid *data,
1729 struct gl_texture_object *texObj,
1730 struct gl_texture_image *texImage )
1731 {
1732 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1733 tdfxTexInfo *ti;
1734 tdfxMipMapLevel *mml;
1735 GLint destRowStride, srcRowStride;
1736 GLint i, rows;
1737 GLubyte *dest;
1738 const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
1739
1740 if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
1741 fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name);
1742 }
1743
1744 ti = TDFX_TEXTURE_DATA(texObj);
1745 assert(ti);
1746 mml = TDFX_TEXIMAGE_DATA(texImage);
1747 assert(mml);
1748
1749 srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
1750
1751 destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width);
1752 dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
1753 mesaFormat,
1754 mml->width,
1755 (GLubyte*) texImage->Data);
1756
1757 rows = height / 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */
1758
1759 for (i = 0; i < rows; i++) {
1760 MEMCPY(dest, data, srcRowStride);
1761 dest += destRowStride;
1762 data = (GLvoid *)((GLuint)data + (GLuint)srcRowStride);
1763 }
1764
1765 /* [dBorca] Hack alert:
1766 * see fxDDCompressedTexImage2D for caveats
1767 */
1768 if (mml->wScale != 1 || mml->hScale != 1) {
1769 srcRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
1770
1771 destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width);
1772 _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4,
1773 destRowStride, mml->height / 4,
1774 1, texImage->Data, destRowStride,
1775 texImage->Data);
1776 }
1777
1778 /* GL_SGIS_generate_mipmap */
1779 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1780 assert(!texImage->IsCompressed);
1781 }
1782
1783 RevalidateTexture(ctx, texObj);
1784
1785 ti->reloadImages = GL_TRUE;
1786 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1787 }
1788
1789
1790 #if 0
1791 static void
1792 PrintTexture(int w, int h, int c, const GLubyte * data)
1793 {
1794 int i, j;
1795 for (i = 0; i < h; i++) {
1796 for (j = 0; j < w; j++) {
1797 if (c == 2)
1798 printf("%02x %02x ", data[0], data[1]);
1799 else if (c == 3)
1800 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1801 data += c;
1802 }
1803 printf("\n");
1804 }
1805 }
1806 #endif
1807
1808
1809 GLboolean
1810 tdfxTestProxyTexImage(GLcontext *ctx, GLenum target,
1811 GLint level, GLint internalFormat,
1812 GLenum format, GLenum type,
1813 GLint width, GLint height,
1814 GLint depth, GLint border)
1815 {
1816 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1817 struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
1818 struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
1819
1820 switch (target) {
1821 case GL_PROXY_TEXTURE_1D:
1822 /*JJJ wrong*/
1823 case GL_PROXY_TEXTURE_2D:
1824 {
1825 struct gl_texture_object *tObj;
1826 tdfxTexInfo *ti;
1827 int memNeeded;
1828
1829 tObj = ctx->Texture.Proxy2D;
1830 if (!tObj->DriverData)
1831 tObj->DriverData = fxAllocTexObjData(fxMesa);
1832 ti = TDFX_TEXTURE_DATA(tObj);
1833 assert(ti);
1834
1835 /* assign the parameters to test against */
1836 tObj->Image[0][level]->Width = width;
1837 tObj->Image[0][level]->Height = height;
1838 tObj->Image[0][level]->Border = border;
1839 #if 0
1840 tObj->Image[0][level]->InternalFormat = internalFormat;
1841 #endif
1842 if (level == 0) {
1843 /* don't use mipmap levels > 0 */
1844 tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
1845 }
1846 else {
1847 /* test with all mipmap levels */
1848 tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
1849 tObj->MagFilter = GL_NEAREST;
1850 }
1851 RevalidateTexture(ctx, tObj);
1852
1853 /*
1854 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1855 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1856 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1857 printf("glide format 0x%x\n", ti->info.format);
1858 printf("data %p\n", ti->info.data);
1859 printf("lodblend %d\n", (int) ti->LODblend);
1860 */
1861
1862 /* determine where texture will reside */
1863 if (ti->LODblend && !shared->umaTexMemory) {
1864 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1865 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1866 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1867 }
1868 else {
1869 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1870 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1871 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1872 }
1873 /*
1874 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1875 */
1876 if (memNeeded > shared->totalTexMem[0])
1877 return GL_FALSE;
1878 else
1879 return GL_TRUE;
1880 }
1881 case GL_PROXY_TEXTURE_3D:
1882 return GL_TRUE; /* software rendering */
1883 default:
1884 return GL_TRUE; /* never happens, silence compiler */
1885 }
1886 }
1887
1888
1889 /**
1890 * Allocate a new texture object.
1891 * Called via ctx->Driver.NewTextureObject.
1892 * Note: this function will be called during context creation to
1893 * allocate the default texture objects.
1894 * Note: we could use containment here to 'derive' the driver-specific
1895 * texture object from the core mesa gl_texture_object. Not done at this time.
1896 */
1897 static struct gl_texture_object *
1898 tdfxNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
1899 {
1900 struct gl_texture_object *obj;
1901 obj = _mesa_new_texture_object(ctx, name, target);
1902 return obj;
1903 }
1904
1905
1906 void tdfxInitTextureFuncs( struct dd_function_table *functions )
1907 {
1908 functions->BindTexture = tdfxBindTexture;
1909 functions->NewTextureObject = tdfxNewTextureObject;
1910 functions->DeleteTexture = tdfxDeleteTexture;
1911 functions->TexEnv = tdfxTexEnv;
1912 functions->TexParameter = tdfxTexParameter;
1913 functions->ChooseTextureFormat = tdfxChooseTextureFormat;
1914 functions->TexImage1D = tdfxTexImage1D;
1915 functions->TexSubImage1D = tdfxTexSubImage1D;
1916 functions->TexImage2D = tdfxTexImage2D;
1917 functions->TexSubImage2D = tdfxTexSubImage2D;
1918 functions->IsTextureResident = tdfxIsTextureResident;
1919 functions->CompressedTexImage2D = tdfxCompressedTexImage2D;
1920 functions->CompressedTexSubImage2D = tdfxCompressedTexSubImage2D;
1921 functions->UpdateTexturePalette = tdfxUpdateTexturePalette;
1922 }