include texobj.h to silence warnings
[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 * Original rewrite:
30 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
31 *
32 * Authors:
33 * Gareth Hughes <gareth@valinux.com>
34 * Brian Paul <brianp@valinux.com>
35 *
36 */
37
38 #include "image.h"
39 #include "texutil.h"
40 #include "texformat.h"
41 #include "teximage.h"
42 #include "texstore.h"
43 #include "texobj.h"
44 #include "tdfx_context.h"
45 #include "tdfx_tex.h"
46 #include "tdfx_texman.h"
47
48
49
50 static int
51 logbase2(int n)
52 {
53 GLint i = 1;
54 GLint log2 = 0;
55
56 if (n < 0) {
57 return -1;
58 }
59
60 while (n > i) {
61 i *= 2;
62 log2++;
63 }
64 if (i != n) {
65 return -1;
66 }
67 else {
68 return log2;
69 }
70 }
71
72
73 /*
74 * Compute various texture image parameters.
75 * Input: w, h - source texture width and height
76 * Output: lodlevel - Glide lod level token for the larger texture dimension
77 * aspectratio - Glide aspect ratio token
78 * sscale - S scale factor used during triangle setup
79 * tscale - T scale factor used during triangle setup
80 * wscale - OpenGL -> Glide image width scale factor
81 * hscale - OpenGL -> Glide image height scale factor
82 *
83 * Sample results:
84 * w h lodlevel aspectRatio
85 * 128 128 GR_LOD_LOG2_128 (=7) GR_ASPECT_LOG2_1x1 (=0)
86 * 64 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x1 (=0)
87 * 64 32 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_2x1 (=1)
88 * 32 64 GR_LOD_LOG2_64 (=6) GR_ASPECT_LOG2_1x2 (=-1)
89 * 32 32 GR_LOD_LOG2_32 (=5) GR_ASPECT_LOG2_1x1 (=0)
90 */
91 static void
92 tdfxTexGetInfo(const GLcontext *ctx, int w, int h,
93 GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,
94 float *sscale, float *tscale,
95 int *wscale, int *hscale)
96 {
97 int logw, logh, ar, lod, ws, hs;
98 float s, t;
99
100 ASSERT(w >= 1);
101 ASSERT(h >= 1);
102
103 logw = logbase2(w);
104 logh = logbase2(h);
105 ar = logw - logh; /* aspect ratio = difference in log dimensions */
106
107 /* Hardware only allows a maximum aspect ratio of 8x1, so handle
108 |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
109 if (ar >= 0) {
110 ASSERT(width >= height);
111 lod = logw;
112 s = 256.0;
113 ws = 1;
114 if (ar <= GR_ASPECT_LOG2_8x1) {
115 t = 256 >> ar;
116 hs = 1;
117 }
118 else {
119 /* have to stretch image height */
120 t = 32.0;
121 hs = 1 << (ar - 3);
122 }
123 }
124 else {
125 ASSERT(width < height);
126 lod = logh;
127 t = 256.0;
128 hs = 1;
129 if (ar >= GR_ASPECT_LOG2_1x8) {
130 s = 256 >> -ar;
131 ws = 1;
132 }
133 else {
134 /* have to stretch image width */
135 s = 32.0;
136 ws = 1 << (-ar - 3);
137 }
138 }
139
140 if (ar < GR_ASPECT_LOG2_1x8)
141 ar = GR_ASPECT_LOG2_1x8;
142 else if (ar > GR_ASPECT_LOG2_8x1)
143 ar = GR_ASPECT_LOG2_8x1;
144
145 if (lodlevel)
146 *lodlevel = (GrLOD_t) lod;
147 if (aspectratio)
148 *aspectratio = (GrAspectRatio_t) ar;
149 if (sscale)
150 *sscale = s;
151 if (tscale)
152 *tscale = t;
153 if (wscale)
154 *wscale = ws;
155 if (hscale)
156 *hscale = hs;
157 }
158
159
160 /*
161 * We need to call this when a texture object's minification filter
162 * or texture image sizes change.
163 */
164 static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj)
165 {
166 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
167 GLint minl, maxl;
168
169 if (!ti)
170 return;
171
172 minl = maxl = tObj->BaseLevel;
173
174 if (tObj->Image[minl]) {
175 maxl = MIN2(tObj->MaxLevel, tObj->Image[minl]->MaxLog2);
176
177 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
178 tdfxTexGetInfo(ctx, tObj->Image[minl]->Width, tObj->Image[minl]->Height,
179 &ti->info.largeLodLog2,
180 &ti->info.aspectRatioLog2,
181 &(ti->sScale), &(ti->tScale), NULL, NULL);
182 }
183
184 if (tObj->Image[maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
185 /* mipmapping: need to compute smallLodLog2 */
186 tdfxTexGetInfo(ctx, tObj->Image[maxl]->Width,
187 tObj->Image[maxl]->Height,
188 &ti->info.smallLodLog2, NULL,
189 NULL, NULL, NULL, NULL);
190 }
191 else {
192 /* not mipmapping: smallLodLog2 = largeLodLog2 */
193 ti->info.smallLodLog2 = ti->info.largeLodLog2;
194 maxl = minl;
195 }
196
197 ti->minLevel = minl;
198 ti->maxLevel = maxl;
199 ti->info.data = NULL;
200 }
201
202
203 static tdfxTexInfo *
204 fxAllocTexObjData(tdfxContextPtr fxMesa)
205 {
206 tdfxTexInfo *ti;
207
208 if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) {
209 _mesa_problem(NULL, "tdfx driver: out of memory");
210 return NULL;
211 }
212
213 ti->isInTM = GL_FALSE;
214
215 ti->whichTMU = TDFX_TMU_NONE;
216
217 ti->tm[TDFX_TMU0] = NULL;
218 ti->tm[TDFX_TMU1] = NULL;
219
220 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
221 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
222
223 ti->sClamp = GR_TEXTURECLAMP_WRAP;
224 ti->tClamp = GR_TEXTURECLAMP_WRAP;
225
226 ti->mmMode = GR_MIPMAP_NEAREST;
227 ti->LODblend = FXFALSE;
228
229 return ti;
230 }
231
232
233 /*
234 * Called via glBindTexture.
235 */
236
237 void
238 tdfxDDBindTexture(GLcontext * ctx, GLenum target,
239 struct gl_texture_object *tObj)
240 {
241 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
242 tdfxTexInfo *ti;
243
244 if (MESA_VERBOSE & VERBOSE_DRIVER) {
245 fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,
246 tObj->DriverData);
247 }
248
249 if (target != GL_TEXTURE_2D)
250 return;
251
252 if (!tObj->DriverData) {
253 tObj->DriverData = fxAllocTexObjData(fxMesa);
254 }
255
256 ti = TDFX_TEXTURE_DATA(tObj);
257 ti->lastTimeUsed = fxMesa->texBindNumber++;
258
259 fxMesa->new_state |= TDFX_NEW_TEXTURE;
260 }
261
262
263 /*
264 * Called via glTexEnv.
265 */
266 void
267 tdfxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
268 const GLfloat * param)
269 {
270 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
271
272 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
273 if (param)
274 fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,
275 (GLint) (*param));
276 else
277 fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
278 }
279
280 /* XXX this is a bit of a hack to force the Glide texture
281 * state to be updated.
282 */
283 fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit] = 0;
284
285 fxMesa->new_state |= TDFX_NEW_TEXTURE;
286 }
287
288
289 /*
290 * Called via glTexParameter.
291 */
292 void
293 tdfxDDTexParameter(GLcontext * ctx, GLenum target,
294 struct gl_texture_object *tObj,
295 GLenum pname, const GLfloat * params)
296 {
297 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
298 GLenum param = (GLenum) (GLint) params[0];
299 tdfxTexInfo *ti;
300
301 if (MESA_VERBOSE & VERBOSE_DRIVER) {
302 fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,
303 tObj->DriverData, pname, param);
304 }
305
306 if (target != GL_TEXTURE_2D)
307 return;
308
309 if (!tObj->DriverData)
310 tObj->DriverData = fxAllocTexObjData(fxMesa);
311
312 ti = TDFX_TEXTURE_DATA(tObj);
313
314 switch (pname) {
315 case GL_TEXTURE_MIN_FILTER:
316 switch (param) {
317 case GL_NEAREST:
318 ti->mmMode = GR_MIPMAP_DISABLE;
319 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
320 ti->LODblend = FXFALSE;
321 break;
322 case GL_LINEAR:
323 ti->mmMode = GR_MIPMAP_DISABLE;
324 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
325 ti->LODblend = FXFALSE;
326 break;
327 case GL_NEAREST_MIPMAP_LINEAR:
328 if (TDFX_IS_NAPALM(fxMesa)) {
329 if (fxMesa->haveTwoTMUs) {
330 ti->mmMode = GR_MIPMAP_NEAREST;
331 ti->LODblend = FXTRUE;
332 }
333 else {
334 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
335 ti->LODblend = FXFALSE;
336 }
337 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
338 break;
339 }
340 /* XXX Voodoo3/Banshee mipmap blending seems to produce
341 * incorrectly filtered colors for the smallest mipmap levels.
342 * To work-around we fall-through here and use a different filter.
343 */
344 case GL_NEAREST_MIPMAP_NEAREST:
345 ti->mmMode = GR_MIPMAP_NEAREST;
346 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
347 ti->LODblend = FXFALSE;
348 break;
349 case GL_LINEAR_MIPMAP_LINEAR:
350 if (TDFX_IS_NAPALM(fxMesa)) {
351 if (fxMesa->haveTwoTMUs) {
352 ti->mmMode = GR_MIPMAP_NEAREST;
353 ti->LODblend = FXTRUE;
354 }
355 else {
356 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
357 ti->LODblend = FXFALSE;
358 }
359 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
360 break;
361 }
362 /* XXX Voodoo3/Banshee mipmap blending seems to produce
363 * incorrectly filtered colors for the smallest mipmap levels.
364 * To work-around we fall-through here and use a different filter.
365 */
366 case GL_LINEAR_MIPMAP_NEAREST:
367 ti->mmMode = GR_MIPMAP_NEAREST;
368 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
369 ti->LODblend = FXFALSE;
370 break;
371 default:
372 break;
373 }
374 RevalidateTexture(ctx, tObj);
375 fxMesa->new_state |= TDFX_NEW_TEXTURE;
376 break;
377
378 case GL_TEXTURE_MAG_FILTER:
379 switch (param) {
380 case GL_NEAREST:
381 ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
382 break;
383 case GL_LINEAR:
384 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
385 break;
386 default:
387 break;
388 }
389 fxMesa->new_state |= TDFX_NEW_TEXTURE;
390 break;
391
392 case GL_TEXTURE_WRAP_S:
393 switch (param) {
394 case GL_CLAMP:
395 ti->sClamp = GR_TEXTURECLAMP_CLAMP;
396 break;
397 case GL_REPEAT:
398 ti->sClamp = GR_TEXTURECLAMP_WRAP;
399 break;
400 default:
401 break;
402 }
403 fxMesa->new_state |= TDFX_NEW_TEXTURE;
404 break;
405
406 case GL_TEXTURE_WRAP_T:
407 switch (param) {
408 case GL_CLAMP:
409 ti->tClamp = GR_TEXTURECLAMP_CLAMP;
410 break;
411 case GL_REPEAT:
412 ti->tClamp = GR_TEXTURECLAMP_WRAP;
413 break;
414 default:
415 break;
416 }
417 fxMesa->new_state |= TDFX_NEW_TEXTURE;
418 break;
419
420 case GL_TEXTURE_BORDER_COLOR:
421 /* TO DO */
422 break;
423 case GL_TEXTURE_MIN_LOD:
424 /* TO DO */
425 break;
426 case GL_TEXTURE_MAX_LOD:
427 /* TO DO */
428 break;
429 case GL_TEXTURE_BASE_LEVEL:
430 RevalidateTexture(ctx, tObj);
431 break;
432 case GL_TEXTURE_MAX_LEVEL:
433 RevalidateTexture(ctx, tObj);
434 break;
435
436 default:
437 break;
438 }
439 }
440
441
442 /*
443 * Called via glDeleteTextures to delete a texture object.
444 * Here, we delete the Glide data associated with the texture.
445 */
446 void
447 tdfxDDDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj)
448 {
449 if (ctx && ctx->DriverCtx) {
450 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
451 tdfxTMFreeTexture(fxMesa, tObj);
452 fxMesa->new_state |= TDFX_NEW_TEXTURE;
453 /* Free mipmap images and the texture object itself */
454 _mesa_delete_texture_object(ctx, tObj);
455 }
456 }
457
458
459 /*
460 * Return true if texture is resident, false otherwise.
461 */
462 GLboolean
463 tdfxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj)
464 {
465 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
466 return (GLboolean) (ti && ti->isInTM);
467 }
468
469
470
471 /*
472 * Convert a gl_color_table texture palette to Glide's format.
473 */
474 static void
475 convertPalette(FxU32 data[256], const struct gl_color_table *table)
476 {
477 const GLubyte *tableUB = (const GLubyte *) table->Table;
478 GLint width = table->Size;
479 FxU32 r, g, b, a;
480 GLint i;
481
482 ASSERT(table->TableType == GL_UNSIGNED_BYTE);
483
484 switch (table->Format) {
485 case GL_INTENSITY:
486 for (i = 0; i < width; i++) {
487 r = tableUB[i];
488 g = tableUB[i];
489 b = tableUB[i];
490 a = tableUB[i];
491 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
492 }
493 break;
494 case GL_LUMINANCE:
495 for (i = 0; i < width; i++) {
496 r = tableUB[i];
497 g = tableUB[i];
498 b = tableUB[i];
499 a = 255;
500 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
501 }
502 break;
503 case GL_ALPHA:
504 for (i = 0; i < width; i++) {
505 r = g = b = 255;
506 a = tableUB[i];
507 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
508 }
509 break;
510 case GL_LUMINANCE_ALPHA:
511 for (i = 0; i < width; i++) {
512 r = g = b = tableUB[i * 2 + 0];
513 a = tableUB[i * 2 + 1];
514 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
515 }
516 break;
517 case GL_RGB:
518 for (i = 0; i < width; i++) {
519 r = tableUB[i * 3 + 0];
520 g = tableUB[i * 3 + 1];
521 b = tableUB[i * 3 + 2];
522 a = 255;
523 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
524 }
525 break;
526 case GL_RGBA:
527 for (i = 0; i < width; i++) {
528 r = tableUB[i * 4 + 0];
529 g = tableUB[i * 4 + 1];
530 b = tableUB[i * 4 + 2];
531 a = tableUB[i * 4 + 3];
532 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
533 }
534 break;
535 }
536 }
537
538
539
540 void
541 tdfxDDTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj)
542 {
543 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
544
545 if (tObj) {
546 /* per-texture palette */
547 tdfxTexInfo *ti;
548
549 /* This might be a proxy texture. */
550 if (!tObj->Palette.Table)
551 return;
552
553 if (!tObj->DriverData)
554 tObj->DriverData = fxAllocTexObjData(fxMesa);
555 ti = TDFX_TEXTURE_DATA(tObj);
556 convertPalette(ti->palette.data, &tObj->Palette);
557 /*tdfxTexInvalidate(ctx, tObj);*/
558 }
559 else {
560 /* global texture palette */
561 convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
562 }
563 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */
564 }
565
566
567 /**********************************************************************/
568 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
569 /**********************************************************************/
570
571 #if 000
572 static FxBool TexusFatalError = FXFALSE;
573 static FxBool TexusError = FXFALSE;
574
575 #define TX_DITHER_NONE 0x00000000
576
577 static void
578 fxTexusError(const char *string, FxBool fatal)
579 {
580 _mesa_problem(NULL, string);
581 /*
582 * Just propagate the fatal value up.
583 */
584 TexusError = FXTRUE;
585 TexusFatalError = fatal;
586 }
587 #endif
588
589
590 const struct gl_texture_format *
591 tdfxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
592 GLenum srcFormat, GLenum srcType )
593 {
594 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
595 const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
596
597 switch (internalFormat) {
598 case GL_ALPHA:
599 case GL_ALPHA4:
600 case GL_ALPHA8:
601 case GL_ALPHA12:
602 case GL_ALPHA16:
603 return &_mesa_texformat_a8;
604 case 1:
605 case GL_LUMINANCE:
606 case GL_LUMINANCE4:
607 case GL_LUMINANCE8:
608 case GL_LUMINANCE12:
609 case GL_LUMINANCE16:
610 return &_mesa_texformat_l8;
611 case 2:
612 case GL_LUMINANCE_ALPHA:
613 case GL_LUMINANCE4_ALPHA4:
614 case GL_LUMINANCE6_ALPHA2:
615 case GL_LUMINANCE8_ALPHA8:
616 case GL_LUMINANCE12_ALPHA4:
617 case GL_LUMINANCE12_ALPHA12:
618 case GL_LUMINANCE16_ALPHA16:
619 return &_mesa_texformat_al88;
620 case GL_INTENSITY:
621 case GL_INTENSITY4:
622 case GL_INTENSITY8:
623 case GL_INTENSITY12:
624 case GL_INTENSITY16:
625 return &_mesa_texformat_i8;
626 case GL_R3_G3_B2:
627 case GL_RGB4:
628 case GL_RGB5:
629 return &_mesa_texformat_rgb565;
630 case 3:
631 case GL_RGB:
632 case GL_RGB8:
633 case GL_RGB10:
634 case GL_RGB12:
635 case GL_RGB16:
636 return (allow32bpt) ? &_mesa_texformat_argb8888
637 : &_mesa_texformat_rgb565;
638 break;
639 case GL_RGBA2:
640 case GL_RGBA4:
641 return &_mesa_texformat_argb4444;
642 case 4:
643 case GL_RGBA:
644 case GL_RGBA8:
645 case GL_RGB10_A2:
646 case GL_RGBA12:
647 case GL_RGBA16:
648 return allow32bpt ? &_mesa_texformat_argb8888
649 : &_mesa_texformat_argb4444;
650 case GL_RGB5_A1:
651 return &_mesa_texformat_argb1555;
652 case GL_COLOR_INDEX:
653 case GL_COLOR_INDEX1_EXT:
654 case GL_COLOR_INDEX2_EXT:
655 case GL_COLOR_INDEX4_EXT:
656 case GL_COLOR_INDEX8_EXT:
657 case GL_COLOR_INDEX12_EXT:
658 case GL_COLOR_INDEX16_EXT:
659 return &_mesa_texformat_ci8;
660 default:
661 _mesa_problem(ctx, "unexpected format in tdfxDDChooseTextureFormat");
662 return NULL;
663 }
664 }
665
666
667 /*
668 * Return the Glide format for the given mesa texture format.
669 */
670 static GrTextureFormat_t
671 fxGlideFormat(GLint mesaFormat)
672 {
673 switch (mesaFormat) {
674 case MESA_FORMAT_I8:
675 return GR_TEXFMT_ALPHA_8;
676 case MESA_FORMAT_A8:
677 return GR_TEXFMT_ALPHA_8;
678 case MESA_FORMAT_L8:
679 return GR_TEXFMT_INTENSITY_8;
680 case MESA_FORMAT_CI8:
681 return GR_TEXFMT_P_8;
682 case MESA_FORMAT_AL88:
683 return GR_TEXFMT_ALPHA_INTENSITY_88;
684 case MESA_FORMAT_RGB565:
685 return GR_TEXFMT_RGB_565;
686 case MESA_FORMAT_ARGB4444:
687 return GR_TEXFMT_ARGB_4444;
688 case MESA_FORMAT_ARGB1555:
689 return GR_TEXFMT_ARGB_1555;
690 case MESA_FORMAT_ARGB8888:
691 return GR_TEXFMT_ARGB_8888;
692 default:
693 _mesa_problem(NULL, "Unexpected format in fxGlideFormat");
694 return 0;
695 }
696 }
697
698
699 /* Texel-fetch functions for software texturing and glGetTexImage().
700 * We should have been able to use some "standard" fetch functions (which
701 * may get defined in texutil.c) but we have to account for scaled texture
702 * images on tdfx hardware (the 8:1 aspect ratio limit).
703 * Hence, we need special functions here.
704 */
705
706 static void
707 fetch_intensity8(const struct gl_texture_image *texImage,
708 GLint i, GLint j, GLint k, GLvoid * texelOut)
709 {
710 GLchan *rgba = (GLchan *) texelOut;
711 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
712 const GLubyte *texel;
713
714 i = i * mml->wScale;
715 j = j * mml->hScale;
716
717 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
718 rgba[RCOMP] = *texel;
719 rgba[GCOMP] = *texel;
720 rgba[BCOMP] = *texel;
721 rgba[ACOMP] = *texel;
722 }
723
724
725 static void
726 fetch_luminance8(const struct gl_texture_image *texImage,
727 GLint i, GLint j, GLint k, GLvoid * texelOut)
728 {
729 GLchan *rgba = (GLchan *) texelOut;
730 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
731 const GLubyte *texel;
732
733 i = i * mml->wScale;
734 j = j * mml->hScale;
735
736 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
737 rgba[RCOMP] = *texel;
738 rgba[GCOMP] = *texel;
739 rgba[BCOMP] = *texel;
740 rgba[ACOMP] = 255;
741 }
742
743
744 static void
745 fetch_alpha8(const struct gl_texture_image *texImage,
746 GLint i, GLint j, GLint k, GLvoid * texelOut)
747 {
748 GLchan *rgba = (GLchan *) texelOut;
749 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
750 const GLubyte *texel;
751
752 i = i * mml->wScale;
753 j = j * mml->hScale;
754 i = i * mml->width / texImage->Width;
755 j = j * mml->height / texImage->Height;
756
757 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
758 rgba[RCOMP] = 255;
759 rgba[GCOMP] = 255;
760 rgba[BCOMP] = 255;
761 rgba[ACOMP] = *texel;
762 }
763
764
765 static void
766 fetch_index8(const struct gl_texture_image *texImage,
767 GLint i, GLint j, GLint k, GLvoid * texelOut)
768 {
769 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
770 (void) mml;
771 /* XXX todo */
772 }
773
774
775 static void
776 fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
777 GLint i, GLint j, GLint k, GLvoid * texelOut)
778 {
779 GLchan *rgba = (GLchan *) texelOut;
780 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
781 const GLubyte *texel;
782
783 i = i * mml->wScale;
784 j = j * mml->hScale;
785
786 texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2;
787 rgba[RCOMP] = texel[0];
788 rgba[GCOMP] = texel[0];
789 rgba[BCOMP] = texel[0];
790 rgba[ACOMP] = texel[1];
791 }
792
793
794 static void
795 fetch_r5g6b5(const struct gl_texture_image *texImage,
796 GLint i, GLint j, GLint k, GLvoid * texelOut)
797 {
798 GLchan *rgba = (GLchan *) texelOut;
799 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
800 const GLushort *texel;
801
802 i = i * mml->wScale;
803 j = j * mml->hScale;
804
805 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
806 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
807 rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63;
808 rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31;
809 rgba[ACOMP] = 255;
810 }
811
812
813 static void
814 fetch_r4g4b4a4(const struct gl_texture_image *texImage,
815 GLint i, GLint j, GLint k, GLvoid * texelOut)
816 {
817 GLchan *rgba = (GLchan *) texelOut;
818 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
819 const GLushort *texel;
820
821 i = i * mml->wScale;
822 j = j * mml->hScale;
823
824 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
825 rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15;
826 rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15;
827 rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15;
828 rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;
829 }
830
831
832 static void
833 fetch_r5g5b5a1(const struct gl_texture_image *texImage,
834 GLint i, GLint j, GLint k, GLvoid * texelOut)
835 {
836 GLchan *rgba = (GLchan *) texelOut;
837 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
838 const GLushort *texel;
839
840 i = i * mml->wScale;
841 j = j * mml->hScale;
842
843 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
844 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
845 rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31;
846 rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31;
847 rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;
848 }
849
850
851 static void
852 fetch_a8r8g8b8(const struct gl_texture_image *texImage,
853 GLint i, GLint j, GLint k, GLvoid * texelOut)
854 {
855 GLchan *rgba = (GLchan *) texelOut;
856 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
857 const GLuint *texel;
858
859 i = i * mml->wScale;
860 j = j * mml->hScale;
861
862 texel = ((GLuint *) texImage->Data) + j * mml->width + i;
863 rgba[RCOMP] = (((*texel) >> 16) & 0xff);
864 rgba[GCOMP] = (((*texel) >> 8) & 0xff);
865 rgba[BCOMP] = (((*texel) ) & 0xff);
866 rgba[ACOMP] = (((*texel) >> 24) & 0xff);
867 }
868
869
870 static FetchTexelFunc
871 fxFetchFunction(GLint mesaFormat)
872 {
873 switch (mesaFormat) {
874 case MESA_FORMAT_I8:
875 return fetch_intensity8;
876 case MESA_FORMAT_A8:
877 return fetch_alpha8;
878 case MESA_FORMAT_L8:
879 return fetch_luminance8;
880 case MESA_FORMAT_CI8:
881 return fetch_index8;
882 case MESA_FORMAT_AL88:
883 return fetch_luminance8_alpha8;
884 case MESA_FORMAT_RGB565:
885 return fetch_r5g6b5;
886 case MESA_FORMAT_ARGB4444:
887 return fetch_r4g4b4a4;
888 case MESA_FORMAT_ARGB1555:
889 return fetch_r5g5b5a1;
890 case MESA_FORMAT_ARGB8888:
891 return fetch_a8r8g8b8;
892 default:
893 _mesa_problem(NULL, "Unexpected format in fxFetchFunction");
894 printf("%d\n", mesaFormat);
895 return NULL;
896 }
897 }
898
899
900 void
901 tdfxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
902 GLint internalFormat, GLint width, GLint height, GLint border,
903 GLenum format, GLenum type, const GLvoid *pixels,
904 const struct gl_pixelstore_attrib *packing,
905 struct gl_texture_object *texObj,
906 struct gl_texture_image *texImage)
907 {
908 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
909 tdfxTexInfo *ti;
910 tdfxMipMapLevel *mml;
911 GLint texelBytes;
912
913 /*
914 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
915 texObj->Name, texImage->IntFormat, format, type,
916 texImage->Width, texImage->Height);
917 */
918
919 ti = TDFX_TEXTURE_DATA(texObj);
920 if (!ti) {
921 texObj->DriverData = fxAllocTexObjData(fxMesa);
922 if (!texObj->DriverData) {
923 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
924 return;
925 }
926 ti = TDFX_TEXTURE_DATA(texObj);
927 }
928
929 mml = TDFX_TEXIMAGE_DATA(texImage);
930 if (!mml) {
931 texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
932 if (!texImage->DriverData) {
933 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
934 return;
935 }
936 mml = TDFX_TEXIMAGE_DATA(texImage);
937 }
938
939 /* Determine width and height scale factors for texture.
940 * Remember, Glide is limited to 8:1 aspect ratios.
941 */
942 tdfxTexGetInfo(ctx,
943 texImage->Width, texImage->Height,
944 NULL, /* lod level */
945 NULL, /* aspect ratio */
946 NULL, NULL, /* sscale, tscale */
947 &mml->wScale, &mml->hScale);
948
949 /* rescaled size: */
950 mml->width = width * mml->wScale;
951 mml->height = height * mml->hScale;
952
953
954 /* choose the texture format */
955 assert(ctx->Driver.ChooseTextureFormat);
956 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
957 internalFormat, format, type);
958 assert(texImage->TexFormat);
959 mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
960 ti->info.format = mml->glideFormat;
961 texImage->FetchTexel = fxFetchFunction(texImage->TexFormat->MesaFormat);
962 texelBytes = texImage->TexFormat->TexelBytes;
963
964 if (mml->width != width || mml->height != height) {
965 /* rescale the image to overcome 1:8 aspect limitation */
966 GLvoid *tempImage;
967 tempImage = MALLOC(width * height * texelBytes);
968 if (!tempImage) {
969 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
970 return;
971 }
972 /* unpack image, apply transfer ops and store in tempImage */
973 _mesa_transfer_teximage(ctx, 2, texImage->Format,
974 texImage->TexFormat,
975 tempImage,
976 width, height, 1, 0, 0, 0,
977 width * texelBytes,
978 0, /* dstImageStride */
979 format, type, pixels, packing);
980 assert(!texImage->Data);
981 texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
982 if (!texImage->Data) {
983 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
984 FREE(tempImage);
985 return;
986 }
987 _mesa_rescale_teximage2d(texelBytes,
988 mml->width * texelBytes, /* dst stride */
989 width, height,
990 mml->width, mml->height,
991 tempImage /*src*/, texImage->Data /*dst*/ );
992 FREE(tempImage);
993 }
994 else {
995 /* no rescaling needed */
996 assert(!texImage->Data);
997 texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
998 if (!texImage->Data) {
999 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1000 return;
1001 }
1002 /* unpack image, apply transfer ops and store in texImage->Data */
1003 _mesa_transfer_teximage(ctx, 2, texImage->Format,
1004 texImage->TexFormat, texImage->Data,
1005 width, height, 1, 0, 0, 0,
1006 texImage->Width * texelBytes,
1007 0, /* dstImageStride */
1008 format, type, pixels, packing);
1009 }
1010
1011 RevalidateTexture(ctx, texObj);
1012
1013 ti->reloadImages = GL_TRUE;
1014 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1015 }
1016
1017
1018 void
1019 tdfxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
1020 GLint xoffset, GLint yoffset,
1021 GLsizei width, GLsizei height,
1022 GLenum format, GLenum type,
1023 const GLvoid *pixels,
1024 const struct gl_pixelstore_attrib *packing,
1025 struct gl_texture_object *texObj,
1026 struct gl_texture_image *texImage )
1027 {
1028 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1029 tdfxTexInfo *ti;
1030 tdfxMipMapLevel *mml;
1031 GLint texelBytes;
1032
1033 if (!texObj->DriverData) {
1034 _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
1035 return;
1036 }
1037
1038 ti = TDFX_TEXTURE_DATA(texObj);
1039 assert(ti);
1040 mml = TDFX_TEXIMAGE_DATA(texImage);
1041 assert(mml);
1042
1043 assert(texImage->Data); /* must have an existing texture image! */
1044 assert(texImage->Format);
1045
1046 texelBytes = texImage->TexFormat->TexelBytes;
1047
1048 if (mml->wScale != 1 || mml->hScale != 1) {
1049 /* need to rescale subimage to match mipmap level's rescale factors */
1050 const GLint newWidth = width * mml->wScale;
1051 const GLint newHeight = height * mml->hScale;
1052 GLvoid *scaledImage, *tempImage;
1053 GLubyte *destAddr;
1054 tempImage = MALLOC(width * height * texelBytes);
1055 if (!tempImage) {
1056 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1057 return;
1058 }
1059
1060 _mesa_transfer_teximage(ctx, 2, texImage->Format,/* Tex int format */
1061 texImage->TexFormat, /* dest format */
1062 (GLubyte *) tempImage, /* dest */
1063 width, height, 1, /* subimage size */
1064 0, 0, 0, /* subimage pos */
1065 width * texelBytes, /* dest row stride */
1066 0, /* dst image stride */
1067 format, type, pixels, packing);
1068
1069 /* now rescale */
1070 scaledImage = MALLOC(newWidth * newHeight * texelBytes);
1071 if (!scaledImage) {
1072 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1073 FREE(tempImage);
1074 return;
1075 }
1076
1077 /* compute address of dest subimage within the overal tex image */
1078 destAddr = (GLubyte *) texImage->Data
1079 + (yoffset * mml->hScale * mml->width
1080 + xoffset * mml->wScale) * texelBytes;
1081
1082 _mesa_rescale_teximage2d(texelBytes,
1083 mml->width * texelBytes, /* dst stride */
1084 width, height,
1085 newWidth, newHeight,
1086 tempImage, destAddr);
1087
1088 FREE(tempImage);
1089 FREE(scaledImage);
1090 }
1091 else {
1092 /* no rescaling needed */
1093 _mesa_transfer_teximage(ctx, 2, texImage->Format, /* Tex int format */
1094 texImage->TexFormat, /* dest format */
1095 (GLubyte *) texImage->Data,/* dest */
1096 width, height, 1, /* subimage size */
1097 xoffset, yoffset, 0, /* subimage pos */
1098 mml->width * texelBytes, /* dest row stride */
1099 0, /* dst image stride */
1100 format, type, pixels, packing);
1101 }
1102
1103 ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
1104 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
1105 }
1106
1107
1108
1109 /**********************************************************************/
1110 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1111 /**********************************************************************/
1112
1113 #if 0000
1114 GLboolean
1115 tdfxDDCompressedTexImage2D( GLcontext *ctx, GLenum target,
1116 GLint level, GLsizei imageSize,
1117 const GLvoid *data,
1118 struct gl_texture_object *texObj,
1119 struct gl_texture_image *texImage,
1120 GLboolean *retainInternalCopy)
1121 {
1122 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1123 const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
1124 GrTextureFormat_t gldformat;
1125 tdfxTexInfo *ti;
1126 tdfxMipMapLevel *mml;
1127 GLint dstWidth, dstHeight, wScale, hScale, texelSize;
1128 MesaIntTexFormat intFormat;
1129 GLboolean isCompressedFormat;
1130 GLsizei texSize;
1131
1132 if (target != GL_TEXTURE_2D || texImage->Border > 0)
1133 return GL_FALSE;
1134
1135 if (!texObj->DriverData)
1136 texObj->DriverData = fxAllocTexObjData(fxMesa);
1137
1138 ti = TDFX_TEXTURE_DATA(texObj);
1139 mml = &ti->mipmapLevel[level];
1140
1141 isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat);
1142 if (!isCompressedFormat) {
1143 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)");
1144 return GL_FALSE;
1145 }
1146 /* Determine the apporpriate GL internal texel format, Mesa internal
1147 * texel format, and texelSize (bytes) given the user's internal
1148 * texture format hint.
1149 */
1150 tdfxTexGetFormat(texImage->IntFormat, allow32bpt,
1151 &gldformat, &intFormat, &texelSize);
1152
1153 /* Determine width and height scale factors for texture.
1154 * Remember, Glide is limited to 8:1 aspect ratios.
1155 */
1156 tdfxTexGetInfo(ctx,
1157 texImage->Width, texImage->Height,
1158 NULL, /* lod level */
1159 NULL, /* aspect ratio */
1160 NULL, NULL, /* sscale, tscale */
1161 &wScale, &hScale);
1162 dstWidth = texImage->Width * wScale;
1163 dstHeight = texImage->Height * hScale;
1164 /* housekeeping */
1165 _mesa_set_teximage_component_sizes(intFormat, texImage);
1166
1167 texSize = tdfxDDCompressedImageSize(ctx,
1168 texImage->IntFormat,
1169 2,
1170 texImage->Width,
1171 texImage->Height,
1172 1);
1173 if (texSize != imageSize) {
1174 _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2D(texSize)");
1175 return GL_FALSE;
1176 }
1177
1178 /* allocate new storage for texture image, if needed */
1179 if (!mml->data || mml->glideFormat != gldformat ||
1180 mml->width != dstWidth || mml->height != dstHeight ||
1181 texSize != mml->dataSize) {
1182 if (mml->data) {
1183 FREE(mml->data);
1184 }
1185 mml->data = MALLOC(texSize);
1186 if (!mml->data) {
1187 return GL_FALSE;
1188 }
1189 mml->texelSize = texelSize;
1190 mml->glideFormat = gldformat;
1191 mml->width = dstWidth;
1192 mml->height = dstHeight;
1193 tdfxTMMoveOutTM(fxMesa, texObj);
1194 /*tdfxTexInvalidate(ctx, texObj);*/
1195 }
1196
1197 /* save the texture data */
1198 MEMCPY(mml->data, data, imageSize);
1199
1200 RevalidateTexture(ctx, texObj);
1201
1202 ti->reloadImages = GL_TRUE;
1203 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1204
1205 *retainInternalCopy = GL_FALSE;
1206 return GL_TRUE;
1207 }
1208
1209 GLboolean
1210 tdfxDDCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
1211 GLint level, GLint xoffset,
1212 GLint yoffset, GLsizei width,
1213 GLint height, GLenum format,
1214 GLsizei imageSize, const GLvoid *data,
1215 struct gl_texture_object *texObj,
1216 struct gl_texture_image *texImage )
1217 {
1218 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1219 tdfxTexInfo *ti;
1220 tdfxMipMapLevel *mml;
1221
1222 /*
1223 * We punt if we are not replacing the entire image. This
1224 * is allowed by the spec.
1225 */
1226 if ((xoffset != 0) && (yoffset != 0)
1227 && (width != texImage->Width)
1228 && (height != texImage->Height)) {
1229 return GL_FALSE;
1230 }
1231
1232 ti = TDFX_TEXTURE_DATA(texObj);
1233 mml = &ti->mipmapLevel[level];
1234 if (imageSize != mml->dataSize) {
1235 return GL_FALSE;
1236 }
1237 MEMCPY(data, mml->data, imageSize);
1238
1239 ti->reloadImages = GL_TRUE;
1240 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1241
1242 return GL_TRUE;
1243 }
1244 #endif
1245
1246
1247
1248 #if 0
1249 static void
1250 PrintTexture(int w, int h, int c, const GLubyte * data)
1251 {
1252 int i, j;
1253 for (i = 0; i < h; i++) {
1254 for (j = 0; j < w; j++) {
1255 if (c == 2)
1256 printf("%02x %02x ", data[0], data[1]);
1257 else if (c == 3)
1258 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1259 data += c;
1260 }
1261 printf("\n");
1262 }
1263 }
1264 #endif
1265
1266
1267 GLboolean
1268 tdfxDDTestProxyTexImage(GLcontext *ctx, GLenum target,
1269 GLint level, GLint internalFormat,
1270 GLenum format, GLenum type,
1271 GLint width, GLint height,
1272 GLint depth, GLint border)
1273 {
1274 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1275 struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
1276 struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
1277
1278 switch (target) {
1279 case GL_PROXY_TEXTURE_1D:
1280 return GL_TRUE; /* software rendering */
1281 case GL_PROXY_TEXTURE_2D:
1282 {
1283 struct gl_texture_object *tObj;
1284 tdfxTexInfo *ti;
1285 int memNeeded;
1286
1287 tObj = ctx->Texture.Proxy2D;
1288 if (!tObj->DriverData)
1289 tObj->DriverData = fxAllocTexObjData(fxMesa);
1290 ti = TDFX_TEXTURE_DATA(tObj);
1291
1292 /* assign the parameters to test against */
1293 tObj->Image[level]->Width = width;
1294 tObj->Image[level]->Height = height;
1295 tObj->Image[level]->Border = border;
1296 #if 0
1297 tObj->Image[level]->IntFormat = internalFormat;
1298 #endif
1299 if (level == 0) {
1300 /* don't use mipmap levels > 0 */
1301 tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
1302 }
1303 else {
1304 /* test with all mipmap levels */
1305 tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
1306 tObj->MagFilter = GL_NEAREST;
1307 }
1308 RevalidateTexture(ctx, tObj);
1309
1310 /*
1311 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1312 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1313 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1314 printf("glide format 0x%x\n", ti->info.format);
1315 printf("data %p\n", ti->info.data);
1316 printf("lodblend %d\n", (int) ti->LODblend);
1317 */
1318
1319 /* determine where texture will reside */
1320 if (ti->LODblend && !shared->umaTexMemory) {
1321 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1322 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1323 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1324 }
1325 else {
1326 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1327 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1328 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1329 }
1330 /*
1331 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1332 */
1333 if (memNeeded > shared->totalTexMem[0])
1334 return GL_FALSE;
1335 else
1336 return GL_TRUE;
1337 }
1338 case GL_PROXY_TEXTURE_3D:
1339 return GL_TRUE; /* software rendering */
1340 default:
1341 return GL_TRUE; /* never happens, silence compiler */
1342 }
1343 }
1344
1345
1346 #if 000
1347 /*
1348 * This is called from _mesa_GetCompressedTexImage. We just
1349 * copy out the compressed data.
1350 */
1351 void
1352 tdfxDDGetCompressedTexImage( GLcontext *ctx, GLenum target,
1353 GLint lod, void *image,
1354 const struct gl_texture_object *texObj,
1355 struct gl_texture_image *texImage )
1356 {
1357 tdfxTexInfo *ti;
1358 tdfxMipMapLevel *mml;
1359
1360 if (target != GL_TEXTURE_2D)
1361 return;
1362
1363 if (!texObj->DriverData)
1364 return;
1365
1366 ti = TDFX_TEXTURE_DATA(texObj);
1367 mml = &ti->mipmapLevel[lod];
1368 if (mml->data) {
1369 MEMCPY(image, mml->data, mml->dataSize);
1370 }
1371 }
1372 #endif
1373
1374 /*
1375 * Calculate a specific texture format given a generic
1376 * texture format.
1377 */
1378 GLint
1379 tdfxDDSpecificCompressedTexFormat(GLcontext *ctx,
1380 GLint internalFormat,
1381 GLint numDimensions)
1382 {
1383 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1384
1385 if (numDimensions != 2) {
1386 return internalFormat;
1387 }
1388 /*
1389 * If we don't have pointers to the functions, then
1390 * we drop back to uncompressed format. The logic
1391 * in Mesa proper handles this for us.
1392 *
1393 * This is just to ease the transition to a Glide with
1394 * the texus2 library.
1395 */
1396 if (!fxMesa->Glide.txImgQuantize || !fxMesa->Glide.txImgDequantizeFXT1) {
1397 return internalFormat;
1398 }
1399 switch (internalFormat) {
1400 case GL_COMPRESSED_RGB_ARB:
1401 return GL_COMPRESSED_RGB_FXT1_3DFX;
1402 case GL_COMPRESSED_RGBA_ARB:
1403 return GL_COMPRESSED_RGBA_FXT1_3DFX;
1404 }
1405 return internalFormat;
1406 }
1407
1408 /*
1409 * Calculate a specific texture format given a generic
1410 * texture format.
1411 */
1412 GLint
1413 tdfxDDBaseCompressedTexFormat(GLcontext *ctx,
1414 GLint internalFormat)
1415 {
1416 switch (internalFormat) {
1417 case GL_COMPRESSED_RGB_FXT1_3DFX:
1418 return GL_RGB;
1419 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1420 return GL_RGBA;
1421 }
1422 return -1;
1423 }
1424
1425 /*
1426 * Tell us if an image is compressed. The real work is done
1427 * in a macro, but we need to have a function to create a
1428 * function pointer.
1429 */
1430 GLboolean
1431 tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat)
1432 {
1433 return tdfxDDIsCompressedFormatMacro(internalFormat);
1434 }
1435
1436
1437 /*
1438 * Calculate the image size of a compressed texture.
1439 *
1440 * The current compressed format, the FXT1 family, all
1441 * map 8x32 texel blocks into 128 bits.
1442 *
1443 * We return 0 if we can't calculate the size.
1444 *
1445 * Glide would report this out to us, but we don't have
1446 * exactly the right parameters.
1447 */
1448 GLsizei
1449 tdfxDDCompressedImageSize(GLcontext *ctx,
1450 GLenum intFormat,
1451 GLuint numDimensions,
1452 GLuint width,
1453 GLuint height,
1454 GLuint depth)
1455 {
1456 if (numDimensions != 2) {
1457 return 0;
1458 }
1459 switch (intFormat) {
1460 case GL_COMPRESSED_RGB_FXT1_3DFX:
1461 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1462 /*
1463 * Round height and width to multiples of 4 and 8,
1464 * divide the resulting product by 32 to get the number
1465 * of blocks, and multiply by 32 = 128/8 to get the.
1466 * number of bytes required. That is to say, just
1467 * return the product. Remember that we are returning
1468 * bytes, not texels, so we have shrunk the texture
1469 * by a factor of the texel size.
1470 */
1471 width = (width + 0x7) &~ 0x7;
1472 height = (height + 0x3) &~ 0x3;
1473 return width * height;
1474 }
1475 return 0;
1476 }