GLES2GLIDE: Disabled Texture optim, it's full of bug...
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glitch64 / textures.cpp
CommitLineData
98e75f2d 1/*
2* Glide64 - Glide video plugin for Nintendo 64 emulators.
3* Copyright (c) 2002 Dave2001
4* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#ifdef _WIN32
22#include <windows.h>
23#else // _WIN32
24#include <stdlib.h>
25#endif // _WIN32
26#include "glide.h"
27#include "main.h"
28#include <stdio.h>
29
30#include "../Glide64/ticks.h"
31
32/* Napalm extensions to GrTextureFormat_t */
33#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
34#define GR_TEXFMT_ARGB_8888 0x12
35#define GR_TEXFMT_YUYV_422 0x13
36#define GR_TEXFMT_UYVY_422 0x14
37#define GR_TEXFMT_AYUV_444 0x15
38#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
39#define GR_TEXFMT_ARGB_CMP_DXT2 0x17
40#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
41#define GR_TEXFMT_ARGB_CMP_DXT4 0x19
42#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
43#define GR_TEXTFMT_RGB_888 0xFF
44
45int TMU_SIZE = 8*2048*2048;
46static unsigned char* texture = NULL;
47
48int packed_pixels_support = -1;
49int ati_sucks = -1;
50float largest_supported_anisotropy = 1.0f;
51
52#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
53#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
54#endif
55
56int tex0_width, tex0_height, tex1_width, tex1_height;
57float lambda;
58
59static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
60static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
61
62unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
63
4d186acb 64//#define TEXBSP
98e75f2d 65#ifdef TEXBSP
66typedef struct _texbsp
67{
68 unsigned int id;
69 struct _texbsp *left;
70 struct _texbsp *right;
71} texbsp;
72
98e75f2d 73static int nbTex = 0;
74static texbsp *list = NULL;
75#else
76typedef struct _texlist
77{
78 unsigned int id;
79 struct _texlist *next;
80} texlist;
81
82static int nbTex = 0;
83static texlist *list = NULL;
84#endif
85
86#ifdef _WIN32
87extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
88extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
89extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
90#endif
4d186acb 91#ifdef TEXBSP
92void print_tex(bool detail=false)
98e75f2d 93{
4d186acb 94 texbsp *bsp = list;
95 int i=0;
96 if (!bsp) {
97 printf("empty list (%s)", (nbTex==i)?"OK":"/!\\ KO");
98 return;
99 }
100 bool ok=true;
101 while (bsp->left) bsp=bsp->left;
102 do {
103 i++;
104 if (detail) printf("%u\t", bsp->id);
105 if (bsp->right) if (bsp->id>=bsp->right->id) ok=false;
106 bsp=bsp->right;
107 } while (bsp);
108 printf("%s%s (taille %i/%i %s)\n",(detail)?"\n":"", (ok)?"OK":"KO", nbTex, i, (nbTex==i)?"OK":"/!\\ KO");
109 if (nbTex!=i && !detail) print_tex(true);
98e75f2d 110}
98e75f2d 111#endif
112void remove_tex(unsigned int idmin, unsigned int idmax)
113{
114#ifdef TEXBSP
4d186acb 115if ((idmin==18449 && idmax==22545) || (idmin==28689 || idmax==30737)) {printf("delete %u->%u, list=", idmin, idmax); print_tex(true);}
98e75f2d 116 GLuint texlist[nbTex];
117 int nbdel = 0;
118 // 1st look at initial point that is <= at idmin and than go right until id > idmax. Deleting all in between, and reattach list is needed
119 texbsp *aux = list;
120 bool reattach = false;
121 texbsp *debut, *fin, *temp;
122 // Empty list, easy
123 if (list==NULL) return;
124 if ((idmin==0x00000000) && (idmax==0xffffffff)) {
125 // delete everything, quite easy
4d186acb 126 debut = list->left;
127 fin = list->right;
128 while ((debut) || (fin)) {
98e75f2d 129 if (debut) {
130 texlist[nbdel++]=debut->id;
4d186acb 131 temp = debut->left;
98e75f2d 132 free(debut);
133 debut = temp;
134 }
135 if (fin) {
136 texlist[nbdel++]=fin->id;
4d186acb 137 temp = fin->right;
98e75f2d 138 free(fin);
139 fin = temp;
140 }
141 }
142 texlist[nbdel++]=list->id;
143 free(list);
144 list=NULL;
145 glDeleteTextures(nbdel, texlist);
146 nbTex = 0;
4d186acb 147//print_tex();
98e75f2d 148 return;
149 }
150 // General case, range delete
151 // find starting point.
152 debut = list;
4d186acb 153 while ((debut->id > idmin) && (debut->left!=NULL)) {
154 debut = debut->left;
98e75f2d 155 }
4d186acb 156 while ((debut->right!=NULL) && (debut->right->id <= idmin)) {
157 debut = debut->right;
98e75f2d 158 }
4d186acb 159 fin = debut->left;
98e75f2d 160 // and now delete
161 while ((debut!=NULL) && (debut->id >= idmin) && (debut->id < idmax))
162 {
4d186acb 163 temp = debut->right;
98e75f2d 164 texlist[nbdel++]=debut->id;
165 free(debut);
166 debut=temp;
167 }
4d186acb 168 if (!nbdel) return;
98e75f2d 169 // rechain the list
4d186acb 170 if (fin) fin->right = debut;
171 if (debut) debut->left = fin;
98e75f2d 172 if (debut) list = debut; else list = fin; //change ankor
98e75f2d 173 nbTex -= nbdel;
4d186acb 174 glDeleteTextures(nbdel, texlist);
175printf("deleted (%i) %u->%u, list=", nbdel, idmin, idmax); print_tex();
98e75f2d 176 return;
177#else
178 unsigned int *t;
179 int n = 0;
180 texlist *aux = list;
181 int sz = nbTex;
182 if (aux == NULL) return;
183 t = (unsigned int*)malloc(sz * sizeof(int));
184 while (aux && aux->id >= idmin && aux->id < idmax)
185 {
186 if (n >= sz)
187 t = (unsigned int *) realloc(t, ++sz*sizeof(int));
188 t[n++] = aux->id;
189 aux = aux->next;
190 free(list);
191 list = aux;
192 nbTex--;
193 }
194 while (aux != NULL && aux->next != NULL)
195 {
196 if (aux->next->id >= idmin && aux->next->id < idmax)
197 {
198 texlist *aux2 = aux->next->next;
199 if (n >= sz)
200 t = (unsigned int *) realloc(t, ++sz*sizeof(int));
201 t[n++] = aux->next->id;
202 free(aux->next);
203 aux->next = aux2;
204 nbTex--;
205 }
206 aux = aux->next;
207 }
208 glDeleteTextures(n, t);
209 free(t);
210 //printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);
211#endif
212}
213
214
215void add_tex(unsigned int id)
216{
217#ifdef TEXBSP
98e75f2d 218 if (list == NULL) {
98e75f2d 219 list = (texbsp*)malloc(sizeof(texbsp));
220 list->left = NULL; list->right = NULL;
221 list->id = id;
222 nbTex++;
223 return;
224 }
225 texbsp *bsp = list;
4d186acb 226if (id>TMU_SIZE*2) {printf("/!\\ add (%u), anchor=%u, list=", id, bsp->id); print_tex();}
98e75f2d 227 if (bsp->id>=id) { // go left
4d186acb 228 while ((bsp->left!=NULL) && (bsp->id > id))
98e75f2d 229 {
230 bsp=bsp->left;
231 }
4d186acb 232 if (bsp->id == id) return;
98e75f2d 233 texbsp *ins = (texbsp*)malloc(sizeof(texbsp));
98e75f2d 234 ins->id = id;
4d186acb 235 if ((bsp->id > id) && (bsp->left==NULL)) {
236 bsp->left = ins;
237 ins->right = bsp;
238 ins->left = NULL;
239 } else {
240 texbsp *aux = bsp->right;
241 ins->left = bsp;
242 ins->right = aux;
243 bsp->right = ins;
244 if (aux) aux->left = ins;
245 }
98e75f2d 246 nbTex++;
247 list=bsp; // new ankor
248 return;
249 } else { // go right
4d186acb 250 while ((bsp->right!=NULL) && (bsp->id < id))
98e75f2d 251 {
98e75f2d 252 bsp=bsp->right;
253 }
4d186acb 254 if (bsp->id == id) return;
98e75f2d 255 texbsp *ins = (texbsp*)malloc(sizeof(texbsp));
98e75f2d 256 ins->id = id;
4d186acb 257 if ((bsp->id < id) && (bsp->right==NULL)) { // add at end of chain !
258 bsp->right = ins;
259 ins->left = bsp;
260 ins->right = NULL;
261 } else { // insert in chain
262 texbsp *aux = bsp->left;
263 ins->right = bsp;
264 ins->left = aux;
265 bsp->left = ins;
266 if (aux) aux->right = ins;
267 }
98e75f2d 268 nbTex++;
269 list=bsp; // new ankor
270 return;
271 }
272#else
273 texlist *aux = list;
274 texlist *aux2;
275 //printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);
276 if (list == NULL || id < list->id)
277 {
278 nbTex++;
279 list = (texlist*)malloc(sizeof(texlist));
280 list->next = aux;
281 list->id = id;
282 return;
283 }
284 while (aux->next != NULL && aux->next->id < id) aux = aux->next;
285 // ZIGGY added this test so that add_tex now accept re-adding an existing texture
286 if (aux->next != NULL && aux->next->id == id) return;
287 nbTex++;
288 aux2 = aux->next;
289 aux->next = (texlist*)malloc(sizeof(texlist));
290 aux->next->id = id;
291 aux->next->next = aux2;
292#endif
293}
294
295void init_textures()
296{
297 tex0_width = tex0_height = tex1_width = tex1_height = 2;
298 // ZIGGY because remove_tex isn't called (Pj64 doesn't like it), it's better
299 // to leave these so that they'll be reused (otherwise we have a memory leak)
300 // list = NULL;
301 // nbTex = 0;
302
303 if (!texture) texture = (unsigned char*)malloc(2048*2048*4);
4d186acb 304 #ifdef TEXBSP
305 list = NULL;
306 nbTex = 0;
307 #endif
98e75f2d 308}
309
310void free_textures()
311{
312#ifndef WIN32
313 // ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
314 remove_tex(0x00000000, 0xFFFFFFFF);
315#endif
316 if (texture != NULL) {
317 free(texture);
318 texture = NULL;
319 }
320}
321
322FX_ENTRY FxU32 FX_CALL
323grTexMinAddress( GrChipID_t tmu )
324{
325 LOG("grTexMinAddress(%d)\r\n", tmu);
326 if (UMAmode)
327 return 0;
328 else
329 return tmu*TMU_SIZE;
330}
331
332FX_ENTRY FxU32 FX_CALL
333grTexMaxAddress( GrChipID_t tmu )
334{
335 LOG("grTexMaxAddress(%d)\r\n", tmu);
336 if (UMAmode)
337 return TMU_SIZE*2 - 1;
338 else
339 return tmu*TMU_SIZE + TMU_SIZE - 1;
340}
341
342FX_ENTRY FxU32 FX_CALL
343grTexTextureMemRequired( FxU32 evenOdd,
344 GrTexInfo *info )
345{
346 int width, height;
347 LOG("grTextureMemRequired(%d)\r\n", evenOdd);
348 if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD");
349
350 if (info->aspectRatioLog2 < 0)
351 {
352 height = 1 << info->largeLodLog2;
353 width = height >> -info->aspectRatioLog2;
354 }
355 else
356 {
357 width = 1 << info->largeLodLog2;
358 height = width >> info->aspectRatioLog2;
359 }
360
361 switch(info->format)
362 {
363 case GR_TEXFMT_ALPHA_8:
364 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
365 case GR_TEXFMT_ALPHA_INTENSITY_44:
366 return width*height;
367 break;
368 case GR_TEXFMT_ARGB_1555:
369 case GR_TEXFMT_ARGB_4444:
370 case GR_TEXFMT_ALPHA_INTENSITY_88:
371 case GR_TEXFMT_RGB_565:
372 return (width*height)<<1;
373 break;
374 case GR_TEXFMT_ARGB_8888:
375 return (width*height)<<2;
376 break;
377 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
378 return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
379 case GR_TEXFMT_ARGB_CMP_DXT3:
380 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
381 case GR_TEXFMT_ARGB_CMP_DXT5:
382 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
383 case GR_TEXFMT_ARGB_CMP_FXT1:
384 return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
385 default:
386 display_warning("grTexTextureMemRequired : unknown texture format: %x", info->format);
387 }
388 return 0;
389}
390
391FX_ENTRY FxU32 FX_CALL
392grTexCalcMemRequired(
393 GrLOD_t lodmin, GrLOD_t lodmax,
394 GrAspectRatio_t aspect, GrTextureFormat_t fmt)
395{
396 int width, height;
397 LOG("grTexCalcMemRequired(%d, %d, %d, %d)\r\n", lodmin, lodmax, aspect, fmt);
398 if (lodmax != lodmin) display_warning("grTexCalcMemRequired : loading more than one LOD");
399
400 if (aspect < 0)
401 {
402 height = 1 << lodmax;
403 width = height >> -aspect;
404 }
405 else
406 {
407 width = 1 << lodmax;
408 height = width >> aspect;
409 }
410
411 switch(fmt)
412 {
413 case GR_TEXFMT_ALPHA_8:
414 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
415 case GR_TEXFMT_ALPHA_INTENSITY_44:
416 return width*height;
417 break;
418 case GR_TEXFMT_ARGB_1555:
419 case GR_TEXFMT_ARGB_4444:
420 case GR_TEXFMT_ALPHA_INTENSITY_88:
421 case GR_TEXFMT_RGB_565:
422 return (width*height)<<1;
423 break;
424 case GR_TEXFMT_ARGB_8888:
425 return (width*height)<<2;
426 break;
427 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
428 return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
429 case GR_TEXFMT_ARGB_CMP_DXT3:
430 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
431 case GR_TEXFMT_ARGB_CMP_DXT5:
432 return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
433 case GR_TEXFMT_ARGB_CMP_FXT1:
434 return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
435 default:
436 display_warning("grTexTextureMemRequired : unknown texture format: %x", fmt);
437 }
438 return 0;
439}
440
441int grTexFormatSize(int fmt)
442{
443 int factor = -1;
444 switch(fmt) {
445 case GR_TEXFMT_ALPHA_8:
446 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
447 factor = 1;
448 break;
449 case GR_TEXFMT_ALPHA_INTENSITY_44:
450 factor = 1;
451 break;
452 case GR_TEXFMT_RGB_565:
453 factor = 2;
454 break;
455 case GR_TEXFMT_ARGB_1555:
456 factor = 2;
457 break;
458 case GR_TEXFMT_ALPHA_INTENSITY_88:
459 factor = 2;
460 break;
461 case GR_TEXFMT_ARGB_4444:
462 factor = 2;
463 break;
464 case GR_TEXFMT_ARGB_8888:
465 factor = 4;
466 break;
467 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
468 factor = 8; // HACKALERT: factor holds block bytes
469 break;
470 case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
471 factor = 16; // HACKALERT: factor holds block bytes
472 break;
473 case GR_TEXFMT_ARGB_CMP_DXT5:
474 factor = 16;
475 break;
476 case GR_TEXFMT_ARGB_CMP_FXT1:
477 factor = 8;
478 break;
479 default:
480 display_warning("grTexFormatSize : unknown texture format: %x", fmt);
481 }
482 return factor;
483}
484
485int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)
486{
487 *gltexfmt = GL_RGBA;
488 *glpixfmt = GL_RGBA;
489 *glpackfmt = GL_UNSIGNED_BYTE;
490 return 0;
491/*
492 int factor = -1;
493 switch(fmt) {
494 case GR_TEXFMT_ALPHA_8:
495 factor = 1;
496 *gltexfmt = GL_INTENSITY8;
497 *glpixfmt = GL_LUMINANCE;
498 *glpackfmt = GL_UNSIGNED_BYTE;
499 break;
500 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
501 factor = 1;
502 *gltexfmt = GL_LUMINANCE8;
503 *glpixfmt = GL_LUMINANCE;
504 *glpackfmt = GL_UNSIGNED_BYTE;
505 break;
506 case GR_TEXFMT_ALPHA_INTENSITY_44:
507 break;
508 case GR_TEXFMT_RGB_565:
509 factor = 2;
510 *gltexfmt = GL_RGB;
511 *glpixfmt = GL_RGB;
512 *glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
513 break;
514 case GR_TEXFMT_ARGB_1555:
515 if (ati_sucks > 0) return -1; // ATI sucks as usual (fixes slowdown on ATI)
516 factor = 2;
517 *gltexfmt = GL_RGB5_A1;
518 *glpixfmt = GL_BGRA;
519 *glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
520 break;
521 case GR_TEXFMT_ALPHA_INTENSITY_88:
522 factor = 2;
523 *gltexfmt = GL_LUMINANCE8_ALPHA8;
524 *glpixfmt = GL_LUMINANCE_ALPHA;
525 *glpackfmt = GL_UNSIGNED_BYTE;
526 break;
527 case GR_TEXFMT_ARGB_4444:
528 factor = 2;
529 *gltexfmt = GL_RGBA4;
530 *glpixfmt = GL_BGRA;
531 *glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
532 break;
533 case GR_TEXFMT_ARGB_8888:
534 factor = 4;
535 *gltexfmt = GL_RGBA8;
536 *glpixfmt = GL_BGRA;
537 *glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;
538 break;
539 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
540 // HACKALERT: 3Dfx Glide uses GR_TEXFMT_ARGB_CMP_DXT1 for both opaque DXT1 and DXT1 with 1bit alpha.
541 // GlideHQ compiled with GLIDE64_DXTN option enabled, uses opaqe DXT1 only.
542 factor = 8; // HACKALERT: factor holds block bytes
543 *gltexfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // these variables aren't used
544 *glpixfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
545 *glpackfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
546 break;
547 case GR_TEXFMT_ARGB_CMP_DXT3:
548 factor = 16;
549 *gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
550 *glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
551 *glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
552 break;
553 case GR_TEXFMT_ARGB_CMP_DXT5:
554 factor = 16;
555 *gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
556 *glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
557 *glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
558 break;
559 case GR_TEXFMT_ARGB_CMP_FXT1:
560 factor = 8;
561 *gltexfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
562 *glpixfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
563 *glpackfmt = GL_COMPRESSED_RGBA_FXT1_3DFX; // XXX: what should we do about GL_COMPRESSED_RGB_FXT1_3DFX?
564 break;
565 default:
566 display_warning("grTexFormat2GLPackedFmt : unknown texture format: %x", fmt);
567 }
568 return factor;
569*/
570}
571
572FX_ENTRY void FX_CALL
573grTexDownloadMipMap( GrChipID_t tmu,
574 FxU32 startAddress,
575 FxU32 evenOdd,
576 GrTexInfo *info )
577{
578 int width, height, i, j;
579 int factor;
580 int glformat = 0;
581 int gltexfmt, glpixfmt, glpackfmt;
582 LOG("grTexDownloadMipMap(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
583 if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexDownloadMipMap : loading more than one LOD");
584
585 if (info->aspectRatioLog2 < 0)
586 {
587 height = 1 << info->largeLodLog2;
588 width = height >> -info->aspectRatioLog2;
589 }
590 else
591 {
592 width = 1 << info->largeLodLog2;
593 height = width >> info->aspectRatioLog2;
594 }
595
596 if (!packed_pixels_support)
597 factor = -1;
598 else
599 factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);
600
601 if (factor < 0) {
602
603 // VP fixed the texture conversions to be more accurate, also swapped
604 // the for i/j loops so that is is less likely to break the memory cache
605 register int n = 0, m = 0;
606 switch(info->format)
607 {
608 case GR_TEXFMT_ALPHA_8:
609 for (i=0; i<height; i++)
610 {
611 for (j=0; j<width; j++)
612 {
613 unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
614 texel |= (texel << 8);
615 texel |= (texel << 16);
616 ((unsigned int*)texture)[n] = texel;
617 m++;
618 n++;
619 }
620 }
621 factor = 1;
622 glformat = GL_RGBA;
623 break;
624 case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
625 for (i=0; i<height; i++)
626 {
627 for (j=0; j<width; j++)
628 {
629 unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
630 texel |= (0xFF000000 | (texel << 16) | (texel << 8));
631 ((unsigned int*)texture)[n] = texel;
632 m++;
633 n++;
634 }
635 }
636 factor = 1;
637 glformat = GL_ALPHA;
638 break;
639 case GR_TEXFMT_ALPHA_INTENSITY_44:
640#if 1
641 for (i=0; i<height; i++)
642 {
643 for (j=0; j<width; j++)
644 {
645 unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
646#if 1
647 /* accurate conversion */
648 unsigned int texel_hi = (texel & 0x000000F0) << 20;
649 unsigned int texel_low = texel & 0x0000000F;
650 texel_low |= (texel_low << 4);
651 texel_hi |= ((texel_hi << 4) | (texel_low << 16) | (texel_low << 8) | texel_low);
652#else
653 unsigned int texel_hi = (texel & 0x000000F0) << 24;
654 unsigned int texel_low = (texel & 0x0000000F) << 4;
655 texel_hi |= ((texel_low << 16) | (texel_low << 8) | texel_low);
656#endif
657 ((unsigned int*)texture)[n] = texel_hi;
658 m++;
659 n++;
660 }
661 }
662 factor = 1;
663 glformat = GL_LUMINANCE_ALPHA;
664#endif
665 break;
666 case GR_TEXFMT_RGB_565:
667 for (i=0; i<height; i++)
668 {
669 for (j=0; j<width; j++)
670 {
671 unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
672 unsigned int B = texel & 0x0000F800;
673 unsigned int G = texel & 0x000007E0;
674 unsigned int R = texel & 0x0000001F;
675#if 0
676 /* accurate conversion */
677 ((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | ((R >> 2) << 16) | (G << 5) | ((G >> 9) << 8) | (B >> 8) | (B >> 13);
678#else
679 ((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8);
680#endif
681 m++;
682 n++;
683 }
684 }
685 factor = 2;
686 glformat = GL_RGB;
687 break;
688 case GR_TEXFMT_ARGB_1555:
689 for (i=0; i<height; i++)
690 {
691 for (j=0; j<width; j++)
692 {
693 unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
694 unsigned int A = texel & 0x00008000 ? 0xFF000000 : 0;
695 unsigned int B = texel & 0x00007C00;
696 unsigned int G = texel & 0x000003E0;
697 unsigned int R = texel & 0x0000001F;
698#if 0
699 /* accurate conversion */
700 ((unsigned int*)texture)[n] = A | (R << 19) | ((R >> 2) << 16) | (G << 6) | ((G >> 8) << 8) | (B >> 7) | (B >> 12);
701#else
702 ((unsigned int*)texture)[n] = A | (R << 19) | (G << 6) | (B >> 7);
703#endif
704 m++;
705 n++;
706 }
707 }
708 factor = 2;
709 glformat = GL_RGBA;
710 break;
711 case GR_TEXFMT_ALPHA_INTENSITY_88:
712 for (i=0; i<height; i++)
713 {
714 for (j=0; j<width; j++)
715 {
716 unsigned int AI = (unsigned int)((unsigned short*)info->data)[m];
717 unsigned int I = (unsigned int)(AI & 0x000000FF);
718 ((unsigned int*)texture)[n] = (AI << 16) | (I << 8) | I;
719 m++;
720 n++;
721 }
722 }
723 factor = 2;
724 glformat = GL_LUMINANCE_ALPHA;
725 break;
726 case GR_TEXFMT_ARGB_4444:
727
728 for (i=0; i<height; i++)
729 {
730 for (j=0; j<width; j++)
731 {
732 unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
733 unsigned int A = texel & 0x0000F000;
734 unsigned int B = texel & 0x00000F00;
735 unsigned int G = texel & 0x000000F0;
736 unsigned int R = texel & 0x0000000F;
737#if 0
738 /* accurate conversion */
739 ((unsigned int*)texture)[n] = (A << 16) | (A << 12) | (R << 20) | (R << 16) | (G << 8) | (G << 4) | (B >> 4) | (B >> 8);
740#else
741 ((unsigned int*)texture)[n] = (A << 16) | (R << 20) | (G << 8) | (B >> 4);
742#endif
743 m++;
744 n++;
745 }
746 }
747 factor = 2;
748 glformat = GL_RGBA;
749 break;
750 case GR_TEXFMT_ARGB_8888:
751 for (i=0; i<height; i++)
752 {
753 for (j=0; j<width; j++)
754 {
755 unsigned int texel = ((unsigned int*)info->data)[m];
756 unsigned int A = texel & 0xFF000000;
757 unsigned int B = texel & 0x00FF0000;
758 unsigned int G = texel & 0x0000FF00;
759 unsigned int R = texel & 0x000000FF;
760 ((unsigned int*)texture)[n] = A | (R << 16) | G | (B >> 16);
761 m++;
762 n++;
763 }
764 }
765 factor = 4;
766 glformat = GL_RGBA;
767 break;
768/*
769 case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
770 factor = 8; // HACKALERT: factor holds block bytes
771 glformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
772 break;
773 case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
774 factor = 16; // HACKALERT: factor holds block bytes
775 glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
776 break;
777 case GR_TEXFMT_ARGB_CMP_DXT5:
778 factor = 16;
779 glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
780 break;
781 case GR_TEXFMT_ARGB_CMP_FXT1:
782 factor = 8;
783 glformat = GL_COMPRESSED_RGBA_FXT1_3DFX;
784 break;
785*/
786 default:
787 display_warning("grTexDownloadMipMap : unknown texture format: %x", info->format);
788 factor = 0;
789 }
790 }
791
792 if (nbTextureUnits <= 2)
793 glActiveTexture(GL_TEXTURE1);
794 else
795 glActiveTexture(GL_TEXTURE2);
796
797 switch(info->format)
798 {
799 case GR_TEXFMT_ARGB_CMP_DXT1:
800 case GR_TEXFMT_ARGB_CMP_DXT3:
801 case GR_TEXFMT_ARGB_CMP_DXT5:
802 case GR_TEXFMT_ARGB_CMP_FXT1:
803 remove_tex(startAddress+1, startAddress+1+((width*height*factor)>>4));
804 break;
805 default:
806 remove_tex(startAddress+1, startAddress+1+(width*height*factor));
807 }
808
809 add_tex(startAddress+1);
810 glBindTexture(GL_TEXTURE_2D, startAddress+1);
811
812 if (largest_supported_anisotropy > 1.0f)
813 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
814
815 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
816/*
817 switch(info->format)
818 {
819 case GR_TEXFMT_ARGB_CMP_DXT1:
820 case GR_TEXFMT_ARGB_CMP_DXT3:
821 case GR_TEXFMT_ARGB_CMP_DXT5:
822 case GR_TEXFMT_ARGB_CMP_FXT1:
823 glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, (glformat ? glformat : gltexfmt), width, height, 0, (width*height*factor)>>4, info->data);
824 break;
825 default:
826 if (glformat) {
827 glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
828 } else
829 glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);
830 }
831*/
832
833 glBindTexture(GL_TEXTURE_2D, default_texture);
834}
835
836int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );
837
838FX_ENTRY void FX_CALL
839grTexSource( GrChipID_t tmu,
840 FxU32 startAddress,
841 FxU32 evenOdd,
842 GrTexInfo *info )
843{
844 LOG("grTexSource(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
845
846 if (tmu == GR_TMU1 || nbTextureUnits <= 2)
847 {
848 if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
849 glActiveTexture(GL_TEXTURE0);
850
851 if (info->aspectRatioLog2 < 0)
852 {
853 tex0_height = 256;
854 tex0_width = tex0_height >> -info->aspectRatioLog2;
855 }
856 else
857 {
858 tex0_width = 256;
859 tex0_height = tex0_width >> info->aspectRatioLog2;
860 }
861
862 glBindTexture(GL_TEXTURE_2D, startAddress+1);
863#ifdef VPDEBUG
864 dump_tex(startAddress+1);
865#endif
866 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
867 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
868 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
870 }
871 else
872 {
873 glActiveTexture(GL_TEXTURE1);
874
875 if (info->aspectRatioLog2 < 0)
876 {
877 tex1_height = 256;
878 tex1_width = tex1_height >> -info->aspectRatioLog2;
879 }
880 else
881 {
882 tex1_width = 256;
883 tex1_height = tex1_width >> info->aspectRatioLog2;
884 }
885
886 glBindTexture(GL_TEXTURE_2D, startAddress+1);
887#ifdef VPDEBUG
888 dump_tex(startAddress+1);
889#endif
890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
893 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
894 }
895 if(!CheckTextureBufferFormat(tmu, startAddress+1, info))
896 {
897 if(tmu == 0 && blackandwhite1 != 0)
898 {
899 blackandwhite1 = 0;
900 need_to_compile = 1;
901 }
902 if(tmu == 1 && blackandwhite0 != 0)
903 {
904 blackandwhite0 = 0;
905 need_to_compile = 1;
906 }
907 }
908
909#if 0
910 extern int auxbuffer;
911 static int oldbuffer;
912 FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
913 if (auxbuffer == GR_BUFFER_AUXBUFFER && auxbuffer != oldbuffer)
914 grAuxBufferExt(auxbuffer);
915 oldbuffer = auxbuffer;
916#endif
917}
918
919FX_ENTRY void FX_CALL
920grTexDetailControl(
921 GrChipID_t tmu,
922 int lod_bias,
923 FxU8 detail_scale,
924 float detail_max
925 )
926{
927 LOG("grTexDetailControl(%d,%d,%d,%d)\r\n", tmu, lod_bias, detail_scale, detail_max);
928 if (lod_bias != 31 && detail_scale != 7)
929 {
930 if (!lod_bias && !detail_scale && !detail_max) return;
931 else
932 display_warning("grTexDetailControl : %d, %d, %f", lod_bias, detail_scale, detail_max);
933 }
934 lambda = detail_max;
935 if(lambda > 1.0f)
936 {
937 lambda = 1.0f - (255.0f - lambda);
938 }
939 if(lambda > 1.0f) display_warning("lambda:%f", lambda);
940
941 set_lambda();
942}
943
944FX_ENTRY void FX_CALL
945grTexLodBiasValue(GrChipID_t tmu, float bias )
946{
947 LOG("grTexLodBiasValue(%d,%f)\r\n", tmu, bias);
948}
949
950FX_ENTRY void FX_CALL
951grTexFilterMode(
952 GrChipID_t tmu,
953 GrTextureFilterMode_t minfilter_mode,
954 GrTextureFilterMode_t magfilter_mode
955 )
956{
957 LOG("grTexFilterMode(%d,%d,%d)\r\n", tmu, minfilter_mode, magfilter_mode);
958 if (tmu == GR_TMU1 || nbTextureUnits <= 2)
959 {
960 if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
961 if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;
962 else min_filter0 = GL_LINEAR;
963
964 if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;
965 else mag_filter0 = GL_LINEAR;
966
967 glActiveTexture(GL_TEXTURE0);
968 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
970 }
971 else
972 {
973 if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;
974 else min_filter1 = GL_LINEAR;
975
976 if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;
977 else mag_filter1 = GL_LINEAR;
978
979 glActiveTexture(GL_TEXTURE1);
980 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
981 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
982 }
983}
984
985FX_ENTRY void FX_CALL
986grTexClampMode(
987 GrChipID_t tmu,
988 GrTextureClampMode_t s_clampmode,
989 GrTextureClampMode_t t_clampmode
990 )
991{
992 LOG("grTexClampMode(%d, %d, %d)\r\n", tmu, s_clampmode, t_clampmode);
993 if (tmu == GR_TMU1 || nbTextureUnits <= 2)
994 {
995 if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
996 switch(s_clampmode)
997 {
998 case GR_TEXTURECLAMP_WRAP:
999 wrap_s0 = GL_REPEAT;
1000 break;
1001 case GR_TEXTURECLAMP_CLAMP:
1002 wrap_s0 = GL_CLAMP_TO_EDGE;
1003 break;
1004 case GR_TEXTURECLAMP_MIRROR_EXT:
1005 wrap_s0 = GL_MIRRORED_REPEAT;
1006 break;
1007 default:
1008 display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
1009 }
1010 switch(t_clampmode)
1011 {
1012 case GR_TEXTURECLAMP_WRAP:
1013 wrap_t0 = GL_REPEAT;
1014 break;
1015 case GR_TEXTURECLAMP_CLAMP:
1016 wrap_t0 = GL_CLAMP_TO_EDGE;
1017 break;
1018 case GR_TEXTURECLAMP_MIRROR_EXT:
1019 wrap_t0 = GL_MIRRORED_REPEAT;
1020 break;
1021 default:
1022 display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
1023 }
1024 glActiveTexture(GL_TEXTURE0);
1025 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
1026 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
1027 }
1028 else
1029 {
1030 switch(s_clampmode)
1031 {
1032 case GR_TEXTURECLAMP_WRAP:
1033 wrap_s1 = GL_REPEAT;
1034 break;
1035 case GR_TEXTURECLAMP_CLAMP:
1036 wrap_s1 = GL_CLAMP_TO_EDGE;
1037 break;
1038 case GR_TEXTURECLAMP_MIRROR_EXT:
1039 wrap_s1 = GL_MIRRORED_REPEAT;
1040 break;
1041 default:
1042 display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
1043 }
1044 switch(t_clampmode)
1045 {
1046 case GR_TEXTURECLAMP_WRAP:
1047 wrap_t1 = GL_REPEAT;
1048 break;
1049 case GR_TEXTURECLAMP_CLAMP:
1050 wrap_t1 = GL_CLAMP_TO_EDGE;
1051 break;
1052 case GR_TEXTURECLAMP_MIRROR_EXT:
1053 wrap_t1 = GL_MIRRORED_REPEAT;
1054 break;
1055 default:
1056 display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
1057 }
1058 glActiveTexture(GL_TEXTURE1);
1059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
1060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
1061 }
1062}