Add render stage for unclipped vb's to fx driver.
[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
338
339
340 /*
341 * Convert a gl_color_table texture palette to Glide's format.
342 */
343 static void
344 convertPalette(FxU32 data[256], const struct gl_color_table *table)
345 {
346 const GLubyte *tableUB = (const GLubyte *) table->Table;
347 GLint width = table->Size;
348 FxU32 r, g, b, a;
349 GLint i;
350
351 ASSERT(!table->FloatTable);
352
353 switch (table->Format) {
354 case GL_INTENSITY:
355 for (i = 0; i < width; i++) {
356 r = tableUB[i];
357 g = tableUB[i];
358 b = tableUB[i];
359 a = tableUB[i];
360 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
361 }
362 break;
363 case GL_LUMINANCE:
364 for (i = 0; i < width; i++) {
365 r = tableUB[i];
366 g = tableUB[i];
367 b = tableUB[i];
368 a = 255;
369 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
370 }
371 break;
372 case GL_ALPHA:
373 for (i = 0; i < width; i++) {
374 r = g = b = 255;
375 a = tableUB[i];
376 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
377 }
378 break;
379 case GL_LUMINANCE_ALPHA:
380 for (i = 0; i < width; i++) {
381 r = g = b = tableUB[i*2+0];
382 a = tableUB[i*2+1];
383 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
384 }
385 break;
386 case GL_RGB:
387 for (i = 0; i < width; i++) {
388 r = tableUB[i*3+0];
389 g = tableUB[i*3+1];
390 b = tableUB[i*3+2];
391 a = 255;
392 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
393 }
394 break;
395 case GL_RGBA:
396 for (i = 0; i < width; i++) {
397 r = tableUB[i*4+0];
398 g = tableUB[i*4+1];
399 b = tableUB[i*4+2];
400 a = tableUB[i*4+3];
401 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
402 }
403 break;
404 }
405 }
406
407
408 void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj)
409 {
410 fxMesaContext fxMesa = FX_CONTEXT(ctx);
411
412 if (tObj) {
413 /* per-texture palette */
414 tfxTexInfo *ti;
415 if (MESA_VERBOSE & VERBOSE_DRIVER) {
416 fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n",
417 tObj->Name, (GLuint) tObj->DriverData);
418 }
419 if (!tObj->DriverData)
420 tObj->DriverData = fxAllocTexObjData(fxMesa);
421 ti = fxTMGetTexInfo(tObj);
422 convertPalette(ti->palette.data, &tObj->Palette);
423 fxTexInvalidate(ctx, tObj);
424 }
425 else {
426 /* global texture palette */
427 if (MESA_VERBOSE & VERBOSE_DRIVER) {
428 fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n");
429 }
430 convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
431 fxMesa->new_state |= FX_NEW_TEXTURING;
432 }
433 }
434
435
436 void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state)
437 {
438 fxMesaContext fxMesa = FX_CONTEXT(ctx);
439
440 if (MESA_VERBOSE&VERBOSE_DRIVER) {
441 fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state);
442 }
443
444 if (state) {
445 fxMesa->haveGlobalPaletteTexture = 1;
446
447 FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
448 if (fxMesa->haveTwoTMUs)
449 FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette));
450 }
451 else {
452 fxMesa->haveGlobalPaletteTexture = 0;
453
454 if ((ctx->Texture.Unit[0]._Current == ctx->Texture.Unit[0].Current2D) &&
455 (ctx->Texture.Unit[0]._Current != NULL)) {
456 struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
457
458 if (!tObj->DriverData)
459 tObj->DriverData = fxAllocTexObjData(fxMesa);
460
461 fxTexInvalidate(ctx, tObj);
462 }
463 }
464 }
465
466
467 static int logbase2(int n)
468 {
469 GLint i = 1;
470 GLint log2 = 0;
471
472 if (n<0) {
473 return -1;
474 }
475
476 while (n > i) {
477 i *= 2;
478 log2++;
479 }
480 if (i != n) {
481 return -1;
482 }
483 else {
484 return log2;
485 }
486 }
487
488 /* Need different versions for different cpus.
489 */
490 #define INT_TRICK(l2) (0x800000 * l2)
491
492
493 int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
494 float *sscale, float *tscale,
495 int *i_sscale, int *i_tscale,
496 int *wscale, int *hscale)
497 {
498
499 static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
500 GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
501
502 int logw,logh,ws,hs;
503 GrLOD_t l;
504 GrAspectRatio_t aspectratio;
505 float s,t;
506 int is,it;
507
508 logw=logbase2(w);
509 logh=logbase2(h);
510
511 switch(logw-logh) {
512 case 0:
513 aspectratio=GR_ASPECT_1x1;
514 l=lod[8-logw];
515 s=t=256.0f;
516 is=it=INT_TRICK(8);
517 ws=hs=1;
518 break;
519 case 1:
520 aspectratio=GR_ASPECT_2x1;
521 l=lod[8-logw];
522 s=256.0f;
523 t=128.0f;
524 is=INT_TRICK(8);it=INT_TRICK(7);
525 ws=1;
526 hs=1;
527 break;
528 case 2:
529 aspectratio=GR_ASPECT_4x1;
530 l=lod[8-logw];
531 s=256.0f;
532 t=64.0f;
533 is=INT_TRICK(8);it=INT_TRICK(6);
534 ws=1;
535 hs=1;
536 break;
537 case 3:
538 aspectratio=GR_ASPECT_8x1;
539 l=lod[8-logw];
540 s=256.0f;
541 t=32.0f;
542 is=INT_TRICK(8);it=INT_TRICK(5);
543 ws=1;
544 hs=1;
545 break;
546 case 4:
547 aspectratio=GR_ASPECT_8x1;
548 l=lod[8-logw];
549 s=256.0f;
550 t=32.0f;
551 is=INT_TRICK(8);it=INT_TRICK(5);
552 ws=1;
553 hs=2;
554 break;
555 case 5:
556 aspectratio=GR_ASPECT_8x1;
557 l=lod[8-logw];
558 s=256.0f;
559 t=32.0f;
560 is=INT_TRICK(8);it=INT_TRICK(5);
561 ws=1;
562 hs=4;
563 break;
564 case 6:
565 aspectratio=GR_ASPECT_8x1;
566 l=lod[8-logw];
567 s=256.0f;
568 t=32.0f;
569 is=INT_TRICK(8);it=INT_TRICK(5);
570 ws=1;
571 hs=8;
572 break;
573 case 7:
574 aspectratio=GR_ASPECT_8x1;
575 l=lod[8-logw];
576 s=256.0f;
577 t=32.0f;
578 is=INT_TRICK(8);it=INT_TRICK(5);
579 ws=1;
580 hs=16;
581 break;
582 case 8:
583 aspectratio=GR_ASPECT_8x1;
584 l=lod[8-logw];
585 s=256.0f;
586 t=32.0f;
587 is=INT_TRICK(8);it=INT_TRICK(5);
588 ws=1;
589 hs=32;
590 break;
591 case -1:
592 aspectratio=GR_ASPECT_1x2;
593 l=lod[8-logh];
594 s=128.0f;
595 t=256.0f;
596 is=INT_TRICK(7);it=INT_TRICK(8);
597 ws=1;
598 hs=1;
599 break;
600 case -2:
601 aspectratio=GR_ASPECT_1x4;
602 l=lod[8-logh];
603 s=64.0f;
604 t=256.0f;
605 is=INT_TRICK(6);it=INT_TRICK(8);
606 ws=1;
607 hs=1;
608 break;
609 case -3:
610 aspectratio=GR_ASPECT_1x8;
611 l=lod[8-logh];
612 s=32.0f;
613 t=256.0f;
614 is=INT_TRICK(5);it=INT_TRICK(8);
615 ws=1;
616 hs=1;
617 break;
618 case -4:
619 aspectratio=GR_ASPECT_1x8;
620 l=lod[8-logh];
621 s=32.0f;
622 t=256.0f;
623 is=INT_TRICK(5);it=INT_TRICK(8);
624 ws=2;
625 hs=1;
626 break;
627 case -5:
628 aspectratio=GR_ASPECT_1x8;
629 l=lod[8-logh];
630 s=32.0f;
631 t=256.0f;
632 is=INT_TRICK(5);it=INT_TRICK(8);
633 ws=4;
634 hs=1;
635 break;
636 case -6:
637 aspectratio=GR_ASPECT_1x8;
638 l=lod[8-logh];
639 s=32.0f;
640 t=256.0f;
641 is=INT_TRICK(5);it=INT_TRICK(8);
642 ws=8;
643 hs=1;
644 break;
645 case -7:
646 aspectratio=GR_ASPECT_1x8;
647 l=lod[8-logh];
648 s=32.0f;
649 t=256.0f;
650 is=INT_TRICK(5);it=INT_TRICK(8);
651 ws=16;
652 hs=1;
653 break;
654 case -8:
655 aspectratio=GR_ASPECT_1x8;
656 l=lod[8-logh];
657 s=32.0f;
658 t=256.0f;
659 is=INT_TRICK(5);it=INT_TRICK(8);
660 ws=32;
661 hs=1;
662 break;
663 default:
664 return 0;
665 break;
666 }
667
668 if(lodlevel)
669 (*lodlevel)=l;
670
671 if(ar)
672 (*ar)=aspectratio;
673
674 if(sscale)
675 (*sscale)=s;
676
677 if(tscale)
678 (*tscale)=t;
679
680 if(wscale)
681 (*wscale)=ws;
682
683 if(hscale)
684 (*hscale)=hs;
685
686 if (i_sscale)
687 *i_sscale = is;
688
689 if (i_tscale)
690 *i_tscale = it;
691
692
693 return 1;
694 }
695
696 /*
697 * Given an OpenGL internal texture format, return the corresponding
698 * Glide internal texture format and base texture format.
699 */
700 void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
701 {
702 switch(glformat) {
703 case 1:
704 case GL_LUMINANCE:
705 case GL_LUMINANCE4:
706 case GL_LUMINANCE8:
707 case GL_LUMINANCE12:
708 case GL_LUMINANCE16:
709 if(tfmt)
710 (*tfmt)=GR_TEXFMT_INTENSITY_8;
711 if(ifmt)
712 (*ifmt)=GL_LUMINANCE;
713 break;
714 case 2:
715 case GL_LUMINANCE_ALPHA:
716 case GL_LUMINANCE4_ALPHA4:
717 case GL_LUMINANCE6_ALPHA2:
718 case GL_LUMINANCE8_ALPHA8:
719 case GL_LUMINANCE12_ALPHA4:
720 case GL_LUMINANCE12_ALPHA12:
721 case GL_LUMINANCE16_ALPHA16:
722 if(tfmt)
723 (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
724 if(ifmt)
725 (*ifmt)=GL_LUMINANCE_ALPHA;
726 break;
727 case GL_INTENSITY:
728 case GL_INTENSITY4:
729 case GL_INTENSITY8:
730 case GL_INTENSITY12:
731 case GL_INTENSITY16:
732 if(tfmt)
733 (*tfmt)=GR_TEXFMT_ALPHA_8;
734 if(ifmt)
735 (*ifmt)=GL_INTENSITY;
736 break;
737 case GL_ALPHA:
738 case GL_ALPHA4:
739 case GL_ALPHA8:
740 case GL_ALPHA12:
741 case GL_ALPHA16:
742 if(tfmt)
743 (*tfmt)=GR_TEXFMT_ALPHA_8;
744 if(ifmt)
745 (*ifmt)=GL_ALPHA;
746 break;
747 case 3:
748 case GL_RGB:
749 case GL_R3_G3_B2:
750 case GL_RGB4:
751 case GL_RGB5:
752 case GL_RGB8:
753 case GL_RGB10:
754 case GL_RGB12:
755 case GL_RGB16:
756 if(tfmt)
757 (*tfmt)=GR_TEXFMT_RGB_565;
758 if(ifmt)
759 (*ifmt)=GL_RGB;
760 break;
761 case 4:
762 case GL_RGBA:
763 case GL_RGBA2:
764 case GL_RGBA4:
765 case GL_RGBA8:
766 case GL_RGB10_A2:
767 case GL_RGBA12:
768 case GL_RGBA16:
769 if(tfmt)
770 (*tfmt)=GR_TEXFMT_ARGB_4444;
771 if(ifmt)
772 (*ifmt)=GL_RGBA;
773 break;
774 case GL_RGB5_A1:
775 if(tfmt)
776 (*tfmt)=GR_TEXFMT_ARGB_1555;
777 if(ifmt)
778 (*ifmt)=GL_RGBA;
779 break;
780 case GL_COLOR_INDEX:
781 case GL_COLOR_INDEX1_EXT:
782 case GL_COLOR_INDEX2_EXT:
783 case GL_COLOR_INDEX4_EXT:
784 case GL_COLOR_INDEX8_EXT:
785 case GL_COLOR_INDEX12_EXT:
786 case GL_COLOR_INDEX16_EXT:
787 if(tfmt)
788 (*tfmt)=GR_TEXFMT_P_8;
789 if(ifmt)
790 (*ifmt)=GL_RGBA; /* XXX why is this RGBA? */
791 break;
792 default:
793 fprintf(stderr,
794 "fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
795 fxCloseHardware();
796 exit(-1);
797 break;
798 }
799 }
800
801 static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat,
802 const struct gl_texture_image *image)
803 {
804 if(target != GL_TEXTURE_2D)
805 return GL_FALSE;
806
807 if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
808 NULL,NULL))
809 return GL_FALSE;
810
811 if (image->Border > 0)
812 return GL_FALSE;
813
814 return GL_TRUE;
815 }
816
817
818 /**********************************************************************/
819 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
820 /**********************************************************************/
821
822
823 static void PrintTexture(int w, int h, int c, const GLubyte *data)
824 {
825 int i, j;
826 for (i = 0; i < h; i++) {
827 for (j = 0; j < w; j++) {
828 if (c==2)
829 printf("%02x %02x ", data[0], data[1]);
830 else if (c==3)
831 printf("%02x %02x %02x ", data[0], data[1], data[2]);
832 data += c;
833 }
834 printf("\n");
835 }
836 }
837
838
839 GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
840 GLenum format, GLenum type, const GLvoid *pixels,
841 const struct gl_pixelstore_attrib *packing,
842 struct gl_texture_object *texObj,
843 struct gl_texture_image *texImage,
844 GLboolean *retainInternalCopy)
845 {
846 fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
847
848 if (target != GL_TEXTURE_2D)
849 return GL_FALSE;
850
851 if (!texObj->DriverData)
852 texObj->DriverData = fxAllocTexObjData(fxMesa);
853
854 if (fxIsTexSupported(target, texImage->IntFormat, texImage)) {
855 GrTextureFormat_t gldformat;
856 tfxTexInfo *ti = fxTMGetTexInfo(texObj);
857 tfxMipMapLevel *mml = &ti->mipmapLevel[level];
858 GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride;
859 MesaIntTexFormat intFormat;
860
861 fxTexGetFormat(texImage->IntFormat, &gldformat, NULL);
862
863 fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
864 NULL,NULL, &wScale, &hScale);
865
866 dstWidth = texImage->Width * wScale;
867 dstHeight = texImage->Height * hScale;
868
869 switch (texImage->IntFormat) {
870 case GL_INTENSITY:
871 case GL_INTENSITY4:
872 case GL_INTENSITY8:
873 case GL_INTENSITY12:
874 case GL_INTENSITY16:
875 texelSize = 1;
876 intFormat = MESA_I8;
877 break;
878 case 1:
879 case GL_LUMINANCE:
880 case GL_LUMINANCE4:
881 case GL_LUMINANCE8:
882 case GL_LUMINANCE12:
883 case GL_LUMINANCE16:
884 texelSize = 1;
885 intFormat = MESA_L8;
886 break;
887 case GL_ALPHA:
888 case GL_ALPHA4:
889 case GL_ALPHA8:
890 case GL_ALPHA12:
891 case GL_ALPHA16:
892 texelSize = 1;
893 intFormat = MESA_A8;
894 break;
895 case GL_COLOR_INDEX:
896 case GL_COLOR_INDEX1_EXT:
897 case GL_COLOR_INDEX2_EXT:
898 case GL_COLOR_INDEX4_EXT:
899 case GL_COLOR_INDEX8_EXT:
900 case GL_COLOR_INDEX12_EXT:
901 case GL_COLOR_INDEX16_EXT:
902 texelSize = 1;
903 intFormat = MESA_C8;
904 break;
905 case 2:
906 case GL_LUMINANCE_ALPHA:
907 case GL_LUMINANCE4_ALPHA4:
908 case GL_LUMINANCE6_ALPHA2:
909 case GL_LUMINANCE8_ALPHA8:
910 case GL_LUMINANCE12_ALPHA4:
911 case GL_LUMINANCE12_ALPHA12:
912 case GL_LUMINANCE16_ALPHA16:
913 texelSize = 2;
914 intFormat = MESA_A8_L8;
915 break;
916 case 3:
917 case GL_RGB:
918 case GL_R3_G3_B2:
919 case GL_RGB4:
920 case GL_RGB5:
921 case GL_RGB8:
922 case GL_RGB10:
923 case GL_RGB12:
924 case GL_RGB16:
925 texelSize = 2;
926 intFormat = MESA_R5_G6_B5;
927 break;
928 case 4:
929 case GL_RGBA:
930 case GL_RGBA2:
931 case GL_RGBA4:
932 case GL_RGBA8:
933 case GL_RGB10_A2:
934 case GL_RGBA12:
935 case GL_RGBA16:
936 texelSize = 2;
937 intFormat = MESA_A4_R4_G4_B4;
938 break;
939 case GL_RGB5_A1:
940 texelSize = 2;
941 intFormat = MESA_A1_R5_G5_B5;
942 break;
943 default:
944 gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format");
945 return GL_FALSE;
946 }
947
948 _mesa_set_teximage_component_sizes(intFormat, texImage);
949
950 /*printf("teximage:\n");*/
951 /* allocate new storage for texture image, if needed */
952 if (!mml->data || mml->glideFormat != gldformat ||
953 mml->width != dstWidth || mml->height != dstHeight) {
954 if (mml->data)
955 FREE(mml->data);
956 mml->data = MALLOC(dstWidth * dstHeight * texelSize);
957 if (!mml->data)
958 return GL_FALSE;
959 mml->glideFormat = gldformat;
960 mml->width = dstWidth;
961 mml->height = dstHeight;
962 fxTexInvalidate(ctx, texObj);
963 }
964
965 dstStride = dstWidth * texelSize;
966
967 /* store the texture image */
968 if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data,
969 dstStride,
970 texImage->Width, texImage->Height,
971 format, type, pixels, packing)) {
972 return GL_FALSE;
973 }
974
975
976 if (ti->validated && ti->isInTM) {
977 /*printf("reloadmipmaplevels\n");*/
978 fxTMReloadMipMapLevel(fxMesa, texObj, level);
979 }
980 else {
981 /*printf("invalidate2\n");*/
982 fxTexInvalidate(ctx,texObj);
983 }
984
985 *retainInternalCopy = GL_FALSE;
986 return GL_TRUE;
987 }
988 else {
989 gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
990 return GL_FALSE;
991 }
992 }
993
994
995 GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
996 GLint xoffset, GLint yoffset,
997 GLsizei width, GLsizei height,
998 GLenum format, GLenum type, const GLvoid *pixels,
999 const struct gl_pixelstore_attrib *packing,
1000 struct gl_texture_object *texObj,
1001 struct gl_texture_image *texImage)
1002 {
1003 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1004 tfxTexInfo *ti;
1005 GLint wscale, hscale, dstStride;
1006 tfxMipMapLevel *mml;
1007 GLboolean result;
1008
1009 if (target != GL_TEXTURE_2D)
1010 return GL_FALSE;
1011
1012 if (!texObj->DriverData)
1013 return GL_FALSE;
1014
1015 ti = fxTMGetTexInfo(texObj);
1016 mml = &ti->mipmapLevel[level];
1017
1018 fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL,
1019 NULL,NULL, &wscale, &hscale);
1020
1021 assert(mml->data); /* must have an existing texture image! */
1022
1023 switch (mml->glideFormat) {
1024 case GR_TEXFMT_INTENSITY_8:
1025 dstStride = mml->width;
1026 result = _mesa_convert_texsubimage(MESA_I8, xoffset, yoffset,
1027 mml->width, mml->height, mml->data,
1028 dstStride, width, height,
1029 texImage->Width, texImage->Height,
1030 format, type, pixels, packing);
1031 break;
1032 case GR_TEXFMT_ALPHA_8:
1033 dstStride = mml->width;
1034 result = _mesa_convert_texsubimage(MESA_A8, xoffset, yoffset,
1035 mml->width, mml->height, mml->data,
1036 dstStride, width, height,
1037 texImage->Width, texImage->Height,
1038 format, type, pixels, packing);
1039 break;
1040 case GR_TEXFMT_P_8:
1041 dstStride = mml->width;
1042 result = _mesa_convert_texsubimage(MESA_C8, xoffset, yoffset,
1043 mml->width, mml->height, mml->data,
1044 dstStride, width, height,
1045 texImage->Width, texImage->Height,
1046 format, type, pixels, packing);
1047 break;
1048 case GR_TEXFMT_ALPHA_INTENSITY_88:
1049 dstStride = mml->width * 2;
1050 result = _mesa_convert_texsubimage(MESA_A8_L8, xoffset, yoffset,
1051 mml->width, mml->height, mml->data,
1052 dstStride, width, height,
1053 texImage->Width, texImage->Height,
1054 format, type, pixels, packing);
1055 break;
1056 case GR_TEXFMT_RGB_565:
1057 dstStride = mml->width * 2;
1058 result = _mesa_convert_texsubimage(MESA_R5_G6_B5, xoffset, yoffset,
1059 mml->width, mml->height, mml->data,
1060 dstStride, width, height,
1061 texImage->Width, texImage->Height,
1062 format, type, pixels, packing);
1063 break;
1064 case GR_TEXFMT_ARGB_4444:
1065 dstStride = mml->width * 2;
1066 result = _mesa_convert_texsubimage(MESA_A4_R4_G4_B4, xoffset, yoffset,
1067 mml->width, mml->height, mml->data,
1068 dstStride, width, height,
1069 texImage->Width, texImage->Height,
1070 format, type, pixels, packing);
1071 break;
1072 case GR_TEXFMT_ARGB_1555:
1073 dstStride = mml->width * 2;
1074 result = _mesa_convert_texsubimage(MESA_A1_R5_G5_B5, xoffset, yoffset,
1075 mml->width, mml->height, mml->data,
1076 dstStride, width, height,
1077 texImage->Width, texImage->Height,
1078 format, type, pixels, packing);
1079 break;
1080 default:
1081 gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format");
1082 result = GL_FALSE;
1083 }
1084
1085 if (!result) {
1086 return GL_FALSE;
1087 }
1088
1089 if (ti->validated && ti->isInTM)
1090 fxTMReloadMipMapLevel(fxMesa, texObj, level);
1091 else
1092 fxTexInvalidate(ctx, texObj);
1093
1094 return GL_TRUE;
1095 }
1096
1097
1098
1099 GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level,
1100 const struct gl_texture_object *texObj,
1101 GLenum *formatOut, GLenum *typeOut,
1102 GLboolean *freeImageOut )
1103 {
1104 tfxTexInfo *ti;
1105 tfxMipMapLevel *mml;
1106
1107 if (target != GL_TEXTURE_2D)
1108 return NULL;
1109
1110 if (!texObj->DriverData)
1111 return NULL;
1112
1113 ti = fxTMGetTexInfo(texObj);
1114 mml = &ti->mipmapLevel[level];
1115 if (mml->data) {
1116 MesaIntTexFormat mesaFormat;
1117 GLenum glFormat;
1118 struct gl_texture_image *texImage = texObj->Image[level];
1119 GLint srcStride;
1120
1121 GLubyte *data = (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4);
1122 if (!data)
1123 return NULL;
1124
1125 switch (mml->glideFormat) {
1126 case GR_TEXFMT_INTENSITY_8:
1127 mesaFormat = MESA_I8;
1128 glFormat = GL_INTENSITY;
1129 srcStride = mml->width;
1130 break;
1131 case GR_TEXFMT_ALPHA_INTENSITY_88:
1132 mesaFormat = MESA_A8_L8;
1133 glFormat = GL_LUMINANCE_ALPHA;
1134 srcStride = mml->width;
1135 break;
1136 case GR_TEXFMT_ALPHA_8:
1137 mesaFormat = MESA_A8;
1138 glFormat = GL_ALPHA;
1139 srcStride = mml->width;
1140 break;
1141 case GR_TEXFMT_RGB_565:
1142 mesaFormat = MESA_R5_G6_B5;
1143 glFormat = GL_RGB;
1144 srcStride = mml->width * 2;
1145 break;
1146 case GR_TEXFMT_ARGB_4444:
1147 mesaFormat = MESA_A4_R4_G4_B4;
1148 glFormat = GL_RGBA;
1149 srcStride = mml->width * 2;
1150 break;
1151 case GR_TEXFMT_ARGB_1555:
1152 mesaFormat = MESA_A1_R5_G5_B5;
1153 glFormat = GL_RGBA;
1154 srcStride = mml->width * 2;
1155 break;
1156 case GR_TEXFMT_P_8:
1157 mesaFormat = MESA_C8;
1158 glFormat = GL_COLOR_INDEX;
1159 srcStride = mml->width;
1160 break;
1161 default:
1162 gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage");
1163 return NULL;
1164 }
1165 _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, mml->data,
1166 srcStride, texImage->Width, texImage->Height,
1167 glFormat, data);
1168 *formatOut = glFormat;
1169 *typeOut = GL_UNSIGNED_BYTE;
1170 *freeImageOut = GL_TRUE;
1171 return data;
1172 }
1173 else {
1174 return NULL;
1175 }
1176 }
1177
1178
1179 #else
1180
1181
1182 /*
1183 * Need this to provide at least one external definition.
1184 */
1185
1186 extern int gl_fx_dummy_function_ddtex(void);
1187 int gl_fx_dummy_function_ddtex(void)
1188 {
1189 return 0;
1190 }
1191
1192 #endif /* FX */