Support for swappable t&l modules, including an example one in the FX
[mesa.git] / src / mesa / drivers / glide / fxddtex.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 3.3
5 *
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
27 * terms stated above.
28 *
29 * Thank you for your contribution, David!
30 *
31 * Please make note of the above copyright/license statement. If you
32 * contributed code or bug fixes to this code under the previous (GNU
33 * Library) license and object to the new license, your code will be
34 * removed at your request. Please see the Mesa docs/COPYRIGHT file
35 * for more information.
36 *
37 * Additional Mesa/3Dfx driver developers:
38 * Daryll Strauss <daryll@precisioninsight.com>
39 * Keith Whitwell <keith@precisioninsight.com>
40 *
41 * See fxapi.h for more revision/author details.
42 */
43
44
45 #ifdef HAVE_CONFIG_H
46 #include "conf.h"
47 #endif
48
49 #if defined(FX)
50
51 #include "fxdrv.h"
52 #include "image.h"
53 #include "texutil.h"
54
55
56 void fxPrintTextureData(tfxTexInfo *ti)
57 {
58 fprintf(stderr, "Texture Data:\n");
59 if (ti->tObj) {
60 fprintf(stderr, "\tName: %d\n", ti->tObj->Name);
61 fprintf(stderr, "\tBaseLevel: %d\n", ti->tObj->BaseLevel);
62 fprintf(stderr, "\tSize: %d x %d\n",
63 ti->tObj->Image[ti->tObj->BaseLevel]->Width,
64 ti->tObj->Image[ti->tObj->BaseLevel]->Height);
65 } else
66 fprintf(stderr, "\tName: UNNAMED\n");
67 fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed);
68 fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU);
69 fprintf(stderr, "\t%s\n", (ti->isInTM)?"In TMU":"Not in TMU");
70 if (ti->tm[0])
71 fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr,
72 (unsigned) ti->tm[0]->endAddr);
73 if (ti->tm[1])
74 fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr,
75 (unsigned) ti->tm[1]->endAddr);
76 fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel);
77 fprintf(stderr, "\tFilters: min %d min %d\n",
78 (int) ti->minFilt, (int) ti->maxFilt);
79 fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp, (int) ti->tClamp);
80 fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale);
81 fprintf(stderr, "\tInt Scales: s %d t %d\n",
82 ti->int_sScale/0x800000, ti->int_tScale/0x800000);
83 fprintf(stderr, "\t%s\n", (ti->fixedPalette)?"Fixed palette":"Non fixed palette");
84 fprintf(stderr, "\t%s\n", (ti->validated)?"Validated":"Not validated");
85 }
86
87
88 /************************************************************************/
89 /*************************** Texture Mapping ****************************/
90 /************************************************************************/
91
92 static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj)
93 {
94 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
95 tfxTexInfo *ti;
96
97 ti=fxTMGetTexInfo(tObj);
98 if (ti->isInTM) fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */
99
100 ti->validated=GL_FALSE;
101 fxMesa->new_state|=FX_NEW_TEXTURING;
102 }
103
104 static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa)
105 {
106 tfxTexInfo *ti;
107 int i;
108
109 if(!(ti=CALLOC(sizeof(tfxTexInfo)))) {
110 fprintf(stderr,"fx Driver: out of memory !\n");
111 fxCloseHardware();
112 exit(-1);
113 }
114
115 ti->validated=GL_FALSE;
116 ti->isInTM=GL_FALSE;
117
118 ti->whichTMU=FX_TMU_NONE;
119
120 ti->tm[FX_TMU0]=NULL;
121 ti->tm[FX_TMU1]=NULL;
122
123 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
124 ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
125
126 ti->sClamp=GR_TEXTURECLAMP_WRAP;
127 ti->tClamp=GR_TEXTURECLAMP_WRAP;
128
129 ti->mmMode=GR_MIPMAP_NEAREST;
130 ti->LODblend=FXFALSE;
131
132 for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
133 ti->mipmapLevel[i].data=NULL;
134 }
135
136 return ti;
137 }
138
139 void fxDDTexBind(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj)
140 {
141 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
142 tfxTexInfo *ti;
143
144 if (MESA_VERBOSE&VERBOSE_DRIVER) {
145 fprintf(stderr,"fxmesa: fxDDTexBind(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
146 }
147
148 if(target!=GL_TEXTURE_2D)
149 return;
150
151 if (!tObj->DriverData) {
152 tObj->DriverData=fxAllocTexObjData(fxMesa);
153 }
154
155 ti=fxTMGetTexInfo(tObj);
156
157 fxMesa->texBindNumber++;
158 ti->lastTimeUsed=fxMesa->texBindNumber;
159
160 fxMesa->new_state|=FX_NEW_TEXTURING;
161 }
162
163 void fxDDTexEnv(GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param)
164 {
165 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
166
167 if (MESA_VERBOSE&VERBOSE_DRIVER) {
168 if(param)
169 fprintf(stderr,"fxmesa: texenv(%x,%x)\n",pname,(GLint)(*param));
170 else
171 fprintf(stderr,"fxmesa: texenv(%x)\n",pname);
172 }
173
174 /* apply any lod biasing right now */
175 if (pname==GL_TEXTURE_LOD_BIAS_EXT) {
176 FX_grTexLodBiasValue(GR_TMU0,*param);
177
178 if(fxMesa->haveTwoTMUs) {
179 FX_grTexLodBiasValue(GR_TMU1,*param);
180 }
181
182 }
183
184 fxMesa->new_state|=FX_NEW_TEXTURING;
185 }
186
187 void fxDDTexParam(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj,
188 GLenum pname, const GLfloat *params)
189 {
190 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
191 GLenum param=(GLenum)(GLint)params[0];
192 tfxTexInfo *ti;
193
194 if (MESA_VERBOSE&VERBOSE_DRIVER) {
195 fprintf(stderr,"fxmesa: fxDDTexParam(%d,%x,%x,%x)\n",tObj->Name,(GLuint)tObj->DriverData,pname,param);
196 }
197
198 if(target!=GL_TEXTURE_2D)
199 return;
200
201 if (!tObj->DriverData)
202 tObj->DriverData=fxAllocTexObjData(fxMesa);
203
204 ti=fxTMGetTexInfo(tObj);
205
206 switch(pname) {
207
208 case GL_TEXTURE_MIN_FILTER:
209 switch(param) {
210 case GL_NEAREST:
211 ti->mmMode=GR_MIPMAP_DISABLE;
212 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
213 ti->LODblend=FXFALSE;
214 break;
215 case GL_LINEAR:
216 ti->mmMode=GR_MIPMAP_DISABLE;
217 ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
218 ti->LODblend=FXFALSE;
219 break;
220 case GL_NEAREST_MIPMAP_NEAREST:
221 ti->mmMode=GR_MIPMAP_NEAREST;
222 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
223 ti->LODblend=FXFALSE;
224 break;
225 case GL_LINEAR_MIPMAP_NEAREST:
226 ti->mmMode=GR_MIPMAP_NEAREST;
227 ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
228 ti->LODblend=FXFALSE;
229 break;
230 case GL_NEAREST_MIPMAP_LINEAR:
231 if(fxMesa->haveTwoTMUs) {
232 ti->mmMode=GR_MIPMAP_NEAREST;
233 ti->LODblend=FXTRUE;
234 } else {
235 ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
236 ti->LODblend=FXFALSE;
237 }
238 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
239 break;
240 case GL_LINEAR_MIPMAP_LINEAR:
241 if(fxMesa->haveTwoTMUs) {
242 ti->mmMode=GR_MIPMAP_NEAREST;
243 ti->LODblend=FXTRUE;
244 } else {
245 ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
246 ti->LODblend=FXFALSE;
247 }
248 ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
249 break;
250 default:
251 break;
252 }
253 fxTexInvalidate(ctx,tObj);
254 break;
255
256 case GL_TEXTURE_MAG_FILTER:
257 switch(param) {
258 case GL_NEAREST:
259 ti->maxFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
260 break;
261 case GL_LINEAR:
262 ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
263 break;
264 default:
265 break;
266 }
267 fxTexInvalidate(ctx,tObj);
268 break;
269
270 case GL_TEXTURE_WRAP_S:
271 switch(param) {
272 case GL_CLAMP:
273 ti->sClamp=GR_TEXTURECLAMP_CLAMP;
274 break;
275 case GL_REPEAT:
276 ti->sClamp=GR_TEXTURECLAMP_WRAP;
277 break;
278 default:
279 break;
280 }
281 fxMesa->new_state|=FX_NEW_TEXTURING;
282 break;
283
284 case GL_TEXTURE_WRAP_T:
285 switch(param) {
286 case GL_CLAMP:
287 ti->tClamp=GR_TEXTURECLAMP_CLAMP;
288 break;
289 case GL_REPEAT:
290 ti->tClamp=GR_TEXTURECLAMP_WRAP;
291 break;
292 default:
293 break;
294 }
295 fxMesa->new_state|=FX_NEW_TEXTURING;
296 break;
297
298 case GL_TEXTURE_BORDER_COLOR:
299 /* TO DO */
300 break;
301
302 case GL_TEXTURE_MIN_LOD:
303 /* TO DO */
304 break;
305 case GL_TEXTURE_MAX_LOD:
306 /* TO DO */
307 break;
308 case GL_TEXTURE_BASE_LEVEL:
309 fxTexInvalidate(ctx,tObj);
310 break;
311 case GL_TEXTURE_MAX_LEVEL:
312 fxTexInvalidate(ctx,tObj);
313 break;
314
315 default:
316 break;
317 }
318 }
319
320 void fxDDTexDel(GLcontext *ctx, struct gl_texture_object *tObj)
321 {
322 fxMesaContext fxMesa = FX_CONTEXT(ctx);
323 tfxTexInfo *ti = fxTMGetTexInfo(tObj);
324
325 if (MESA_VERBOSE & VERBOSE_DRIVER) {
326 fprintf(stderr, "fxmesa: fxDDTexDel(%d,%p)\n", tObj->Name, ti);
327 }
328
329 if (!ti)
330 return;
331
332 fxTMFreeTexture(fxMesa, tObj);
333
334 FREE(ti);
335 tObj->DriverData = NULL;
336
337 /* Pushed into core: Set _NEW_TEXTURE whenever a bound texture is
338 * deleted (changes bound texture id).
339 */
340 /* ctx->NewState |= _NEW_TEXTURE; */
341 }
342
343
344
345 /*
346 * Convert a gl_color_table texture palette to Glide's format.
347 */
348 static void
349 convertPalette(FxU32 data[256], const struct gl_color_table *table)
350 {
351 const GLubyte *tableUB = (const GLubyte *) table->Table;
352 GLint width = table->Size;
353 FxU32 r, g, b, a;
354 GLint i;
355
356 ASSERT(!table->FloatTable);
357
358 switch (table->Format) {
359 case GL_INTENSITY:
360 for (i = 0; i < width; i++) {
361 r = tableUB[i];
362 g = tableUB[i];
363 b = tableUB[i];
364 a = tableUB[i];
365 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
366 }
367 break;
368 case GL_LUMINANCE:
369 for (i = 0; i < width; i++) {
370 r = tableUB[i];
371 g = tableUB[i];
372 b = tableUB[i];
373 a = 255;
374 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
375 }
376 break;
377 case GL_ALPHA:
378 for (i = 0; i < width; i++) {
379 r = g = b = 255;
380 a = tableUB[i];
381 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
382 }
383 break;
384 case GL_LUMINANCE_ALPHA:
385 for (i = 0; i < width; i++) {
386 r = g = b = tableUB[i*2+0];
387 a = tableUB[i*2+1];
388 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
389 }
390 break;
391 case GL_RGB:
392 for (i = 0; i < width; i++) {
393 r = tableUB[i*3+0];
394 g = tableUB[i*3+1];
395 b = tableUB[i*3+2];
396 a = 255;
397 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
398 }
399 break;
400 case GL_RGBA:
401 for (i = 0; i < width; i++) {
402 r = tableUB[i*4+0];
403 g = tableUB[i*4+1];
404 b = tableUB[i*4+2];
405 a = tableUB[i*4+3];
406 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
407 }
408 break;
409 }
410 }
411
412
413 void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj)
414 {
415 fxMesaContext fxMesa = FX_CONTEXT(ctx);
416
417 if (tObj) {
418 /* per-texture palette */
419 tfxTexInfo *ti;
420 if (MESA_VERBOSE & VERBOSE_DRIVER) {
421 fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n",
422 tObj->Name, (GLuint) tObj->DriverData);
423 }
424 if (!tObj->DriverData)
425 tObj->DriverData = fxAllocTexObjData(fxMesa);
426 ti = fxTMGetTexInfo(tObj);
427 convertPalette(ti->palette.data, &tObj->Palette);
428 fxTexInvalidate(ctx, tObj);
429 }
430 else {
431 /* global texture palette */
432 if (MESA_VERBOSE & VERBOSE_DRIVER) {
433 fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n");
434 }
435 convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
436 fxMesa->new_state |= FX_NEW_TEXTURING;
437 }
438 }
439
440
441 void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state)
442 {
443 fxMesaContext fxMesa = FX_CONTEXT(ctx);
444
445 if (MESA_VERBOSE&VERBOSE_DRIVER) {
446 fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state);
447 }
448
449 if (state) {
450 fxMesa->haveGlobalPaletteTexture = 1;
451
452 FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
453 if (fxMesa->haveTwoTMUs)
454 FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
455 }
456 else {
457 fxMesa->haveGlobalPaletteTexture = 0;
458
459 if ((ctx->Texture.Unit[0]._Current == ctx->Texture.Unit[0].Current2D) &&
460 (ctx->Texture.Unit[0]._Current != NULL)) {
461 struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
462
463 if (!tObj->DriverData)
464 tObj->DriverData = fxAllocTexObjData(fxMesa);
465
466 fxTexInvalidate(ctx, tObj);
467 }
468 }
469 }
470
471
472 static int logbase2(int n)
473 {
474 GLint i = 1;
475 GLint log2 = 0;
476
477 if (n<0) {
478 return -1;
479 }
480
481 while (n > i) {
482 i *= 2;
483 log2++;
484 }
485 if (i != n) {
486 return -1;
487 }
488 else {
489 return log2;
490 }
491 }
492
493 /* Need different versions for different cpus.
494 */
495 #define INT_TRICK(l2) (0x800000 * l2)
496
497
498 int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
499 float *sscale, float *tscale,
500 int *i_sscale, int *i_tscale,
501 int *wscale, int *hscale)
502 {
503
504 static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
505 GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
506
507 int logw,logh,ws,hs;
508 GrLOD_t l;
509 GrAspectRatio_t aspectratio;
510 float s,t;
511 int is,it;
512
513 logw=logbase2(w);
514 logh=logbase2(h);
515
516 switch(logw-logh) {
517 case 0:
518 aspectratio=GR_ASPECT_1x1;
519 l=lod[8-logw];
520 s=t=256.0f;
521 is=it=INT_TRICK(8);
522 ws=hs=1;
523 break;
524 case 1:
525 aspectratio=GR_ASPECT_2x1;
526 l=lod[8-logw];
527 s=256.0f;
528 t=128.0f;
529 is=INT_TRICK(8);it=INT_TRICK(7);
530 ws=1;
531 hs=1;
532 break;
533 case 2:
534 aspectratio=GR_ASPECT_4x1;
535 l=lod[8-logw];
536 s=256.0f;
537 t=64.0f;
538 is=INT_TRICK(8);it=INT_TRICK(6);
539 ws=1;
540 hs=1;
541 break;
542 case 3:
543 aspectratio=GR_ASPECT_8x1;
544 l=lod[8-logw];
545 s=256.0f;
546 t=32.0f;
547 is=INT_TRICK(8);it=INT_TRICK(5);
548 ws=1;
549 hs=1;
550 break;
551 case 4:
552 aspectratio=GR_ASPECT_8x1;
553 l=lod[8-logw];
554 s=256.0f;
555 t=32.0f;
556 is=INT_TRICK(8);it=INT_TRICK(5);
557 ws=1;
558 hs=2;
559 break;
560 case 5:
561 aspectratio=GR_ASPECT_8x1;
562 l=lod[8-logw];
563 s=256.0f;
564 t=32.0f;
565 is=INT_TRICK(8);it=INT_TRICK(5);
566 ws=1;
567 hs=4;
568 break;
569 case 6:
570 aspectratio=GR_ASPECT_8x1;
571 l=lod[8-logw];
572 s=256.0f;
573 t=32.0f;
574 is=INT_TRICK(8);it=INT_TRICK(5);
575 ws=1;
576 hs=8;
577 break;
578 case 7:
579 aspectratio=GR_ASPECT_8x1;
580 l=lod[8-logw];
581 s=256.0f;
582 t=32.0f;
583 is=INT_TRICK(8);it=INT_TRICK(5);
584 ws=1;
585 hs=16;
586 break;
587 case 8:
588 aspectratio=GR_ASPECT_8x1;
589 l=lod[8-logw];
590 s=256.0f;
591 t=32.0f;
592 is=INT_TRICK(8);it=INT_TRICK(5);
593 ws=1;
594 hs=32;
595 break;
596 case -1:
597 aspectratio=GR_ASPECT_1x2;
598 l=lod[8-logh];
599 s=128.0f;
600 t=256.0f;
601 is=INT_TRICK(7);it=INT_TRICK(8);
602 ws=1;
603 hs=1;
604 break;
605 case -2:
606 aspectratio=GR_ASPECT_1x4;
607 l=lod[8-logh];
608 s=64.0f;
609 t=256.0f;
610 is=INT_TRICK(6);it=INT_TRICK(8);
611 ws=1;
612 hs=1;
613 break;
614 case -3:
615 aspectratio=GR_ASPECT_1x8;
616 l=lod[8-logh];
617 s=32.0f;
618 t=256.0f;
619 is=INT_TRICK(5);it=INT_TRICK(8);
620 ws=1;
621 hs=1;
622 break;
623 case -4:
624 aspectratio=GR_ASPECT_1x8;
625 l=lod[8-logh];
626 s=32.0f;
627 t=256.0f;
628 is=INT_TRICK(5);it=INT_TRICK(8);
629 ws=2;
630 hs=1;
631 break;
632 case -5:
633 aspectratio=GR_ASPECT_1x8;
634 l=lod[8-logh];
635 s=32.0f;
636 t=256.0f;
637 is=INT_TRICK(5);it=INT_TRICK(8);
638 ws=4;
639 hs=1;
640 break;
641 case -6:
642 aspectratio=GR_ASPECT_1x8;
643 l=lod[8-logh];
644 s=32.0f;
645 t=256.0f;
646 is=INT_TRICK(5);it=INT_TRICK(8);
647 ws=8;
648 hs=1;
649 break;
650 case -7:
651 aspectratio=GR_ASPECT_1x8;
652 l=lod[8-logh];
653 s=32.0f;
654 t=256.0f;
655 is=INT_TRICK(5);it=INT_TRICK(8);
656 ws=16;
657 hs=1;
658 break;
659 case -8:
660 aspectratio=GR_ASPECT_1x8;
661 l=lod[8-logh];
662 s=32.0f;
663 t=256.0f;
664 is=INT_TRICK(5);it=INT_TRICK(8);
665 ws=32;
666 hs=1;
667 break;
668 default:
669 return 0;
670 break;
671 }
672
673 if(lodlevel)
674 (*lodlevel)=l;
675
676 if(ar)
677 (*ar)=aspectratio;
678
679 if(sscale)
680 (*sscale)=s;
681
682 if(tscale)
683 (*tscale)=t;
684
685 if(wscale)
686 (*wscale)=ws;
687
688 if(hscale)
689 (*hscale)=hs;
690
691 if (i_sscale)
692 *i_sscale = is;
693
694 if (i_tscale)
695 *i_tscale = it;
696
697
698 return 1;
699 }
700
701 /*
702 * Given an OpenGL internal texture format, return the corresponding
703 * Glide internal texture format and base texture format.
704 */
705 void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
706 {
707 switch(glformat) {
708 case 1:
709 case GL_LUMINANCE:
710 case GL_LUMINANCE4:
711 case GL_LUMINANCE8:
712 case GL_LUMINANCE12:
713 case GL_LUMINANCE16:
714 if(tfmt)
715 (*tfmt)=GR_TEXFMT_INTENSITY_8;
716 if(ifmt)
717 (*ifmt)=GL_LUMINANCE;
718 break;
719 case 2:
720 case GL_LUMINANCE_ALPHA:
721 case GL_LUMINANCE4_ALPHA4:
722 case GL_LUMINANCE6_ALPHA2:
723 case GL_LUMINANCE8_ALPHA8:
724 case GL_LUMINANCE12_ALPHA4:
725 case GL_LUMINANCE12_ALPHA12:
726 case GL_LUMINANCE16_ALPHA16:
727 if(tfmt)
728 (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
729 if(ifmt)
730 (*ifmt)=GL_LUMINANCE_ALPHA;
731 break;
732 case GL_INTENSITY:
733 case GL_INTENSITY4:
734 case GL_INTENSITY8:
735 case GL_INTENSITY12:
736 case GL_INTENSITY16:
737 if(tfmt)
738 (*tfmt)=GR_TEXFMT_ALPHA_8;
739 if(ifmt)
740 (*ifmt)=GL_INTENSITY;
741 break;
742 case GL_ALPHA:
743 case GL_ALPHA4:
744 case GL_ALPHA8:
745 case GL_ALPHA12:
746 case GL_ALPHA16:
747 if(tfmt)
748 (*tfmt)=GR_TEXFMT_ALPHA_8;
749 if(ifmt)
750 (*ifmt)=GL_ALPHA;
751 break;
752 case 3:
753 case GL_RGB:
754 case GL_R3_G3_B2:
755 case GL_RGB4:
756 case GL_RGB5:
757 case GL_RGB8:
758 case GL_RGB10:
759 case GL_RGB12:
760 case GL_RGB16:
761 if(tfmt)
762 (*tfmt)=GR_TEXFMT_RGB_565;
763 if(ifmt)
764 (*ifmt)=GL_RGB;
765 break;
766 case 4:
767 case GL_RGBA:
768 case GL_RGBA2:
769 case GL_RGBA4:
770 case GL_RGBA8:
771 case GL_RGB10_A2:
772 case GL_RGBA12:
773 case GL_RGBA16:
774 if(tfmt)
775 (*tfmt)=GR_TEXFMT_ARGB_4444;
776 if(ifmt)
777 (*ifmt)=GL_RGBA;
778 break;
779 case GL_RGB5_A1:
780 if(tfmt)
781 (*tfmt)=GR_TEXFMT_ARGB_1555;
782 if(ifmt)
783 (*ifmt)=GL_RGBA;
784 break;
785 case GL_COLOR_INDEX:
786 case GL_COLOR_INDEX1_EXT:
787 case GL_COLOR_INDEX2_EXT:
788 case GL_COLOR_INDEX4_EXT:
789 case GL_COLOR_INDEX8_EXT:
790 case GL_COLOR_INDEX12_EXT:
791 case GL_COLOR_INDEX16_EXT:
792 if(tfmt)
793 (*tfmt)=GR_TEXFMT_P_8;
794 if(ifmt)
795 (*ifmt)=GL_RGBA; /* XXX why is this RGBA? */
796 break;
797 default:
798 fprintf(stderr,
799 "fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
800 fxCloseHardware();
801 exit(-1);
802 break;
803 }
804 }
805
806 static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat,
807 const struct gl_texture_image *image)
808 {
809 if(target != GL_TEXTURE_2D)
810 return GL_FALSE;
811
812 if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
813 NULL,NULL))
814 return GL_FALSE;
815
816 if (image->Border > 0)
817 return GL_FALSE;
818
819 return GL_TRUE;
820 }
821
822
823 /**********************************************************************/
824 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
825 /**********************************************************************/
826
827 GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
828 GLenum format, GLenum type, const GLvoid *pixels,
829 const struct gl_pixelstore_attrib *packing,
830 struct gl_texture_object *texObj,
831 struct gl_texture_image *texImage,
832 GLboolean *retainInternalCopy)
833 {
834 fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
835
836 if (target != GL_TEXTURE_2D)
837 return GL_FALSE;
838
839 if (!texObj->DriverData)
840 texObj->DriverData = fxAllocTexObjData(fxMesa);
841
842 if (fxIsTexSupported(target, texImage->IntFormat, texImage)) {
843 GrTextureFormat_t gldformat;
844 tfxTexInfo *ti = fxTMGetTexInfo(texObj);
845 tfxMipMapLevel *mml = &ti->mipmapLevel[level];
846 GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride;
847 MesaIntTexFormat intFormat;
848
849 fxTexGetFormat(texImage->IntFormat, &gldformat, NULL);
850
851 fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
852 NULL,NULL, &wScale, &hScale);
853
854 dstWidth = texImage->Width * wScale;
855 dstHeight = texImage->Height * hScale;
856
857 switch (texImage->IntFormat) {
858 case GL_INTENSITY:
859 case GL_INTENSITY4:
860 case GL_INTENSITY8:
861 case GL_INTENSITY12:
862 case GL_INTENSITY16:
863 texelSize = 1;
864 intFormat = MESA_I8;
865 break;
866 case 1:
867 case GL_LUMINANCE:
868 case GL_LUMINANCE4:
869 case GL_LUMINANCE8:
870 case GL_LUMINANCE12:
871 case GL_LUMINANCE16:
872 texelSize = 1;
873 intFormat = MESA_L8;
874 break;
875 case GL_ALPHA:
876 case GL_ALPHA4:
877 case GL_ALPHA8:
878 case GL_ALPHA12:
879 case GL_ALPHA16:
880 texelSize = 1;
881 intFormat = MESA_A8;
882 break;
883 case GL_COLOR_INDEX:
884 case GL_COLOR_INDEX1_EXT:
885 case GL_COLOR_INDEX2_EXT:
886 case GL_COLOR_INDEX4_EXT:
887 case GL_COLOR_INDEX8_EXT:
888 case GL_COLOR_INDEX12_EXT:
889 case GL_COLOR_INDEX16_EXT:
890 texelSize = 1;
891 intFormat = MESA_C8;
892 break;
893 case 2:
894 case GL_LUMINANCE_ALPHA:
895 case GL_LUMINANCE4_ALPHA4:
896 case GL_LUMINANCE6_ALPHA2:
897 case GL_LUMINANCE8_ALPHA8:
898 case GL_LUMINANCE12_ALPHA4:
899 case GL_LUMINANCE12_ALPHA12:
900 case GL_LUMINANCE16_ALPHA16:
901 texelSize = 2;
902 intFormat = MESA_A8_L8;
903 break;
904 case 3:
905 case GL_RGB:
906 case GL_R3_G3_B2:
907 case GL_RGB4:
908 case GL_RGB5:
909 case GL_RGB8:
910 case GL_RGB10:
911 case GL_RGB12:
912 case GL_RGB16:
913 texelSize = 2;
914 intFormat = MESA_R5_G6_B5;
915 break;
916 case 4:
917 case GL_RGBA:
918 case GL_RGBA2:
919 case GL_RGBA4:
920 case GL_RGBA8:
921 case GL_RGB10_A2:
922 case GL_RGBA12:
923 case GL_RGBA16:
924 texelSize = 2;
925 intFormat = MESA_A4_R4_G4_B4;
926 break;
927 case GL_RGB5_A1:
928 texelSize = 2;
929 intFormat = MESA_A1_R5_G5_B5;
930 break;
931 default:
932 gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format");
933 return GL_FALSE;
934 }
935
936 _mesa_set_teximage_component_sizes(intFormat, texImage);
937
938 /*printf("teximage:\n");*/
939 /* allocate new storage for texture image, if needed */
940 if (!mml->data || mml->glideFormat != gldformat ||
941 mml->width != dstWidth || mml->height != dstHeight) {
942 if (mml->data)
943 FREE(mml->data);
944 mml->data = MALLOC(dstWidth * dstHeight * texelSize);
945 if (!mml->data)
946 return GL_FALSE;
947 mml->glideFormat = gldformat;
948 mml->width = dstWidth;
949 mml->height = dstHeight;
950 fxTexInvalidate(ctx, texObj);
951 }
952
953 dstStride = dstWidth * texelSize;
954
955 /* store the texture image */
956 if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data,
957 dstStride,
958 texImage->Width, texImage->Height,
959 format, type, pixels, packing)) {
960 return GL_FALSE;
961 }
962
963 if (ti->validated && ti->isInTM) {
964 /*printf("reloadmipmaplevels\n");*/
965 fxTMReloadMipMapLevel(fxMesa, texObj, level);
966 }
967 else {
968 /*printf("invalidate2\n");*/
969 fxTexInvalidate(ctx,texObj);
970 }
971
972 *retainInternalCopy = GL_FALSE;
973 return GL_TRUE;
974 }
975 else {
976 gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
977 return GL_FALSE;
978 }
979 }
980
981
982 GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
983 GLint xoffset, GLint yoffset,
984 GLsizei width, GLsizei height,
985 GLenum format, GLenum type, const GLvoid *pixels,
986 const struct gl_pixelstore_attrib *packing,
987 struct gl_texture_object *texObj,
988 struct gl_texture_image *texImage)
989 {
990 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
991 tfxTexInfo *ti;
992 GLint wscale, hscale, dstStride;
993 tfxMipMapLevel *mml;
994 GLboolean result;
995
996 if (target != GL_TEXTURE_2D)
997 return GL_FALSE;
998
999 if (!texObj->DriverData)
1000 return GL_FALSE;
1001
1002 ti = fxTMGetTexInfo(texObj);
1003 mml = &ti->mipmapLevel[level];
1004
1005 fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
1006 NULL,NULL, &wscale, &hscale);
1007
1008 assert(mml->data); /* must have an existing texture image! */
1009
1010 switch (mml->glideFormat) {
1011 case GR_TEXFMT_INTENSITY_8:
1012 dstStride = mml->width;
1013 result = _mesa_convert_texsubimage(MESA_I8, xoffset, yoffset,
1014 mml->width, mml->height, mml->data,
1015 dstStride, width, height,
1016 texImage->Width, texImage->Height,
1017 format, type, pixels, packing);
1018 break;
1019 case GR_TEXFMT_ALPHA_8:
1020 dstStride = mml->width;
1021 result = _mesa_convert_texsubimage(MESA_A8, xoffset, yoffset,
1022 mml->width, mml->height, mml->data,
1023 dstStride, width, height,
1024 texImage->Width, texImage->Height,
1025 format, type, pixels, packing);
1026 break;
1027 case GR_TEXFMT_P_8:
1028 dstStride = mml->width;
1029 result = _mesa_convert_texsubimage(MESA_C8, xoffset, yoffset,
1030 mml->width, mml->height, mml->data,
1031 dstStride, width, height,
1032 texImage->Width, texImage->Height,
1033 format, type, pixels, packing);
1034 break;
1035 case GR_TEXFMT_ALPHA_INTENSITY_88:
1036 dstStride = mml->width * 2;
1037 result = _mesa_convert_texsubimage(MESA_A8_L8, xoffset, yoffset,
1038 mml->width, mml->height, mml->data,
1039 dstStride, width, height,
1040 texImage->Width, texImage->Height,
1041 format, type, pixels, packing);
1042 break;
1043 case GR_TEXFMT_RGB_565:
1044 dstStride = mml->width * 2;
1045 result = _mesa_convert_texsubimage(MESA_R5_G6_B5, xoffset, yoffset,
1046 mml->width, mml->height, mml->data,
1047 dstStride, width, height,
1048 texImage->Width, texImage->Height,
1049 format, type, pixels, packing);
1050 break;
1051 case GR_TEXFMT_ARGB_4444:
1052 dstStride = mml->width * 2;
1053 result = _mesa_convert_texsubimage(MESA_A4_R4_G4_B4, xoffset, yoffset,
1054 mml->width, mml->height, mml->data,
1055 dstStride, width, height,
1056 texImage->Width, texImage->Height,
1057 format, type, pixels, packing);
1058 break;
1059 case GR_TEXFMT_ARGB_1555:
1060 dstStride = mml->width * 2;
1061 result = _mesa_convert_texsubimage(MESA_A1_R5_G5_B5, xoffset, yoffset,
1062 mml->width, mml->height, mml->data,
1063 dstStride, width, height,
1064 texImage->Width, texImage->Height,
1065 format, type, pixels, packing);
1066 break;
1067 default:
1068 gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format");
1069 result = GL_FALSE;
1070 }
1071
1072 if (!result) {
1073 return GL_FALSE;
1074 }
1075
1076 if (ti->validated && ti->isInTM)
1077 fxTMReloadMipMapLevel(fxMesa, texObj, level);
1078 else
1079 fxTexInvalidate(ctx, texObj);
1080
1081 return GL_TRUE;
1082 }
1083
1084
1085 static void PrintTexture(int w, int h, int c, const GLubyte *data)
1086 {
1087 int i, j;
1088 for (i = 0; i < h; i++) {
1089 for (j = 0; j < w; j++) {
1090 if (c==2)
1091 printf("%02x %02x ", data[0], data[1]);
1092 else if (c==3)
1093 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1094 data += c;
1095 }
1096 printf("\n");
1097 }
1098 }
1099
1100
1101 GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level,
1102 const struct gl_texture_object *texObj,
1103 GLenum *formatOut, GLenum *typeOut,
1104 GLboolean *freeImageOut )
1105 {
1106 tfxTexInfo *ti;
1107 tfxMipMapLevel *mml;
1108
1109 if (target != GL_TEXTURE_2D)
1110 return NULL;
1111
1112 if (!texObj->DriverData)
1113 return NULL;
1114
1115 ti = fxTMGetTexInfo(texObj);
1116 mml = &ti->mipmapLevel[level];
1117 if (mml->data) {
1118 MesaIntTexFormat mesaFormat;
1119 GLenum glFormat;
1120 struct gl_texture_image *texImage = texObj->Image[level];
1121 GLint srcStride;
1122
1123 GLubyte *data = (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4);
1124 if (!data)
1125 return NULL;
1126
1127 switch (mml->glideFormat) {
1128 case GR_TEXFMT_INTENSITY_8:
1129 mesaFormat = MESA_I8;
1130 glFormat = GL_INTENSITY;
1131 srcStride = mml->width;
1132 break;
1133 case GR_TEXFMT_ALPHA_INTENSITY_88:
1134 mesaFormat = MESA_A8_L8;
1135 glFormat = GL_LUMINANCE_ALPHA;
1136 srcStride = mml->width;
1137 break;
1138 case GR_TEXFMT_ALPHA_8:
1139 mesaFormat = MESA_A8;
1140 glFormat = GL_ALPHA;
1141 srcStride = mml->width;
1142 break;
1143 case GR_TEXFMT_RGB_565:
1144 mesaFormat = MESA_R5_G6_B5;
1145 glFormat = GL_RGB;
1146 srcStride = mml->width * 2;
1147 break;
1148 case GR_TEXFMT_ARGB_4444:
1149 mesaFormat = MESA_A4_R4_G4_B4;
1150 glFormat = GL_RGBA;
1151 srcStride = mml->width * 2;
1152 break;
1153 case GR_TEXFMT_ARGB_1555:
1154 mesaFormat = MESA_A1_R5_G5_B5;
1155 glFormat = GL_RGBA;
1156 srcStride = mml->width * 2;
1157 break;
1158 case GR_TEXFMT_P_8:
1159 mesaFormat = MESA_C8;
1160 glFormat = GL_COLOR_INDEX;
1161 srcStride = mml->width;
1162 break;
1163 default:
1164 gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage");
1165 return NULL;
1166 }
1167 _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, mml->data,
1168 srcStride, texImage->Width, texImage->Height,
1169 glFormat, data);
1170 *formatOut = glFormat;
1171 *typeOut = GL_UNSIGNED_BYTE;
1172 *freeImageOut = GL_TRUE;
1173 return data;
1174 }
1175 else {
1176 return NULL;
1177 }
1178 }
1179
1180
1181 #else
1182
1183
1184 /*
1185 * Need this to provide at least one external definition.
1186 */
1187
1188 extern int gl_fx_dummy_function_ddtex(void);
1189 int gl_fx_dummy_function_ddtex(void)
1190 {
1191 return 0;
1192 }
1193
1194 #endif /* FX */