fix bracket at wrong place
[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[0][minl]) {
175 maxl = MIN2(tObj->MaxLevel, tObj->Image[0][minl]->MaxLog2);
176
177 /* compute largeLodLog2, aspect ratio and texcoord scale factors */
178 tdfxTexGetInfo(ctx, tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,
179 &ti->info.largeLodLog2,
180 &ti->info.aspectRatioLog2,
181 &(ti->sScale), &(ti->tScale), NULL, NULL);
182 }
183
184 if (tObj->Image[0][maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
185 /* mipmapping: need to compute smallLodLog2 */
186 tdfxTexGetInfo(ctx, tObj->Image[0][maxl]->Width,
187 tObj->Image[0][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 static void
540 tdfxUpdateTexturePalette(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 #if !NEWTEXSTORE
967 _mesa_transfer_teximage(ctx, 2, texImage->Format,
968 texImage->TexFormat,
969 tempImage,
970 width, height, 1, 0, 0, 0,
971 width * texelBytes,
972 0, /* dstImageStride */
973 format, type, pixels, packing);
974 #else
975 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
976 texImage->Format, tempImage,
977 0, 0, 0, /* dstX/Y/Zoffset */
978 width * texelBytes, /* dstRowStride */
979 0, /* dstImageStride */
980 width, height, 1,
981 format, type, pixels, packing);
982 #endif
983 assert(!texImage->Data);
984 texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
985 if (!texImage->Data) {
986 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
987 FREE(tempImage);
988 return;
989 }
990 _mesa_rescale_teximage2d(texelBytes,
991 mml->width * texelBytes, /* dst stride */
992 width, height,
993 mml->width, mml->height,
994 tempImage /*src*/, texImage->Data /*dst*/ );
995 FREE(tempImage);
996 }
997 else {
998 /* no rescaling needed */
999 assert(!texImage->Data);
1000 texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes);
1001 if (!texImage->Data) {
1002 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1003 return;
1004 }
1005 /* unpack image, apply transfer ops and store in texImage->Data */
1006 #if !NEWTEXSTORE
1007 _mesa_transfer_teximage(ctx, 2, texImage->Format,
1008 texImage->TexFormat, texImage->Data,
1009 width, height, 1, 0, 0, 0,
1010 texImage->Width * texelBytes,
1011 0, /* dstImageStride */
1012 format, type, pixels, packing);
1013 #else
1014 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1015 texImage->Format, texImage->Data,
1016 0, 0, 0, /* dstX/Y/Zoffset */
1017 width * texelBytes, /* dstRowStride */
1018 0, /* dstImageStride */
1019 width, height, 1,
1020 format, type, pixels, packing);
1021 #endif
1022 }
1023
1024 RevalidateTexture(ctx, texObj);
1025
1026 ti->reloadImages = GL_TRUE;
1027 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1028 }
1029
1030
1031 static void
1032 tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
1033 GLint xoffset, GLint yoffset,
1034 GLsizei width, GLsizei height,
1035 GLenum format, GLenum type,
1036 const GLvoid *pixels,
1037 const struct gl_pixelstore_attrib *packing,
1038 struct gl_texture_object *texObj,
1039 struct gl_texture_image *texImage )
1040 {
1041 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1042 tdfxTexInfo *ti;
1043 tdfxMipMapLevel *mml;
1044 GLint texelBytes;
1045
1046 if (!texObj->DriverData) {
1047 _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
1048 return;
1049 }
1050
1051 ti = TDFX_TEXTURE_DATA(texObj);
1052 assert(ti);
1053 mml = TDFX_TEXIMAGE_DATA(texImage);
1054 assert(mml);
1055
1056 assert(texImage->Data); /* must have an existing texture image! */
1057 assert(texImage->Format);
1058
1059 texelBytes = texImage->TexFormat->TexelBytes;
1060
1061 if (mml->wScale != 1 || mml->hScale != 1) {
1062 /* need to rescale subimage to match mipmap level's rescale factors */
1063 const GLint newWidth = width * mml->wScale;
1064 const GLint newHeight = height * mml->hScale;
1065 GLvoid *scaledImage, *tempImage;
1066 GLubyte *destAddr;
1067 tempImage = MALLOC(width * height * texelBytes);
1068 if (!tempImage) {
1069 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1070 return;
1071 }
1072
1073 #if !NEWTEXSTORE
1074 _mesa_transfer_teximage(ctx, 2, texImage->Format,/* Tex int format */
1075 texImage->TexFormat, /* dest format */
1076 (GLubyte *) tempImage, /* dest */
1077 width, height, 1, /* subimage size */
1078 0, 0, 0, /* subimage pos */
1079 width * texelBytes, /* dest row stride */
1080 0, /* dst image stride */
1081 format, type, pixels, packing);
1082 #else
1083 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1084 texImage->Format, texImage->Data,
1085 0, 0, 0, /* dstX/Y/Zoffset */
1086 width * texelBytes, /* dstRowStride */
1087 0, /* dstImageStride */
1088 width, height, 1,
1089 format, type, pixels, packing);
1090 #endif
1091
1092 /* now rescale */
1093 scaledImage = MALLOC(newWidth * newHeight * texelBytes);
1094 if (!scaledImage) {
1095 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1096 FREE(tempImage);
1097 return;
1098 }
1099
1100 /* compute address of dest subimage within the overal tex image */
1101 destAddr = (GLubyte *) texImage->Data
1102 + (yoffset * mml->hScale * mml->width
1103 + xoffset * mml->wScale) * texelBytes;
1104
1105 _mesa_rescale_teximage2d(texelBytes,
1106 mml->width * texelBytes, /* dst stride */
1107 width, height,
1108 newWidth, newHeight,
1109 tempImage, destAddr);
1110
1111 FREE(tempImage);
1112 FREE(scaledImage);
1113 }
1114 else {
1115 /* no rescaling needed */
1116 #if !NEWTEXSTORE
1117 _mesa_transfer_teximage(ctx, 2, texImage->Format, /* Tex int format */
1118 texImage->TexFormat, /* dest format */
1119 (GLubyte *) texImage->Data,/* dest */
1120 width, height, 1, /* subimage size */
1121 xoffset, yoffset, 0, /* subimage pos */
1122 mml->width * texelBytes, /* dest row stride */
1123 0, /* dst image stride */
1124 format, type, pixels, packing);
1125 #else
1126 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1127 texImage->Format, texImage->Data,
1128 xoffset, yoffset, 0,
1129 mml->width * texelBytes, /* dstRowStride */
1130 0, /* dstImageStride */
1131 width, height, 1,
1132 format, type, pixels, packing);
1133 #endif
1134 }
1135
1136 ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
1137 fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
1138 }
1139
1140
1141
1142 /**********************************************************************/
1143 /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/
1144 /**********************************************************************/
1145
1146 #if 0000
1147 GLboolean
1148 tdfxCompressedTexImage2D( GLcontext *ctx, GLenum target,
1149 GLint level, GLsizei imageSize,
1150 const GLvoid *data,
1151 struct gl_texture_object *texObj,
1152 struct gl_texture_image *texImage,
1153 GLboolean *retainInternalCopy)
1154 {
1155 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1156 const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);
1157 GrTextureFormat_t gldformat;
1158 tdfxTexInfo *ti;
1159 tdfxMipMapLevel *mml;
1160 GLint dstWidth, dstHeight, wScale, hScale, texelSize;
1161 MesaIntTexFormat intFormat;
1162 GLboolean isCompressedFormat;
1163 GLsizei texSize;
1164
1165 if (target != GL_TEXTURE_2D || texImage->Border > 0)
1166 return GL_FALSE;
1167
1168 ti = TDFX_TEXTURE_DATA(texObj);
1169 assert(ti);
1170 mml = &ti->mipmapLevel[level];
1171
1172 isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat);
1173 if (!isCompressedFormat) {
1174 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)");
1175 return GL_FALSE;
1176 }
1177 /* Determine the apporpriate GL internal texel format, Mesa internal
1178 * texel format, and texelSize (bytes) given the user's internal
1179 * texture format hint.
1180 */
1181 tdfxTexGetFormat(texImage->IntFormat, allow32bpt,
1182 &gldformat, &intFormat, &texelSize);
1183
1184 /* Determine width and height scale factors for texture.
1185 * Remember, Glide is limited to 8:1 aspect ratios.
1186 */
1187 tdfxTexGetInfo(ctx,
1188 texImage->Width, texImage->Height,
1189 NULL, /* lod level */
1190 NULL, /* aspect ratio */
1191 NULL, NULL, /* sscale, tscale */
1192 &wScale, &hScale);
1193 dstWidth = texImage->Width * wScale;
1194 dstHeight = texImage->Height * hScale;
1195 /* housekeeping */
1196 _mesa_set_teximage_component_sizes(intFormat, texImage);
1197
1198 texSize = tdfxDDCompressedImageSize(ctx,
1199 texImage->IntFormat,
1200 2,
1201 texImage->Width,
1202 texImage->Height,
1203 1);
1204 if (texSize != imageSize) {
1205 _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2D(texSize)");
1206 return GL_FALSE;
1207 }
1208
1209 /* allocate new storage for texture image, if needed */
1210 if (!mml->data || mml->glideFormat != gldformat ||
1211 mml->width != dstWidth || mml->height != dstHeight ||
1212 texSize != mml->dataSize) {
1213 if (mml->data) {
1214 FREE(mml->data);
1215 }
1216 mml->data = MALLOC(texSize);
1217 if (!mml->data) {
1218 return GL_FALSE;
1219 }
1220 mml->texelSize = texelSize;
1221 mml->glideFormat = gldformat;
1222 mml->width = dstWidth;
1223 mml->height = dstHeight;
1224 tdfxTMMoveOutTM(fxMesa, texObj);
1225 /*tdfxTexInvalidate(ctx, texObj);*/
1226 }
1227
1228 /* save the texture data */
1229 MEMCPY(mml->data, data, imageSize);
1230
1231 RevalidateTexture(ctx, texObj);
1232
1233 ti->reloadImages = GL_TRUE;
1234 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1235
1236 *retainInternalCopy = GL_FALSE;
1237 return GL_TRUE;
1238 }
1239
1240 GLboolean
1241 tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
1242 GLint level, GLint xoffset,
1243 GLint yoffset, GLsizei width,
1244 GLint height, GLenum format,
1245 GLsizei imageSize, const GLvoid *data,
1246 struct gl_texture_object *texObj,
1247 struct gl_texture_image *texImage )
1248 {
1249 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1250 tdfxTexInfo *ti;
1251 tdfxMipMapLevel *mml;
1252
1253 /*
1254 * We punt if we are not replacing the entire image. This
1255 * is allowed by the spec.
1256 */
1257 if ((xoffset != 0) && (yoffset != 0)
1258 && (width != texImage->Width)
1259 && (height != texImage->Height)) {
1260 return GL_FALSE;
1261 }
1262
1263 ti = TDFX_TEXTURE_DATA(texObj);
1264 mml = &ti->mipmapLevel[level];
1265 if (imageSize != mml->dataSize) {
1266 return GL_FALSE;
1267 }
1268 MEMCPY(data, mml->data, imageSize);
1269
1270 ti->reloadImages = GL_TRUE;
1271 fxMesa->new_state |= TDFX_NEW_TEXTURE;
1272
1273 return GL_TRUE;
1274 }
1275 #endif
1276
1277
1278
1279 #if 0
1280 static void
1281 PrintTexture(int w, int h, int c, const GLubyte * data)
1282 {
1283 int i, j;
1284 for (i = 0; i < h; i++) {
1285 for (j = 0; j < w; j++) {
1286 if (c == 2)
1287 printf("%02x %02x ", data[0], data[1]);
1288 else if (c == 3)
1289 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1290 data += c;
1291 }
1292 printf("\n");
1293 }
1294 }
1295 #endif
1296
1297
1298 GLboolean
1299 tdfxTestProxyTexImage(GLcontext *ctx, GLenum target,
1300 GLint level, GLint internalFormat,
1301 GLenum format, GLenum type,
1302 GLint width, GLint height,
1303 GLint depth, GLint border)
1304 {
1305 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1306 struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
1307 struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;
1308
1309 switch (target) {
1310 case GL_PROXY_TEXTURE_1D:
1311 return GL_TRUE; /* software rendering */
1312 case GL_PROXY_TEXTURE_2D:
1313 {
1314 struct gl_texture_object *tObj;
1315 tdfxTexInfo *ti;
1316 int memNeeded;
1317
1318 tObj = ctx->Texture.Proxy2D;
1319 if (!tObj->DriverData)
1320 tObj->DriverData = fxAllocTexObjData(fxMesa);
1321 ti = TDFX_TEXTURE_DATA(tObj);
1322 assert(ti);
1323
1324 /* assign the parameters to test against */
1325 tObj->Image[0][level]->Width = width;
1326 tObj->Image[0][level]->Height = height;
1327 tObj->Image[0][level]->Border = border;
1328 #if 0
1329 tObj->Image[0][level]->IntFormat = internalFormat;
1330 #endif
1331 if (level == 0) {
1332 /* don't use mipmap levels > 0 */
1333 tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
1334 }
1335 else {
1336 /* test with all mipmap levels */
1337 tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
1338 tObj->MagFilter = GL_NEAREST;
1339 }
1340 RevalidateTexture(ctx, tObj);
1341
1342 /*
1343 printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
1344 printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
1345 printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
1346 printf("glide format 0x%x\n", ti->info.format);
1347 printf("data %p\n", ti->info.data);
1348 printf("lodblend %d\n", (int) ti->LODblend);
1349 */
1350
1351 /* determine where texture will reside */
1352 if (ti->LODblend && !shared->umaTexMemory) {
1353 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1354 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1355 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1356 }
1357 else {
1358 /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
1359 memNeeded = fxMesa->Glide.grTexTextureMemRequired(
1360 GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
1361 }
1362 /*
1363 printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
1364 */
1365 if (memNeeded > shared->totalTexMem[0])
1366 return GL_FALSE;
1367 else
1368 return GL_TRUE;
1369 }
1370 case GL_PROXY_TEXTURE_3D:
1371 return GL_TRUE; /* software rendering */
1372 default:
1373 return GL_TRUE; /* never happens, silence compiler */
1374 }
1375 }
1376
1377
1378 #if 000
1379 /*
1380 * This is called from _mesa_GetCompressedTexImage. We just
1381 * copy out the compressed data.
1382 */
1383 void
1384 tdfxGetCompressedTexImage( GLcontext *ctx, GLenum target,
1385 GLint lod, void *image,
1386 const struct gl_texture_object *texObj,
1387 struct gl_texture_image *texImage )
1388 {
1389 tdfxTexInfo *ti;
1390 tdfxMipMapLevel *mml;
1391
1392 if (target != GL_TEXTURE_2D)
1393 return;
1394
1395 if (!texObj->DriverData)
1396 return;
1397
1398 ti = TDFX_TEXTURE_DATA(texObj);
1399 assert(ti);
1400 mml = &ti->mipmapLevel[lod];
1401 if (mml->data) {
1402 MEMCPY(image, mml->data, mml->dataSize);
1403 }
1404 }
1405 #endif
1406
1407 /*
1408 * Calculate a specific texture format given a generic
1409 * texture format.
1410 */
1411 GLint
1412 tdfxSpecificCompressedTexFormat(GLcontext *ctx,
1413 GLint internalFormat,
1414 GLint numDimensions)
1415 {
1416 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1417
1418 if (numDimensions != 2) {
1419 return internalFormat;
1420 }
1421 /*
1422 * If we don't have pointers to the functions, then
1423 * we drop back to uncompressed format. The logic
1424 * in Mesa proper handles this for us.
1425 *
1426 * This is just to ease the transition to a Glide with
1427 * the texus2 library.
1428 */
1429 if (!fxMesa->Glide.txImgQuantize || !fxMesa->Glide.txImgDequantizeFXT1) {
1430 return internalFormat;
1431 }
1432 switch (internalFormat) {
1433 case GL_COMPRESSED_RGB_ARB:
1434 return GL_COMPRESSED_RGB_FXT1_3DFX;
1435 case GL_COMPRESSED_RGBA_ARB:
1436 return GL_COMPRESSED_RGBA_FXT1_3DFX;
1437 }
1438 return internalFormat;
1439 }
1440
1441 /*
1442 * Calculate a specific texture format given a generic
1443 * texture format.
1444 */
1445 GLint
1446 tdfxBaseCompressedTexFormat(GLcontext *ctx,
1447 GLint internalFormat)
1448 {
1449 switch (internalFormat) {
1450 case GL_COMPRESSED_RGB_FXT1_3DFX:
1451 return GL_RGB;
1452 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1453 return GL_RGBA;
1454 }
1455 return -1;
1456 }
1457
1458 /*
1459 * Tell us if an image is compressed. The real work is done
1460 * in a macro, but we need to have a function to create a
1461 * function pointer.
1462 */
1463 GLboolean
1464 tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat)
1465 {
1466 return tdfxDDIsCompressedFormatMacro(internalFormat);
1467 }
1468
1469
1470 /*
1471 * Calculate the image size of a compressed texture.
1472 *
1473 * The current compressed format, the FXT1 family, all
1474 * map 8x32 texel blocks into 128 bits.
1475 *
1476 * We return 0 if we can't calculate the size.
1477 *
1478 * Glide would report this out to us, but we don't have
1479 * exactly the right parameters.
1480 */
1481 GLsizei
1482 tdfxDDCompressedImageSize(GLcontext *ctx,
1483 GLenum intFormat,
1484 GLuint numDimensions,
1485 GLuint width,
1486 GLuint height,
1487 GLuint depth)
1488 {
1489 if (numDimensions != 2) {
1490 return 0;
1491 }
1492 switch (intFormat) {
1493 case GL_COMPRESSED_RGB_FXT1_3DFX:
1494 case GL_COMPRESSED_RGBA_FXT1_3DFX:
1495 /*
1496 * Round height and width to multiples of 4 and 8,
1497 * divide the resulting product by 32 to get the number
1498 * of blocks, and multiply by 32 = 128/8 to get the.
1499 * number of bytes required. That is to say, just
1500 * return the product. Remember that we are returning
1501 * bytes, not texels, so we have shrunk the texture
1502 * by a factor of the texel size.
1503 */
1504 width = (width + 0x7) &~ 0x7;
1505 height = (height + 0x3) &~ 0x3;
1506 return width * height;
1507 }
1508 return 0;
1509 }
1510
1511
1512
1513 /**
1514 * Allocate a new texture object.
1515 * Called via ctx->Driver.NewTextureObject.
1516 * Note: this function will be called during context creation to
1517 * allocate the default texture objects.
1518 * Note: we could use containment here to 'derive' the driver-specific
1519 * texture object from the core mesa gl_texture_object. Not done at this time.
1520 */
1521 static struct gl_texture_object *
1522 tdfxNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
1523 {
1524 struct gl_texture_object *obj;
1525 obj = _mesa_new_texture_object(ctx, name, target);
1526 return obj;
1527 }
1528
1529
1530 void tdfxInitTextureFuncs( struct dd_function_table *functions )
1531 {
1532 functions->BindTexture = tdfxBindTexture;
1533 functions->NewTextureObject = tdfxNewTextureObject;
1534 functions->DeleteTexture = tdfxDeleteTexture;
1535 functions->TexEnv = tdfxTexEnv;
1536 functions->TexParameter = tdfxTexParameter;
1537 functions->ChooseTextureFormat = tdfxChooseTextureFormat;
1538 functions->TexImage2D = tdfxTexImage2D;
1539 functions->TexSubImage2D = tdfxTexSubImage2D;
1540 functions->IsTextureResident = tdfxIsTextureResident;
1541 functions->UpdateTexturePalette = tdfxUpdateTexturePalette;
1542 }
1543