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