fix assorted compilation issues
[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 static void
237 tdfxBindTexture(GLcontext * ctx, GLenum target,
238 struct gl_texture_object *tObj)
239 {
240 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
241 tdfxTexInfo *ti;
242
243 if (MESA_VERBOSE & VERBOSE_DRIVER) {
244 fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,
245 tObj->DriverData);
246 }
247
248 if (target != GL_TEXTURE_2D)
249 return;
250
251 if (!tObj->DriverData) {
252 tObj->DriverData = fxAllocTexObjData(fxMesa);
253 }
254
255 ti = TDFX_TEXTURE_DATA(tObj);
256 ti->lastTimeUsed = fxMesa->texBindNumber++;
257
258 fxMesa->new_state |= TDFX_NEW_TEXTURE;
259 }
260
261
262 /*
263 * Called via glTexEnv.
264 */
265 static void
266 tdfxTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
267 const GLfloat * param)
268 {
269 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
270
271 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
272 if (param)
273 fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,
274 (GLint) (*param));
275 else
276 fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
277 }
278
279 /* XXX this is a bit of a hack to force the Glide texture
280 * state to be updated.
281 */
282 fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit] = 0;
283
284 fxMesa->new_state |= TDFX_NEW_TEXTURE;
285 }
286
287
288 /*
289 * Called via glTexParameter.
290 */
291 static void
292 tdfxTexParameter(GLcontext * ctx, GLenum target,
293 struct gl_texture_object *tObj,
294 GLenum pname, const GLfloat * params)
295 {
296 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
297 GLenum param = (GLenum) (GLint) params[0];
298 tdfxTexInfo *ti;
299
300 if (MESA_VERBOSE & VERBOSE_DRIVER) {
301 fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,
302 tObj->DriverData, pname, param);
303 }
304
305 if (target != GL_TEXTURE_2D)
306 return;
307
308 if (!tObj->DriverData)
309 tObj->DriverData = fxAllocTexObjData(fxMesa);
310
311 ti = TDFX_TEXTURE_DATA(tObj);
312
313 switch (pname) {
314 case GL_TEXTURE_MIN_FILTER:
315 switch (param) {
316 case GL_NEAREST:
317 ti->mmMode = GR_MIPMAP_DISABLE;
318 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
319 ti->LODblend = FXFALSE;
320 break;
321 case GL_LINEAR:
322 ti->mmMode = GR_MIPMAP_DISABLE;
323 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
324 ti->LODblend = FXFALSE;
325 break;
326 case GL_NEAREST_MIPMAP_LINEAR:
327 if (TDFX_IS_NAPALM(fxMesa)) {
328 if (fxMesa->haveTwoTMUs) {
329 ti->mmMode = GR_MIPMAP_NEAREST;
330 ti->LODblend = FXTRUE;
331 }
332 else {
333 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
334 ti->LODblend = FXFALSE;
335 }
336 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
337 break;
338 }
339 /* XXX Voodoo3/Banshee mipmap blending seems to produce
340 * incorrectly filtered colors for the smallest mipmap levels.
341 * To work-around we fall-through here and use a different filter.
342 */
343 case GL_NEAREST_MIPMAP_NEAREST:
344 ti->mmMode = GR_MIPMAP_NEAREST;
345 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
346 ti->LODblend = FXFALSE;
347 break;
348 case GL_LINEAR_MIPMAP_LINEAR:
349 if (TDFX_IS_NAPALM(fxMesa)) {
350 if (fxMesa->haveTwoTMUs) {
351 ti->mmMode = GR_MIPMAP_NEAREST;
352 ti->LODblend = FXTRUE;
353 }
354 else {
355 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
356 ti->LODblend = FXFALSE;
357 }
358 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
359 break;
360 }
361 /* XXX Voodoo3/Banshee mipmap blending seems to produce
362 * incorrectly filtered colors for the smallest mipmap levels.
363 * To work-around we fall-through here and use a different filter.
364 */
365 case GL_LINEAR_MIPMAP_NEAREST:
366 ti->mmMode = GR_MIPMAP_NEAREST;
367 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
368 ti->LODblend = FXFALSE;
369 break;
370 default:
371 break;
372 }
373 RevalidateTexture(ctx, tObj);
374 fxMesa->new_state |= TDFX_NEW_TEXTURE;
375 break;
376
377 case GL_TEXTURE_MAG_FILTER:
378 switch (param) {
379 case GL_NEAREST:
380 ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
381 break;
382 case GL_LINEAR:
383 ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
384 break;
385 default:
386 break;
387 }
388 fxMesa->new_state |= TDFX_NEW_TEXTURE;
389 break;
390
391 case GL_TEXTURE_WRAP_S:
392 switch (param) {
393 case GL_CLAMP:
394 ti->sClamp = GR_TEXTURECLAMP_CLAMP;
395 break;
396 case GL_REPEAT:
397 ti->sClamp = GR_TEXTURECLAMP_WRAP;
398 break;
399 default:
400 break;
401 }
402 fxMesa->new_state |= TDFX_NEW_TEXTURE;
403 break;
404
405 case GL_TEXTURE_WRAP_T:
406 switch (param) {
407 case GL_CLAMP:
408 ti->tClamp = GR_TEXTURECLAMP_CLAMP;
409 break;
410 case GL_REPEAT:
411 ti->tClamp = GR_TEXTURECLAMP_WRAP;
412 break;
413 default:
414 break;
415 }
416 fxMesa->new_state |= TDFX_NEW_TEXTURE;
417 break;
418
419 case GL_TEXTURE_BORDER_COLOR:
420 /* TO DO */
421 break;
422 case GL_TEXTURE_MIN_LOD:
423 /* TO DO */
424 break;
425 case GL_TEXTURE_MAX_LOD:
426 /* TO DO */
427 break;
428 case GL_TEXTURE_BASE_LEVEL:
429 RevalidateTexture(ctx, tObj);
430 break;
431 case GL_TEXTURE_MAX_LEVEL:
432 RevalidateTexture(ctx, tObj);
433 break;
434
435 default:
436 break;
437 }
438 }
439
440
441 /*
442 * Called via glDeleteTextures to delete a texture object.
443 * Here, we delete the Glide data associated with the texture.
444 */
445 static void
446 tdfxDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj)
447 {
448 if (ctx && ctx->DriverCtx) {
449 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
450 tdfxTMFreeTexture(fxMesa, tObj);
451 fxMesa->new_state |= TDFX_NEW_TEXTURE;
452 /* Free mipmap images and the texture object itself */
453 _mesa_delete_texture_object(ctx, tObj);
454 }
455 }
456
457
458 /*
459 * Return true if texture is resident, false otherwise.
460 */
461 static GLboolean
462 tdfxIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj)
463 {
464 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
465 return (GLboolean) (ti && ti->isInTM);
466 }
467
468
469
470 /*
471 * Convert a gl_color_table texture palette to Glide's format.
472 */
473 static void
474 convertPalette(FxU32 data[256], const struct gl_color_table *table)
475 {
476 const GLubyte *tableUB = (const GLubyte *) table->Table;
477 GLint width = table->Size;
478 FxU32 r, g, b, a;
479 GLint i;
480
481 ASSERT(table->TableType == GL_UNSIGNED_BYTE);
482
483 switch (table->Format) {
484 case GL_INTENSITY:
485 for (i = 0; i < width; i++) {
486 r = tableUB[i];
487 g = tableUB[i];
488 b = tableUB[i];
489 a = tableUB[i];
490 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
491 }
492 break;
493 case GL_LUMINANCE:
494 for (i = 0; i < width; i++) {
495 r = tableUB[i];
496 g = tableUB[i];
497 b = tableUB[i];
498 a = 255;
499 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
500 }
501 break;
502 case GL_ALPHA:
503 for (i = 0; i < width; i++) {
504 r = g = b = 255;
505 a = tableUB[i];
506 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
507 }
508 break;
509 case GL_LUMINANCE_ALPHA:
510 for (i = 0; i < width; i++) {
511 r = g = b = tableUB[i * 2 + 0];
512 a = tableUB[i * 2 + 1];
513 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
514 }
515 break;
516 case GL_RGB:
517 for (i = 0; i < width; i++) {
518 r = tableUB[i * 3 + 0];
519 g = tableUB[i * 3 + 1];
520 b = tableUB[i * 3 + 2];
521 a = 255;
522 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
523 }
524 break;
525 case GL_RGBA:
526 for (i = 0; i < width; i++) {
527 r = tableUB[i * 4 + 0];
528 g = tableUB[i * 4 + 1];
529 b = tableUB[i * 4 + 2];
530 a = tableUB[i * 4 + 3];
531 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
532 }
533 break;
534 }
535 }
536
537
538
539 void
540 tdfxTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj)
541 {
542 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
543
544 if (tObj) {
545 /* per-texture palette */
546 tdfxTexInfo *ti;
547
548 /* This might be a proxy texture. */
549 if (!tObj->Palette.Table)
550 return;
551
552 if (!tObj->DriverData)
553 tObj->DriverData = fxAllocTexObjData(fxMesa);
554 ti = TDFX_TEXTURE_DATA(tObj);
555 assert(ti);
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 static const struct gl_texture_format *
591 tdfxChooseTextureFormat( 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 tdfxChooseTextureFormat");
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, GLchan * rgba)
709 {
710 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
711 const GLubyte *texel;
712
713 i = i * mml->wScale;
714 j = j * mml->hScale;
715
716 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
717 rgba[RCOMP] = *texel;
718 rgba[GCOMP] = *texel;
719 rgba[BCOMP] = *texel;
720 rgba[ACOMP] = *texel;
721 }
722
723
724 static void
725 fetch_luminance8(const struct gl_texture_image *texImage,
726 GLint i, GLint j, GLint k, GLchan * rgba)
727 {
728 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
729 const GLubyte *texel;
730
731 i = i * mml->wScale;
732 j = j * mml->hScale;
733
734 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
735 rgba[RCOMP] = *texel;
736 rgba[GCOMP] = *texel;
737 rgba[BCOMP] = *texel;
738 rgba[ACOMP] = 255;
739 }
740
741
742 static void
743 fetch_alpha8(const struct gl_texture_image *texImage,
744 GLint i, GLint j, GLint k, GLchan * rgba)
745 {
746 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
747 const GLubyte *texel;
748
749 i = i * mml->wScale;
750 j = j * mml->hScale;
751 i = i * mml->width / texImage->Width;
752 j = j * mml->height / texImage->Height;
753
754 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
755 rgba[RCOMP] = 255;
756 rgba[GCOMP] = 255;
757 rgba[BCOMP] = 255;
758 rgba[ACOMP] = *texel;
759 }
760
761
762 static void
763 fetch_index8(const struct gl_texture_image *texImage,
764 GLint i, GLint j, GLint k, GLchan * rgba)
765 {
766 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
767 (void) mml;
768 /* XXX todo */
769 }
770
771
772 static void
773 fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
774 GLint i, GLint j, GLint k, GLchan * rgba)
775 {
776 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
777 const GLubyte *texel;
778
779 i = i * mml->wScale;
780 j = j * mml->hScale;
781
782 texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2;
783 rgba[RCOMP] = texel[0];
784 rgba[GCOMP] = texel[0];
785 rgba[BCOMP] = texel[0];
786 rgba[ACOMP] = texel[1];
787 }
788
789
790 static void
791 fetch_r5g6b5(const struct gl_texture_image *texImage,
792 GLint i, GLint j, GLint k, GLchan * rgba)
793 {
794 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
795 const GLushort *texel;
796
797 i = i * mml->wScale;
798 j = j * mml->hScale;
799
800 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
801 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
802 rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63;
803 rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31;
804 rgba[ACOMP] = 255;
805 }
806
807
808 static void
809 fetch_r4g4b4a4(const struct gl_texture_image *texImage,
810 GLint i, GLint j, GLint k, GLchan * rgba)
811 {
812 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
813 const GLushort *texel;
814
815 i = i * mml->wScale;
816 j = j * mml->hScale;
817
818 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
819 rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15;
820 rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15;
821 rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15;
822 rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;
823 }
824
825
826 static void
827 fetch_r5g5b5a1(const struct gl_texture_image *texImage,
828 GLint i, GLint j, GLint k, GLchan * rgba)
829 {
830 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
831 const GLushort *texel;
832
833 i = i * mml->wScale;
834 j = j * mml->hScale;
835
836 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
837 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
838 rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31;
839 rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31;
840 rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;
841 }
842
843
844 static void
845 fetch_a8r8g8b8(const struct gl_texture_image *texImage,
846 GLint i, GLint j, GLint k, GLchan * rgba)
847 {
848 const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
849 const GLuint *texel;
850
851 i = i * mml->wScale;
852 j = j * mml->hScale;
853
854 texel = ((GLuint *) texImage->Data) + j * mml->width + i;
855 rgba[RCOMP] = (((*texel) >> 16) & 0xff);
856 rgba[GCOMP] = (((*texel) >> 8) & 0xff);
857 rgba[BCOMP] = (((*texel) ) & 0xff);
858 rgba[ACOMP] = (((*texel) >> 24) & 0xff);
859 }
860
861
862 static FetchTexelFuncC
863 fxFetchFunction(GLint mesaFormat)
864 {
865 switch (mesaFormat) {
866 case MESA_FORMAT_I8:
867 return fetch_intensity8;
868 case MESA_FORMAT_A8:
869 return fetch_alpha8;
870 case MESA_FORMAT_L8:
871 return fetch_luminance8;
872 case MESA_FORMAT_CI8:
873 return fetch_index8;
874 case MESA_FORMAT_AL88:
875 return fetch_luminance8_alpha8;
876 case MESA_FORMAT_RGB565:
877 return fetch_r5g6b5;
878 case MESA_FORMAT_ARGB4444:
879 return fetch_r4g4b4a4;
880 case MESA_FORMAT_ARGB1555:
881 return fetch_r5g5b5a1;
882 case MESA_FORMAT_ARGB8888:
883 return fetch_a8r8g8b8;
884 default:
885 _mesa_problem(NULL, "Unexpected format in fxFetchFunction");
886 printf("%d\n", mesaFormat);
887 return NULL;
888 }
889 }
890
891
892 static void
893 tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
894 GLint internalFormat, GLint width, GLint height, GLint border,
895 GLenum format, GLenum type, const GLvoid *pixels,
896 const struct gl_pixelstore_attrib *packing,
897 struct gl_texture_object *texObj,
898 struct gl_texture_image *texImage)
899 {
900 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
901 tdfxTexInfo *ti;
902 tdfxMipMapLevel *mml;
903 GLint texelBytes;
904
905 /*
906 printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n",
907 texObj->Name, texImage->IntFormat, format, type,
908 texImage->Width, texImage->Height);
909 */
910
911 ti = TDFX_TEXTURE_DATA(texObj);
912 if (!ti) {
913 texObj->DriverData = fxAllocTexObjData(fxMesa);
914 if (!texObj->DriverData) {
915 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
916 return;
917 }
918 ti = TDFX_TEXTURE_DATA(texObj);
919 }
920 assert(ti);
921
922 mml = TDFX_TEXIMAGE_DATA(texImage);
923 if (!mml) {
924 texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
925 if (!texImage->DriverData) {
926 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
927 return;
928 }
929 mml = TDFX_TEXIMAGE_DATA(texImage);
930 }
931
932 /* Determine width and height scale factors for texture.
933 * Remember, Glide is limited to 8:1 aspect ratios.
934 */
935 tdfxTexGetInfo(ctx,
936 texImage->Width, texImage->Height,
937 NULL, /* lod level */
938 NULL, /* aspect ratio */
939 NULL, NULL, /* sscale, tscale */
940 &mml->wScale, &mml->hScale);
941
942 /* rescaled size: */
943 mml->width = width * mml->wScale;
944 mml->height = height * mml->hScale;
945
946
947 /* choose the texture format */
948 assert(ctx->Driver.ChooseTextureFormat);
949 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
950 internalFormat, format, type);
951 assert(texImage->TexFormat);
952 mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat);
953 ti->info.format = mml->glideFormat;
954 texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat);
955 texelBytes = texImage->TexFormat->TexelBytes;
956
957 if (mml->width != width || mml->height != height) {
958 /* rescale the image to overcome 1:8 aspect limitation */
959 GLvoid *tempImage;
960 tempImage = MALLOC(width * height * texelBytes);
961 if (!tempImage) {
962 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
963 return;
964 }
965 /* unpack image, apply transfer ops and store in tempImage */
966 _mesa_transfer_teximage(ctx, 2, texImage->Format,
967 texImage->TexFormat,
968 tempImage,
969 width, height, 1, 0, 0, 0,
970 width * texelBytes,
971 0, /* dstImageStride */
972 format, type, pixels, packing);
973 assert(!texImage->Data);
974 texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
975 if (!texImage->Data) {
976 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
977 FREE(tempImage);
978 return;
979 }
980 _mesa_rescale_teximage2d(texelBytes,
981 mml->width * texelBytes, /* dst stride */
982 width, height,
983 mml->width, mml->height,
984 tempImage /*src*/, texImage->Data /*dst*/ );
985 FREE(tempImage);
986 }
987 else {
988 /* no rescaling needed */
989 assert(!texImage->Data);
990 texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
991 if (!texImage->Data) {
992 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
993 return;
994 }
995 /* unpack image, apply transfer ops and store in texImage->Data */
996 _mesa_transfer_teximage(ctx, 2, texImage->Format,
997 texImage->TexFormat, texImage->Data,
998 width, height, 1, 0, 0, 0,
999 texImage->Width * texelBytes,
1000 0, /* dstImageStride */
1001 format, type, pixels, packing);
1002 }
1003
1004 RevalidateTexture(ctx, texObj);
1005
1006 ti->reloadImages = GL_TRUE;
1007 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1008 }
1009
1010
1011 static void
1012 tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
1013 GLint xoffset, GLint yoffset,
1014 GLsizei width, GLsizei height,
1015 GLenum format, GLenum type,
1016 const GLvoid *pixels,
1017 const struct gl_pixelstore_attrib *packing,
1018 struct gl_texture_object *texObj,
1019 struct gl_texture_image *texImage )
1020 {
1021 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1022 tdfxTexInfo *ti;
1023 tdfxMipMapLevel *mml;
1024 GLint texelBytes;
1025
1026 if (!texObj->DriverData) {
1027 _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
1028 return;
1029 }
1030
1031 ti = TDFX_TEXTURE_DATA(texObj);
1032 assert(ti);
1033 mml = TDFX_TEXIMAGE_DATA(texImage);
1034 assert(mml);
1035
1036 assert(texImage->Data); /* must have an existing texture image! */
1037 assert(texImage->Format);
1038
1039 texelBytes = texImage->TexFormat->TexelBytes;
1040
1041 if (mml->wScale != 1 || mml->hScale != 1) {
1042 /* need to rescale subimage to match mipmap level's rescale factors */
1043 const GLint newWidth = width * mml->wScale;
1044 const GLint newHeight = height * mml->hScale;
1045 GLvoid *scaledImage, *tempImage;
1046 GLubyte *destAddr;
1047 tempImage = MALLOC(width * height * texelBytes);
1048 if (!tempImage) {
1049 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1050 return;
1051 }
1052
1053 _mesa_transfer_teximage(ctx, 2, texImage->Format,/* Tex int format */
1054 texImage->TexFormat, /* dest format */
1055 (GLubyte *) tempImage, /* dest */
1056 width, height, 1, /* subimage size */
1057 0, 0, 0, /* subimage pos */
1058 width * texelBytes, /* dest row stride */
1059 0, /* dst image stride */
1060 format, type, pixels, packing);
1061
1062 /* now rescale */
1063 scaledImage = MALLOC(newWidth * newHeight * texelBytes);
1064 if (!scaledImage) {
1065 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1066 FREE(tempImage);
1067 return;
1068 }
1069
1070 /* compute address of dest subimage within the overal tex image */
1071 destAddr = (GLubyte *) texImage->Data
1072 + (yoffset * mml->hScale * mml->width
1073 + xoffset * mml->wScale) * texelBytes;
1074
1075 _mesa_rescale_teximage2d(texelBytes,
1076 mml->width * texelBytes, /* dst stride */
1077 width, height,
1078 newWidth, newHeight,
1079 tempImage, destAddr);
1080
1081 FREE(tempImage);
1082 FREE(scaledImage);
1083 }
1084 else {
1085 /* no rescaling needed */
1086 _mesa_transfer_teximage(ctx, 2, texImage->Format, /* Tex int format */
1087 texImage->TexFormat, /* dest format */
1088 (GLubyte *) texImage->Data,/* dest */
1089 width, height, 1, /* subimage size */
1090 xoffset, yoffset, 0, /* subimage pos */
1091 mml->width * texelBytes, /* dest row stride */
1092 0, /* dst image stride */
1093 format, type, pixels, packing);
1094 }
1095
1096 ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
1097 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
1098 }
1099
1100
1101
1102 /**********************************************************************/
1103 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1104 /**********************************************************************/
1105
1106 #if 0000
1107 GLboolean
1108 tdfxCompressedTexImage2D( GLcontext *ctx, GLenum target,
1109 GLint level, GLsizei imageSize,
1110 const GLvoid *data,
1111 struct gl_texture_object *texObj,
1112 struct gl_texture_image *texImage,
1113 GLboolean *retainInternalCopy)
1114 {
1115 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1116 const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
1117 GrTextureFormat_t gldformat;
1118 tdfxTexInfo *ti;
1119 tdfxMipMapLevel *mml;
1120 GLint dstWidth, dstHeight, wScale, hScale, texelSize;
1121 MesaIntTexFormat intFormat;
1122 GLboolean isCompressedFormat;
1123 GLsizei texSize;
1124
1125 if (target != GL_TEXTURE_2D || texImage->Border > 0)
1126 return GL_FALSE;
1127
1128 ti = TDFX_TEXTURE_DATA(texObj);
1129 assert(ti);
1130 mml = &ti->mipmapLevel[level];
1131
1132 isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat);
1133 if (!isCompressedFormat) {
1134 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)");
1135 return GL_FALSE;
1136 }
1137 /* Determine the apporpriate GL internal texel format, Mesa internal
1138 * texel format, and texelSize (bytes) given the user's internal
1139 * texture format hint.
1140 */
1141 tdfxTexGetFormat(texImage->IntFormat, allow32bpt,
1142 &gldformat, &intFormat, &texelSize);
1143
1144 /* Determine width and height scale factors for texture.
1145 * Remember, Glide is limited to 8:1 aspect ratios.
1146 */
1147 tdfxTexGetInfo(ctx,
1148 texImage->Width, texImage->Height,
1149 NULL, /* lod level */
1150 NULL, /* aspect ratio */
1151 NULL, NULL, /* sscale, tscale */
1152 &wScale, &hScale);
1153 dstWidth = texImage->Width * wScale;
1154 dstHeight = texImage->Height * hScale;
1155 /* housekeeping */
1156 _mesa_set_teximage_component_sizes(intFormat, texImage);
1157
1158 texSize = tdfxDDCompressedImageSize(ctx,
1159 texImage->IntFormat,
1160 2,
1161 texImage->Width,
1162 texImage->Height,
1163 1);
1164 if (texSize != imageSize) {
1165 _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2D(texSize)");
1166 return GL_FALSE;
1167 }
1168
1169 /* allocate new storage for texture image, if needed */
1170 if (!mml->data || mml->glideFormat != gldformat ||
1171 mml->width != dstWidth || mml->height != dstHeight ||
1172 texSize != mml->dataSize) {
1173 if (mml->data) {
1174 FREE(mml->data);
1175 }
1176 mml->data = MALLOC(texSize);
1177 if (!mml->data) {
1178 return GL_FALSE;
1179 }
1180 mml->texelSize = texelSize;
1181 mml->glideFormat = gldformat;
1182 mml->width = dstWidth;
1183 mml->height = dstHeight;
1184 tdfxTMMoveOutTM(fxMesa, texObj);
1185 /*tdfxTexInvalidate(ctx, texObj);*/
1186 }
1187
1188 /* save the texture data */
1189 MEMCPY(mml->data, data, imageSize);
1190
1191 RevalidateTexture(ctx, texObj);
1192
1193 ti->reloadImages = GL_TRUE;
1194 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1195
1196 *retainInternalCopy = GL_FALSE;
1197 return GL_TRUE;
1198 }
1199
1200 GLboolean
1201 tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
1202 GLint level, GLint xoffset,
1203 GLint yoffset, GLsizei width,
1204 GLint height, GLenum format,
1205 GLsizei imageSize, const GLvoid *data,
1206 struct gl_texture_object *texObj,
1207 struct gl_texture_image *texImage )
1208 {
1209 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1210 tdfxTexInfo *ti;
1211 tdfxMipMapLevel *mml;
1212
1213 /*
1214 * We punt if we are not replacing the entire image. This
1215 * is allowed by the spec.
1216 */
1217 if ((xoffset != 0) && (yoffset != 0)
1218 && (width != texImage->Width)
1219 && (height != texImage->Height)) {
1220 return GL_FALSE;
1221 }
1222
1223 ti = TDFX_TEXTURE_DATA(texObj);
1224 mml = &ti->mipmapLevel[level];
1225 if (imageSize != mml->dataSize) {
1226 return GL_FALSE;
1227 }
1228 MEMCPY(data, mml->data, imageSize);
1229
1230 ti->reloadImages = GL_TRUE;
1231 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1232
1233 return GL_TRUE;
1234 }
1235 #endif
1236
1237
1238
1239 #if 0
1240 static void
1241 PrintTexture(int w, int h, int c, const GLubyte * data)
1242 {
1243 int i, j;
1244 for (i = 0; i < h; i++) {
1245 for (j = 0; j < w; j++) {
1246 if (c == 2)
1247 printf("%02x %02x ", data[0], data[1]);
1248 else if (c == 3)
1249 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1250 data += c;
1251 }
1252 printf("\n");
1253 }
1254 }
1255 #endif
1256
1257
1258 GLboolean
1259 tdfxTestProxyTexImage(GLcontext *ctx, GLenum target,
1260 GLint level, GLint internalFormat,
1261 GLenum format, GLenum type,
1262 GLint width, GLint height,
1263 GLint depth, GLint border)
1264 {
1265 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1266 struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
1267 struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
1268
1269 switch (target) {
1270 case GL_PROXY_TEXTURE_1D:
1271 return GL_TRUE; /* software rendering */
1272 case GL_PROXY_TEXTURE_2D:
1273 {
1274 struct gl_texture_object *tObj;
1275 tdfxTexInfo *ti;
1276 int memNeeded;
1277
1278 tObj = ctx->Texture.Proxy2D;
1279 if (!tObj->DriverData)
1280 tObj->DriverData = fxAllocTexObjData(fxMesa);
1281 ti = TDFX_TEXTURE_DATA(tObj);
1282 assert(ti);
1283
1284 /* assign the parameters to test against */
1285 tObj->Image[level]->Width = width;
1286 tObj->Image[level]->Height = height;
1287 tObj->Image[level]->Border = border;
1288 #if 0
1289 tObj->Image[level]->IntFormat = internalFormat;
1290 #endif
1291 if (level == 0) {
1292 /* don't use mipmap levels > 0 */
1293 tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
1294 }
1295 else {
1296 /* test with all mipmap levels */
1297 tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
1298 tObj->MagFilter = GL_NEAREST;
1299 }
1300 RevalidateTexture(ctx, tObj);
1301
1302 /*
1303 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1304 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1305 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1306 printf("glide format 0x%x\n", ti->info.format);
1307 printf("data %p\n", ti->info.data);
1308 printf("lodblend %d\n", (int) ti->LODblend);
1309 */
1310
1311 /* determine where texture will reside */
1312 if (ti->LODblend && !shared->umaTexMemory) {
1313 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1314 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1315 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1316 }
1317 else {
1318 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1319 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1320 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1321 }
1322 /*
1323 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1324 */
1325 if (memNeeded > shared->totalTexMem[0])
1326 return GL_FALSE;
1327 else
1328 return GL_TRUE;
1329 }
1330 case GL_PROXY_TEXTURE_3D:
1331 return GL_TRUE; /* software rendering */
1332 default:
1333 return GL_TRUE; /* never happens, silence compiler */
1334 }
1335 }
1336
1337
1338 #if 000
1339 /*
1340 * This is called from _mesa_GetCompressedTexImage. We just
1341 * copy out the compressed data.
1342 */
1343 void
1344 tdfxGetCompressedTexImage( GLcontext *ctx, GLenum target,
1345 GLint lod, void *image,
1346 const struct gl_texture_object *texObj,
1347 struct gl_texture_image *texImage )
1348 {
1349 tdfxTexInfo *ti;
1350 tdfxMipMapLevel *mml;
1351
1352 if (target != GL_TEXTURE_2D)
1353 return;
1354
1355 if (!texObj->DriverData)
1356 return;
1357
1358 ti = TDFX_TEXTURE_DATA(texObj);
1359 assert(ti);
1360 mml = &ti->mipmapLevel[lod];
1361 if (mml->data) {
1362 MEMCPY(image, mml->data, mml->dataSize);
1363 }
1364 }
1365 #endif
1366
1367 /*
1368 * Calculate a specific texture format given a generic
1369 * texture format.
1370 */
1371 GLint
1372 tdfxSpecificCompressedTexFormat(GLcontext *ctx,
1373 GLint internalFormat,
1374 GLint numDimensions)
1375 {
1376 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1377
1378 if (numDimensions != 2) {
1379 return internalFormat;
1380 }
1381 /*
1382 * If we don't have pointers to the functions, then
1383 * we drop back to uncompressed format. The logic
1384 * in Mesa proper handles this for us.
1385 *
1386 * This is just to ease the transition to a Glide with
1387 * the texus2 library.
1388 */
1389 if (!fxMesa->Glide.txImgQuantize || !fxMesa->Glide.txImgDequantizeFXT1) {
1390 return internalFormat;
1391 }
1392 switch (internalFormat) {
1393 case GL_COMPRESSED_RGB_ARB:
1394 return GL_COMPRESSED_RGB_FXT1_3DFX;
1395 case GL_COMPRESSED_RGBA_ARB:
1396 return GL_COMPRESSED_RGBA_FXT1_3DFX;
1397 }
1398 return internalFormat;
1399 }
1400
1401 /*
1402 * Calculate a specific texture format given a generic
1403 * texture format.
1404 */
1405 GLint
1406 tdfxBaseCompressedTexFormat(GLcontext *ctx,
1407 GLint internalFormat)
1408 {
1409 switch (internalFormat) {
1410 case GL_COMPRESSED_RGB_FXT1_3DFX:
1411 return GL_RGB;
1412 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1413 return GL_RGBA;
1414 }
1415 return -1;
1416 }
1417
1418 /*
1419 * Tell us if an image is compressed. The real work is done
1420 * in a macro, but we need to have a function to create a
1421 * function pointer.
1422 */
1423 GLboolean
1424 tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat)
1425 {
1426 return tdfxDDIsCompressedFormatMacro(internalFormat);
1427 }
1428
1429
1430 /*
1431 * Calculate the image size of a compressed texture.
1432 *
1433 * The current compressed format, the FXT1 family, all
1434 * map 8x32 texel blocks into 128 bits.
1435 *
1436 * We return 0 if we can't calculate the size.
1437 *
1438 * Glide would report this out to us, but we don't have
1439 * exactly the right parameters.
1440 */
1441 GLsizei
1442 tdfxDDCompressedImageSize(GLcontext *ctx,
1443 GLenum intFormat,
1444 GLuint numDimensions,
1445 GLuint width,
1446 GLuint height,
1447 GLuint depth)
1448 {
1449 if (numDimensions != 2) {
1450 return 0;
1451 }
1452 switch (intFormat) {
1453 case GL_COMPRESSED_RGB_FXT1_3DFX:
1454 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1455 /*
1456 * Round height and width to multiples of 4 and 8,
1457 * divide the resulting product by 32 to get the number
1458 * of blocks, and multiply by 32 = 128/8 to get the.
1459 * number of bytes required. That is to say, just
1460 * return the product. Remember that we are returning
1461 * bytes, not texels, so we have shrunk the texture
1462 * by a factor of the texel size.
1463 */
1464 width = (width + 0x7) &~ 0x7;
1465 height = (height + 0x3) &~ 0x3;
1466 return width * height;
1467 }
1468 return 0;
1469 }
1470
1471
1472
1473 /**
1474 * Allocate a new texture object.
1475 * Called via ctx->Driver.NewTextureObject.
1476 * Note: this function will be called during context creation to
1477 * allocate the default texture objects.
1478 * Note: we could use containment here to 'derive' the driver-specific
1479 * texture object from the core mesa gl_texture_object. Not done at this time.
1480 */
1481 static struct gl_texture_object *
1482 tdfxNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
1483 {
1484 struct gl_texture_object *obj;
1485 obj = _mesa_new_texture_object(ctx, name, target);
1486 return obj;
1487 }
1488
1489
1490 void tdfxInitTextureFuncs( struct dd_function_table *functions )
1491 {
1492 functions->BindTexture = tdfxBindTexture;
1493 functions->NewTextureObject = tdfxNewTextureObject;
1494 functions->DeleteTexture = tdfxDeleteTexture;
1495 functions->TexEnv = tdfxTexEnv;
1496 functions->TexParameter = tdfxTexParameter;
1497 functions->ChooseTextureFormat = tdfxChooseTextureFormat;
1498 functions->TexImage2D = tdfxTexImage2D;
1499 functions->TexSubImage2D = tdfxTexSubImage2D;
1500 functions->IsTextureResident = tdfxIsTextureResident;
1501 functions->UpdateTexturePalette = tdfxTexturePalette;
1502 }
1503