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