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