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