Initial revision
[mesa.git] / src / mesa / drivers / glide / fxddtex.c
1 /* -*- mode: C; tab-width:8; -*-
2
3 fxddtex.c - 3Dfx VooDoo Texture mapping functions
4 */
5
6 /*
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * See the file fxapi.c for more informations about authors
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "conf.h"
27 #endif
28
29 #if defined(FX)
30
31 #include "fxdrv.h"
32
33 /************************************************************************/
34 /*************************** Texture Mapping ****************************/
35 /************************************************************************/
36
37 static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj)
38 {
39 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
40 tfxTexInfo *ti;
41
42 fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */
43
44 ti=(tfxTexInfo *)tObj->DriverData;
45 ti->validated=GL_FALSE;
46 fxMesa->new_state|=FX_NEW_TEXTURING;
47 ctx->Driver.RenderStart = fxSetupFXUnits;
48 }
49
50 static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa)
51 {
52 tfxTexInfo *ti;
53 int i;
54
55 if(!(ti=malloc(sizeof(tfxTexInfo)))) {
56 fprintf(stderr,"fx Driver: out of memory !\n");
57 fxCloseHardware();
58 exit(-1);
59 }
60
61 ti->validated=GL_FALSE;
62 ti->tmi.isInTM=GL_FALSE;
63
64 ti->tmi.whichTMU=FX_TMU_NONE;
65
66 ti->tmi.tm[FX_TMU0]=NULL;
67 ti->tmi.tm[FX_TMU1]=NULL;
68
69 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
70 ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
71
72 ti->sClamp=GR_TEXTURECLAMP_WRAP;
73 ti->tClamp=GR_TEXTURECLAMP_WRAP;
74
75 if(fxMesa->haveTwoTMUs) {
76 ti->mmMode=GR_MIPMAP_NEAREST;
77 ti->LODblend=FXTRUE;
78 } else {
79 ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
80 ti->LODblend=FXFALSE;
81 }
82
83 for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
84 ti->tmi.mipmapLevel[i].used=GL_FALSE;
85 ti->tmi.mipmapLevel[i].data=NULL;
86 }
87
88 return ti;
89 }
90
91 void fxDDTexBind(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj)
92 {
93 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
94 tfxTexInfo *ti;
95
96 if (MESA_VERBOSE&VERBOSE_DRIVER) {
97 fprintf(stderr,"fxmesa: fxDDTexBind(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
98 }
99
100 if(target!=GL_TEXTURE_2D)
101 return;
102
103 if(!tObj->DriverData)
104 tObj->DriverData=fxAllocTexObjData(fxMesa);
105
106 ti=(tfxTexInfo *)tObj->DriverData;
107
108 fxMesa->texBindNumber++;
109 ti->tmi.lastTimeUsed=fxMesa->texBindNumber;
110
111 fxMesa->new_state|=FX_NEW_TEXTURING;
112 ctx->Driver.RenderStart = fxSetupFXUnits;
113 }
114
115 void fxDDTexEnv(GLcontext *ctx, GLenum pname, const GLfloat *param)
116 {
117 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
118
119 if (MESA_VERBOSE&VERBOSE_DRIVER) {
120 if(param)
121 fprintf(stderr,"fxmesa: texenv(%x,%x)\n",pname,(GLint)(*param));
122 else
123 fprintf(stderr,"fxmesa: texenv(%x)\n",pname);
124 }
125
126 fxMesa->new_state|=FX_NEW_TEXTURING;
127 ctx->Driver.RenderStart = fxSetupFXUnits;
128 }
129
130 void fxDDTexParam(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj,
131 GLenum pname, const GLfloat *params)
132 {
133 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
134 GLenum param=(GLenum)(GLint)params[0];
135 tfxTexInfo *ti;
136
137 if (MESA_VERBOSE&VERBOSE_DRIVER) {
138 fprintf(stderr,"fxmesa: fxDDTexParam(%d,%x,%x,%x)\n",tObj->Name,(GLuint)tObj->DriverData,pname,param);
139 }
140
141 if(target!=GL_TEXTURE_2D)
142 return;
143
144 if(!tObj->DriverData)
145 tObj->DriverData=fxAllocTexObjData(fxMesa);
146
147 ti=(tfxTexInfo *)tObj->DriverData;
148
149 switch(pname) {
150
151 case GL_TEXTURE_MIN_FILTER:
152 switch(param) {
153 case GL_NEAREST:
154 ti->mmMode=GR_MIPMAP_DISABLE;
155 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
156 ti->LODblend=FXFALSE;
157 break;
158 case GL_LINEAR:
159 ti->mmMode=GR_MIPMAP_DISABLE;
160 ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
161 ti->LODblend=FXFALSE;
162 break;
163 case GL_NEAREST_MIPMAP_NEAREST:
164 ti->mmMode=GR_MIPMAP_NEAREST;
165 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
166 ti->LODblend=FXFALSE;
167 break;
168 case GL_LINEAR_MIPMAP_NEAREST:
169 ti->mmMode=GR_MIPMAP_NEAREST;
170 ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
171 ti->LODblend=FXFALSE;
172 break;
173 case GL_NEAREST_MIPMAP_LINEAR:
174 if(fxMesa->haveTwoTMUs) {
175 ti->mmMode=GR_MIPMAP_NEAREST;
176 ti->LODblend=FXTRUE;
177 } else {
178 ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
179 ti->LODblend=FXFALSE;
180 }
181 ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
182 break;
183 case GL_LINEAR_MIPMAP_LINEAR:
184 if(fxMesa->haveTwoTMUs) {
185 ti->mmMode=GR_MIPMAP_NEAREST;
186 ti->LODblend=FXTRUE;
187 } else {
188 ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
189 ti->LODblend=FXFALSE;
190 }
191 ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
192 break;
193 default:
194 break;
195 }
196 fxTexInvalidate(ctx,tObj);
197 break;
198
199 case GL_TEXTURE_MAG_FILTER:
200 switch(param) {
201 case GL_NEAREST:
202 ti->maxFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
203 break;
204 case GL_LINEAR:
205 ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
206 break;
207 default:
208 break;
209 }
210 fxTexInvalidate(ctx,tObj);
211 break;
212
213 case GL_TEXTURE_WRAP_S:
214 switch(param) {
215 case GL_CLAMP:
216 ti->sClamp=GR_TEXTURECLAMP_CLAMP;
217 break;
218 case GL_REPEAT:
219 ti->sClamp=GR_TEXTURECLAMP_WRAP;
220 break;
221 default:
222 break;
223 }
224 fxMesa->new_state|=FX_NEW_TEXTURING;
225 ctx->Driver.RenderStart = fxSetupFXUnits;
226 break;
227
228 case GL_TEXTURE_WRAP_T:
229 switch(param) {
230 case GL_CLAMP:
231 ti->tClamp=GR_TEXTURECLAMP_CLAMP;
232 break;
233 case GL_REPEAT:
234 ti->tClamp=GR_TEXTURECLAMP_WRAP;
235 break;
236 default:
237 break;
238 }
239 fxMesa->new_state|=FX_NEW_TEXTURING;
240 ctx->Driver.RenderStart = fxSetupFXUnits;
241 break;
242
243 case GL_TEXTURE_BORDER_COLOR:
244 /* TO DO */
245 break;
246
247 case GL_TEXTURE_MIN_LOD:
248 /* TO DO */
249 break;
250 case GL_TEXTURE_MAX_LOD:
251 /* TO DO */
252 break;
253 case GL_TEXTURE_BASE_LEVEL:
254 fxTexInvalidate(ctx,tObj);
255 break;
256 case GL_TEXTURE_MAX_LEVEL:
257 fxTexInvalidate(ctx,tObj);
258 break;
259
260 default:
261 break;
262 }
263 }
264
265 void fxDDTexDel(GLcontext *ctx, struct gl_texture_object *tObj)
266 {
267 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
268 tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
269
270 if (MESA_VERBOSE&VERBOSE_DRIVER) {
271 fprintf(stderr,"fxmesa: fxDDTexDel(%d,%x)\n",tObj->Name,(GLuint)ti);
272 }
273
274 if(!ti)
275 return;
276
277 fxTMFreeTexture(fxMesa,tObj);
278
279 free(ti);
280 tObj->DriverData=NULL;
281
282 ctx->NewState|=NEW_TEXTURING;
283 }
284
285 void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj)
286 {
287 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
288 int i;
289 FxU32 r,g,b,a;
290 tfxTexInfo *ti;
291
292 if(tObj) {
293 if (MESA_VERBOSE&VERBOSE_DRIVER) {
294 fprintf(stderr,"fxmesa: fxDDTexPalette(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
295 }
296
297 if(tObj->PaletteFormat!=GL_RGBA) {
298 #ifndef FX_SILENT
299 fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n");
300 #endif
301 return;
302 }
303
304 if(tObj->PaletteSize>256) {
305 #ifndef FX_SILENT
306 fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n");
307 #endif
308 return;
309 }
310
311 if(!tObj->DriverData)
312 tObj->DriverData=fxAllocTexObjData(fxMesa);
313
314 ti=(tfxTexInfo *)tObj->DriverData;
315
316 for(i=0;i<tObj->PaletteSize;i++) {
317 r=tObj->Palette[i*4];
318 g=tObj->Palette[i*4+1];
319 b=tObj->Palette[i*4+2];
320 a=tObj->Palette[i*4+3];
321 ti->palette.data[i]=(a<<24)|(r<<16)|(g<<8)|b;
322 }
323
324 fxTexInvalidate(ctx,tObj);
325 } else {
326 if (MESA_VERBOSE&VERBOSE_DRIVER) {
327 fprintf(stderr,"fxmesa: fxDDTexPalette(global)\n");
328 }
329 if(ctx->Texture.PaletteFormat!=GL_RGBA) {
330 #ifndef FX_SILENT
331 fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n");
332 #endif
333 return;
334 }
335
336 if(ctx->Texture.PaletteSize>256) {
337 #ifndef FX_SILENT
338 fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n");
339 #endif
340 return;
341 }
342
343 for(i=0;i<ctx->Texture.PaletteSize;i++) {
344 r=ctx->Texture.Palette[i*4];
345 g=ctx->Texture.Palette[i*4+1];
346 b=ctx->Texture.Palette[i*4+2];
347 a=ctx->Texture.Palette[i*4+3];
348 fxMesa->glbPalette.data[i]=(a<<24)|(r<<16)|(g<<8)|b;
349 }
350
351 fxMesa->new_state|=FX_NEW_TEXTURING;
352 ctx->Driver.RenderStart = fxSetupFXUnits;
353 }
354 }
355
356 void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state)
357 {
358 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
359
360 if (MESA_VERBOSE&VERBOSE_DRIVER) {
361 fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state);
362 }
363
364 if(state) {
365 fxMesa->haveGlobalPaletteTexture=1;
366
367 FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette));
368 if (fxMesa->haveTwoTMUs)
369 FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette));
370 } else {
371 fxMesa->haveGlobalPaletteTexture=0;
372
373 if((ctx->Texture.Unit[0].Current==ctx->Texture.Unit[0].CurrentD[2]) &&
374 (ctx->Texture.Unit[0].Current!=NULL)) {
375 struct gl_texture_object *tObj=ctx->Texture.Unit[0].Current;
376 tfxTexInfo *ti;
377
378 if(!tObj->DriverData)
379 tObj->DriverData=fxAllocTexObjData(fxMesa);
380
381 ti=(tfxTexInfo *)tObj->DriverData;
382
383 fxTexInvalidate(ctx,tObj);
384 }
385 }
386 }
387
388 static int logbase2(int n)
389 {
390 GLint i = 1;
391 GLint log2 = 0;
392
393 if (n<0) {
394 return -1;
395 }
396
397 while (n > i) {
398 i *= 2;
399 log2++;
400 }
401 if (i != n) {
402 return -1;
403 }
404 else {
405 return log2;
406 }
407 }
408
409 /* Need different versions for different cpus.
410 */
411 #define INT_TRICK(l2) (0x800000 * l2)
412
413
414 int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
415 float *sscale, float *tscale,
416 int *i_sscale, int *i_tscale,
417 int *wscale, int *hscale)
418 {
419
420 static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
421 GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
422
423 int logw,logh,ws,hs;
424 GrLOD_t l;
425 GrAspectRatio_t aspectratio;
426 float s,t;
427 int is,it;
428
429 logw=logbase2(w);
430 logh=logbase2(h);
431
432 switch(logw-logh) {
433 case 0:
434 aspectratio=GR_ASPECT_1x1;
435 l=lod[8-logw];
436 s=t=256.0f;
437 is=it=INT_TRICK(8);
438 ws=hs=1;
439 break;
440 case 1:
441 aspectratio=GR_ASPECT_2x1;
442 l=lod[8-logw];
443 s=256.0f;
444 t=128.0f;
445 is=INT_TRICK(8);it=INT_TRICK(7);
446 ws=1;
447 hs=1;
448 break;
449 case 2:
450 aspectratio=GR_ASPECT_4x1;
451 l=lod[8-logw];
452 s=256.0f;
453 t=64.0f;
454 is=INT_TRICK(8);it=INT_TRICK(6);
455 ws=1;
456 hs=1;
457 break;
458 case 3:
459 aspectratio=GR_ASPECT_8x1;
460 l=lod[8-logw];
461 s=256.0f;
462 t=32.0f;
463 is=INT_TRICK(8);it=INT_TRICK(5);
464 ws=1;
465 hs=1;
466 break;
467 case 4:
468 aspectratio=GR_ASPECT_8x1;
469 l=lod[8-logw];
470 s=256.0f;
471 t=32.0f;
472 is=INT_TRICK(8);it=INT_TRICK(5);
473 ws=1;
474 hs=2;
475 break;
476 case 5:
477 aspectratio=GR_ASPECT_8x1;
478 l=lod[8-logw];
479 s=256.0f;
480 t=32.0f;
481 is=INT_TRICK(8);it=INT_TRICK(5);
482 ws=1;
483 hs=4;
484 break;
485 case 6:
486 aspectratio=GR_ASPECT_8x1;
487 l=lod[8-logw];
488 s=256.0f;
489 t=32.0f;
490 is=INT_TRICK(8);it=INT_TRICK(5);
491 ws=1;
492 hs=8;
493 break;
494 case 7:
495 aspectratio=GR_ASPECT_8x1;
496 l=lod[8-logw];
497 s=256.0f;
498 t=32.0f;
499 is=INT_TRICK(8);it=INT_TRICK(5);
500 ws=1;
501 hs=16;
502 break;
503 case 8:
504 aspectratio=GR_ASPECT_8x1;
505 l=lod[8-logw];
506 s=256.0f;
507 t=32.0f;
508 is=INT_TRICK(8);it=INT_TRICK(5);
509 ws=1;
510 hs=32;
511 break;
512 case -1:
513 aspectratio=GR_ASPECT_1x2;
514 l=lod[8-logh];
515 s=128.0f;
516 t=256.0f;
517 is=INT_TRICK(7);it=INT_TRICK(8);
518 ws=1;
519 hs=1;
520 break;
521 case -2:
522 aspectratio=GR_ASPECT_1x4;
523 l=lod[8-logh];
524 s=64.0f;
525 t=256.0f;
526 is=INT_TRICK(6);it=INT_TRICK(8);
527 ws=1;
528 hs=1;
529 break;
530 case -3:
531 aspectratio=GR_ASPECT_1x8;
532 l=lod[8-logh];
533 s=32.0f;
534 t=256.0f;
535 is=INT_TRICK(5);it=INT_TRICK(8);
536 ws=1;
537 hs=1;
538 break;
539 case -4:
540 aspectratio=GR_ASPECT_1x8;
541 l=lod[8-logh];
542 s=32.0f;
543 t=256.0f;
544 is=INT_TRICK(5);it=INT_TRICK(8);
545 ws=2;
546 hs=1;
547 break;
548 case -5:
549 aspectratio=GR_ASPECT_1x8;
550 l=lod[8-logh];
551 s=32.0f;
552 t=256.0f;
553 is=INT_TRICK(5);it=INT_TRICK(8);
554 ws=4;
555 hs=1;
556 break;
557 case -6:
558 aspectratio=GR_ASPECT_1x8;
559 l=lod[8-logh];
560 s=32.0f;
561 t=256.0f;
562 is=INT_TRICK(5);it=INT_TRICK(8);
563 ws=8;
564 hs=1;
565 break;
566 case -7:
567 aspectratio=GR_ASPECT_1x8;
568 l=lod[8-logh];
569 s=32.0f;
570 t=256.0f;
571 is=INT_TRICK(5);it=INT_TRICK(8);
572 ws=16;
573 hs=1;
574 break;
575 case -8:
576 aspectratio=GR_ASPECT_1x8;
577 l=lod[8-logh];
578 s=32.0f;
579 t=256.0f;
580 is=INT_TRICK(5);it=INT_TRICK(8);
581 ws=32;
582 hs=1;
583 break;
584 default:
585 return 0;
586 break;
587 }
588
589 if(lodlevel)
590 (*lodlevel)=l;
591
592 if(ar)
593 (*ar)=aspectratio;
594
595 if(sscale)
596 (*sscale)=s;
597
598 if(tscale)
599 (*tscale)=t;
600
601 if(wscale)
602 (*wscale)=ws;
603
604 if(hscale)
605 (*hscale)=hs;
606
607 if (i_sscale)
608 *i_sscale = is;
609
610 if (i_tscale)
611 *i_tscale = it;
612
613
614 return 1;
615 }
616
617 void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
618 {
619 switch(glformat) {
620 case 1:
621 case GL_LUMINANCE:
622 case GL_LUMINANCE4:
623 case GL_LUMINANCE8:
624 case GL_LUMINANCE12:
625 case GL_LUMINANCE16:
626 if(tfmt)
627 (*tfmt)=GR_TEXFMT_INTENSITY_8;
628 if(ifmt)
629 (*ifmt)=GL_LUMINANCE;
630 break;
631 case 2:
632 case GL_LUMINANCE_ALPHA:
633 case GL_LUMINANCE4_ALPHA4:
634 case GL_LUMINANCE6_ALPHA2:
635 case GL_LUMINANCE8_ALPHA8:
636 case GL_LUMINANCE12_ALPHA4:
637 case GL_LUMINANCE12_ALPHA12:
638 case GL_LUMINANCE16_ALPHA16:
639 if(tfmt)
640 (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
641 if(ifmt)
642 (*ifmt)=GL_LUMINANCE_ALPHA;
643 break;
644 case GL_INTENSITY:
645 case GL_INTENSITY4:
646 case GL_INTENSITY8:
647 case GL_INTENSITY12:
648 case GL_INTENSITY16:
649 if(tfmt)
650 (*tfmt)=GR_TEXFMT_ALPHA_8;
651 if(ifmt)
652 (*ifmt)=GL_INTENSITY;
653 break;
654 case GL_ALPHA:
655 case GL_ALPHA4:
656 case GL_ALPHA8:
657 case GL_ALPHA12:
658 case GL_ALPHA16:
659 if(tfmt)
660 (*tfmt)=GR_TEXFMT_ALPHA_8;
661 if(ifmt)
662 (*ifmt)=GL_ALPHA;
663 break;
664 case 3:
665 case GL_RGB:
666 case GL_R3_G3_B2:
667 case GL_RGB4:
668 case GL_RGB5:
669 case GL_RGB8:
670 case GL_RGB10:
671 case GL_RGB12:
672 case GL_RGB16:
673 if(tfmt)
674 (*tfmt)=GR_TEXFMT_RGB_565;
675 if(ifmt)
676 (*ifmt)=GL_RGB;
677 break;
678 case 4:
679 case GL_RGBA:
680 case GL_RGBA2:
681 case GL_RGBA4:
682 case GL_RGB5_A1:
683 case GL_RGBA8:
684 case GL_RGB10_A2:
685 case GL_RGBA12:
686 case GL_RGBA16:
687 if(tfmt)
688 (*tfmt)=GR_TEXFMT_ARGB_4444;
689 if(ifmt)
690 (*ifmt)=GL_RGBA;
691 break;
692 case GL_COLOR_INDEX:
693 case GL_COLOR_INDEX1_EXT:
694 case GL_COLOR_INDEX2_EXT:
695 case GL_COLOR_INDEX4_EXT:
696 case GL_COLOR_INDEX8_EXT:
697 case GL_COLOR_INDEX12_EXT:
698 case GL_COLOR_INDEX16_EXT:
699 if(tfmt)
700 (*tfmt)=GR_TEXFMT_P_8;
701 if(ifmt)
702 (*ifmt)=GL_RGBA;
703 break;
704 default:
705 fprintf(stderr,"fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
706 fxCloseHardware();
707 exit(-1);
708 break;
709 }
710 }
711
712 static int fxIsTexSupported(GLenum target, GLint internalFormat,
713 const struct gl_texture_image *image)
714 {
715 if(target!=GL_TEXTURE_2D)
716 return GL_FALSE;
717
718 switch(internalFormat) {
719 case GL_INTENSITY:
720 case GL_INTENSITY4:
721 case GL_INTENSITY8:
722 case GL_INTENSITY12:
723 case GL_INTENSITY16:
724 case 1:
725 case GL_LUMINANCE:
726 case GL_LUMINANCE4:
727 case GL_LUMINANCE8:
728 case GL_LUMINANCE12:
729 case GL_LUMINANCE16:
730 case 2:
731 case GL_LUMINANCE_ALPHA:
732 case GL_LUMINANCE4_ALPHA4:
733 case GL_LUMINANCE6_ALPHA2:
734 case GL_LUMINANCE8_ALPHA8:
735 case GL_LUMINANCE12_ALPHA4:
736 case GL_LUMINANCE12_ALPHA12:
737 case GL_LUMINANCE16_ALPHA16:
738 case GL_ALPHA:
739 case GL_ALPHA4:
740 case GL_ALPHA8:
741 case GL_ALPHA12:
742 case GL_ALPHA16:
743 case 3:
744 case GL_RGB:
745 case GL_R3_G3_B2:
746 case GL_RGB4:
747 case GL_RGB5:
748 case GL_RGB8:
749 case GL_RGB10:
750 case GL_RGB12:
751 case GL_RGB16:
752 case 4:
753 case GL_RGBA:
754 case GL_RGBA2:
755 case GL_RGBA4:
756 case GL_RGB5_A1:
757 case GL_RGBA8:
758 case GL_RGB10_A2:
759 case GL_RGBA12:
760 case GL_RGBA16:
761 case GL_COLOR_INDEX:
762 case GL_COLOR_INDEX1_EXT:
763 case GL_COLOR_INDEX2_EXT:
764 case GL_COLOR_INDEX4_EXT:
765 case GL_COLOR_INDEX8_EXT:
766 case GL_COLOR_INDEX12_EXT:
767 case GL_COLOR_INDEX16_EXT:
768 break;
769 default:
770 return GL_FALSE;
771 }
772
773 if(image->Width>256)
774 return GL_FALSE;
775
776 if(image->Height>256)
777 return GL_FALSE;
778
779 if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
780 NULL,NULL))
781 return GL_FALSE;
782
783 return GL_TRUE;
784 }
785
786 static void fxTexBuildImageMap(const struct gl_texture_image *image,
787 GLint internalFormat, unsigned short **dest,
788 GLboolean *istranslate)
789 {
790 unsigned short *src;
791 unsigned char *data;
792 int x,y,w,h,wscale,hscale,idx;
793
794 fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
795 &wscale,&hscale);
796 w=image->Width*wscale;
797 h=image->Height*hscale;
798
799 data=image->Data;
800 switch(internalFormat) {
801 case GL_INTENSITY:
802 case GL_INTENSITY4:
803 case GL_INTENSITY8:
804 case GL_INTENSITY12:
805 case GL_INTENSITY16:
806 case 1:
807 case GL_LUMINANCE:
808 case GL_LUMINANCE4:
809 case GL_LUMINANCE8:
810 case GL_LUMINANCE12:
811 case GL_LUMINANCE16:
812 case GL_ALPHA:
813 case GL_ALPHA4:
814 case GL_ALPHA8:
815 case GL_ALPHA12:
816 case GL_ALPHA16:
817 case GL_COLOR_INDEX:
818 case GL_COLOR_INDEX1_EXT:
819 case GL_COLOR_INDEX2_EXT:
820 case GL_COLOR_INDEX4_EXT:
821 case GL_COLOR_INDEX8_EXT:
822 case GL_COLOR_INDEX12_EXT:
823 case GL_COLOR_INDEX16_EXT:
824 /* Optimized for GLQuake */
825
826 if(wscale==hscale==1) {
827 (*istranslate)=GL_FALSE;
828
829 (*dest)=(unsigned short *)data;
830 } else {
831 unsigned char *srcb;
832
833 (*istranslate)=GL_TRUE;
834
835 if(!(*dest)) {
836 if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned char)*w*h))) {
837 fprintf(stderr,"fx Driver: out of memory !\n");
838 fxCloseHardware();
839 exit(-1);
840 }
841 } else
842 src=(*dest);
843
844 srcb=(unsigned char *)src;
845
846 for(y=0;y<h;y++)
847 for(x=0;x<w;x++) {
848 idx=(x/wscale+(y/hscale)*(w/wscale));
849 srcb[x+y*w]=data[idx];
850 }
851 }
852 break;
853 case 2:
854 case GL_LUMINANCE_ALPHA:
855 case GL_LUMINANCE4_ALPHA4:
856 case GL_LUMINANCE6_ALPHA2:
857 case GL_LUMINANCE8_ALPHA8:
858 case GL_LUMINANCE12_ALPHA4:
859 case GL_LUMINANCE12_ALPHA12:
860 case GL_LUMINANCE16_ALPHA16:
861 (*istranslate)=GL_TRUE;
862
863 if(!(*dest)) {
864 if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
865 fprintf(stderr,"fx Driver: out of memory !\n");
866 fxCloseHardware();
867 exit(-1);
868 }
869 } else
870 src=(*dest);
871
872 if(wscale==hscale==1) {
873 int i=0;
874 int lenght=h*w;
875 unsigned short a,l;
876
877 while(i++<lenght) {
878 l=*data++;
879 a=*data++;
880
881 *src++=(a << 8) | l;
882 }
883 } else {
884 unsigned short a,l;
885
886 for(y=0;y<h;y++)
887 for(x=0;x<w;x++) {
888 idx=(x/wscale+(y/hscale)*(w/wscale))*2;
889 l=data[idx];
890 a=data[idx+1];
891
892 src[x+y*w]=(a << 8) | l;
893 }
894 }
895 break;
896 case 3:
897 case GL_RGB:
898 case GL_R3_G3_B2:
899 case GL_RGB4:
900 case GL_RGB5:
901 case GL_RGB8:
902 case GL_RGB10:
903 case GL_RGB12:
904 case GL_RGB16:
905 (*istranslate)=GL_TRUE;
906
907 if(!(*dest)) {
908 if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
909 fprintf(stderr,"fx Driver: out of memory !\n");
910 fxCloseHardware();
911 exit(-1);
912 }
913 } else
914 src=(*dest);
915
916 if(wscale==hscale==1) {
917 int i=0;
918 int lenght=h*w;
919 unsigned short r,g,b;
920
921 while(i++<lenght) {
922 r=*data++;
923 g=*data++;
924 b=*data++;
925
926 *src++=((0xf8 & r) << (11-3)) |
927 ((0xfc & g) << (5-3+1)) |
928 ((0xf8 & b) >> 3);
929 }
930 } else {
931 unsigned short r,g,b;
932
933 for(y=0;y<h;y++)
934 for(x=0;x<w;x++) {
935 idx=(x/wscale+(y/hscale)*(w/wscale))*3;
936 r=data[idx];
937 g=data[idx+1];
938 b=data[idx+2];
939
940 src[x+y*w]=((0xf8 & r) << (11-3)) |
941 ((0xfc & g) << (5-3+1)) |
942 ((0xf8 & b) >> 3);
943 }
944 }
945 break;
946 case 4:
947 case GL_RGBA:
948 case GL_RGBA2:
949 case GL_RGBA4:
950 case GL_RGB5_A1:
951 case GL_RGBA8:
952 case GL_RGB10_A2:
953 case GL_RGBA12:
954 case GL_RGBA16:
955 (*istranslate)=GL_TRUE;
956
957 if(!(*dest)) {
958 if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
959 fprintf(stderr,"fx Driver: out of memory !\n");
960 fxCloseHardware();
961 exit(-1);
962 }
963 } else
964 src=(*dest);
965
966 if(wscale==hscale==1) {
967 int i=0;
968 int lenght=h*w;
969 unsigned short r,g,b,a;
970
971 while(i++<lenght) {
972 r=*data++;
973 g=*data++;
974 b=*data++;
975 a=*data++;
976
977 *src++=((0xf0 & a) << 8) |
978 ((0xf0 & r) << 4) |
979 (0xf0 & g) |
980 ((0xf0 & b) >> 4);
981 }
982 } else {
983 unsigned short r,g,b,a;
984
985 for(y=0;y<h;y++)
986 for(x=0;x<w;x++) {
987 idx=(x/wscale+(y/hscale)*(w/wscale))*4;
988 r=data[idx];
989 g=data[idx+1];
990 b=data[idx+2];
991 a=data[idx+3];
992
993 src[x+y*w]=((0xf0 & a) << 8) |
994 ((0xf0 & r) << 4) |
995 (0xf0 & g) |
996 ((0xf0 & b) >> 4);
997 }
998 }
999 break;
1000 default:
1001 fprintf(stderr,"fx Driver: wrong internalFormat in texbuildimagemap()\n");
1002 fxCloseHardware();
1003 exit(-1);
1004 break;
1005 }
1006 }
1007
1008 void fxDDTexImg(GLcontext *ctx, GLenum target,
1009 struct gl_texture_object *tObj, GLint level, GLint internalFormat,
1010 const struct gl_texture_image *image)
1011 {
1012 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1013 tfxTexInfo *ti;
1014
1015 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1016 fprintf(stderr,"fxmesa: (%d) fxDDTexImg(...,%d,%x,%d,%d...)\n",tObj->Name,
1017 target,internalFormat,image->Width,image->Height);
1018 }
1019
1020 if(target!=GL_TEXTURE_2D)
1021 return;
1022
1023 if(!tObj->DriverData)
1024 tObj->DriverData=fxAllocTexObjData(fxMesa);
1025
1026 ti=(tfxTexInfo *)tObj->DriverData;
1027
1028 if(fxIsTexSupported(target,internalFormat,image)) {
1029 GrTextureFormat_t gldformat;
1030 tfxMipMapLevel *mml=&ti->tmi.mipmapLevel[level];
1031
1032 fxTexGetFormat(internalFormat,&gldformat,NULL);
1033
1034 if(mml->used) {
1035 if((mml->glideFormat==gldformat) &&
1036 (mml->width==image->Width) &&
1037 (mml->height==image->Height)) {
1038 fxTexBuildImageMap(image,internalFormat,&(mml->data),
1039 &(mml->translated));
1040
1041 if(ti->validated && ti->tmi.isInTM)
1042 fxTMReloadMipMapLevel(fxMesa,tObj,level);
1043 else
1044 fxTexInvalidate(ctx,tObj);
1045
1046 return;
1047 } else {
1048 if(mml->translated)
1049 free(mml->data);
1050 mml->data=NULL;
1051 }
1052 }
1053
1054 mml->glideFormat=gldformat;
1055 mml->width=image->Width;
1056 mml->height=image->Height;
1057 mml->used=GL_TRUE;
1058
1059 fxTexBuildImageMap(image,internalFormat,&(mml->data),
1060 &(mml->translated));
1061
1062 fxTexInvalidate(ctx,tObj);
1063 }
1064 #ifndef FX_SILENT
1065 else
1066 fprintf(stderr,"fx Driver: unsupported texture in fxDDTexImg()\n");
1067 #endif
1068 }
1069
1070 static void fxTexBuildSubImageMap(const struct gl_texture_image *image,
1071 GLint internalFormat,
1072 GLint xoffset, GLint yoffset, GLint width, GLint height,
1073 unsigned short *destimg)
1074 {
1075 fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
1076 NULL,NULL);
1077
1078 switch(internalFormat) {
1079 case GL_INTENSITY:
1080 case GL_INTENSITY4:
1081 case GL_INTENSITY8:
1082 case GL_INTENSITY12:
1083 case GL_INTENSITY16:
1084 case 1:
1085 case GL_LUMINANCE:
1086 case GL_LUMINANCE4:
1087 case GL_LUMINANCE8:
1088 case GL_LUMINANCE12:
1089 case GL_LUMINANCE16:
1090 case GL_ALPHA:
1091 case GL_ALPHA4:
1092 case GL_ALPHA8:
1093 case GL_ALPHA12:
1094 case GL_ALPHA16:
1095 case GL_COLOR_INDEX:
1096 case GL_COLOR_INDEX1_EXT:
1097 case GL_COLOR_INDEX2_EXT:
1098 case GL_COLOR_INDEX4_EXT:
1099 case GL_COLOR_INDEX8_EXT:
1100 case GL_COLOR_INDEX12_EXT:
1101 case GL_COLOR_INDEX16_EXT:
1102 {
1103
1104 int y;
1105 unsigned char *bsrc,*bdst;
1106
1107 bsrc=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset));
1108 bdst=((unsigned char *)destimg)+(yoffset*image->Width+xoffset);
1109
1110 for(y=0;y<height;y++) {
1111 MEMCPY(bdst,bsrc,width);
1112 bsrc += image->Width;
1113 bdst += image->Width;
1114 }
1115 }
1116 break;
1117 case 2:
1118 case GL_LUMINANCE_ALPHA:
1119 case GL_LUMINANCE4_ALPHA4:
1120 case GL_LUMINANCE6_ALPHA2:
1121 case GL_LUMINANCE8_ALPHA8:
1122 case GL_LUMINANCE12_ALPHA4:
1123 case GL_LUMINANCE12_ALPHA12:
1124 case GL_LUMINANCE16_ALPHA16:
1125 {
1126 int x,y;
1127 unsigned char *src;
1128 unsigned short *dst,a,l;
1129 int simgw,dimgw;
1130
1131 src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*2);
1132 dst=destimg+(yoffset*image->Width+xoffset);
1133
1134 simgw=(image->Width-width)*2;
1135 dimgw=image->Width-width;
1136 for(y=0;y<height;y++) {
1137 for(x=0;x<width;x++) {
1138 l=*src++;
1139 a=*src++;
1140 *dst++=(a << 8) | l;
1141 }
1142
1143 src += simgw;
1144 dst += dimgw;
1145 }
1146 }
1147 break;
1148 case 3:
1149 case GL_RGB:
1150 case GL_R3_G3_B2:
1151 case GL_RGB4:
1152 case GL_RGB5:
1153 case GL_RGB8:
1154 case GL_RGB10:
1155 case GL_RGB12:
1156 case GL_RGB16:
1157 {
1158 int x,y;
1159 unsigned char *src;
1160 unsigned short *dst,r,g,b;
1161 int simgw,dimgw;
1162
1163 src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*3);
1164 dst=destimg+(yoffset*image->Width+xoffset);
1165
1166 simgw=(image->Width-width)*3;
1167 dimgw=image->Width-width;
1168 for(y=0;y<height;y++) {
1169 for(x=0;x<width;x++) {
1170 r=*src++;
1171 g=*src++;
1172 b=*src++;
1173 *dst++=((0xf8 & r) << (11-3)) |
1174 ((0xfc & g) << (5-3+1)) |
1175 ((0xf8 & b) >> 3);
1176 }
1177
1178 src += simgw;
1179 dst += dimgw;
1180 }
1181 }
1182 break;
1183 case 4:
1184 case GL_RGBA:
1185 case GL_RGBA2:
1186 case GL_RGBA4:
1187 case GL_RGB5_A1:
1188 case GL_RGBA8:
1189 case GL_RGB10_A2:
1190 case GL_RGBA12:
1191 case GL_RGBA16:
1192 {
1193 int x,y;
1194 unsigned char *src;
1195 unsigned short *dst,r,g,b,a;
1196 int simgw,dimgw;
1197
1198 src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4);
1199 dst=destimg+(yoffset*image->Width+xoffset);
1200
1201 simgw=(image->Width-width)*4;
1202 dimgw=image->Width-width;
1203 for(y=0;y<height;y++) {
1204 for(x=0;x<width;x++) {
1205 r=*src++;
1206 g=*src++;
1207 b=*src++;
1208 a=*src++;
1209 *dst++=((0xf0 & a) << 8) |
1210 ((0xf0 & r) << 4) |
1211 (0xf0 & g) |
1212 ((0xf0 & b) >> 4);
1213 }
1214
1215 src += simgw;
1216 dst += dimgw;
1217 }
1218 }
1219 break;
1220 default:
1221 fprintf(stderr,"fx Driver: wrong internalFormat in fxTexBuildSubImageMap()\n");
1222 fxCloseHardware();
1223 exit(-1);
1224 break;
1225 }
1226 }
1227
1228
1229 void fxDDTexSubImg(GLcontext *ctx, GLenum target,
1230 struct gl_texture_object *tObj, GLint level,
1231 GLint xoffset, GLint yoffset, GLint width, GLint height,
1232 GLint internalFormat, const struct gl_texture_image *image)
1233 {
1234 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
1235 tfxTexInfo *ti;
1236 GrTextureFormat_t gldformat;
1237 int wscale,hscale;
1238 tfxMipMapLevel *mml;
1239
1240 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1241 fprintf(stderr,"fxmesa: (%d) fxDDTexSubImg(...,%d,%x,%d,%d...)\n",tObj->Name,
1242 target,internalFormat,image->Width,image->Height);
1243 }
1244
1245 if(target!=GL_TEXTURE_2D)
1246 return;
1247
1248 if(!tObj->DriverData)
1249 return;
1250
1251 ti=(tfxTexInfo *)tObj->DriverData;
1252 mml=&ti->tmi.mipmapLevel[level];
1253
1254 fxTexGetFormat(internalFormat,&gldformat,NULL);
1255
1256 if(mml->glideFormat!=gldformat) {
1257 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1258 fprintf(stderr,"fxmesa: ti->info.format!=format in fxDDTexSubImg()\n");
1259 }
1260 fxDDTexImg(ctx,target,tObj,level,internalFormat,image);
1261
1262 return;
1263 }
1264
1265 fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,&wscale,&hscale);
1266
1267 if((wscale!=1) || (hscale!=1)) {
1268 if (MESA_VERBOSE&VERBOSE_DRIVER) {
1269 fprintf(stderr,"fxmesa: (wscale!=1) || (hscale!=1) in fxDDTexSubImg()\n");
1270 }
1271 fxDDTexImg(ctx,target,tObj,level,internalFormat,image);
1272
1273 return;
1274 }
1275
1276 if(mml->translated)
1277 fxTexBuildSubImageMap(image,internalFormat,xoffset,yoffset,
1278 width,height,mml->data);
1279
1280 if(ti->validated && ti->tmi.isInTM)
1281 fxTMReloadSubMipMapLevel(fxMesa,tObj,level,yoffset,height);
1282 else
1283 fxTexInvalidate(ctx,tObj);
1284 }
1285
1286
1287 #else
1288
1289
1290 /*
1291 * Need this to provide at least one external definition.
1292 */
1293
1294 int gl_fx_dummy_function_ddtex(void)
1295 {
1296 return 0;
1297 }
1298
1299 #endif /* FX */