Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-glide64mk2/src/Glitch64/textures.cpp
2 views
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
/* Napalm extensions to GrTextureFormat_t */
31
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
32
#define GR_TEXFMT_ARGB_8888 0x12
33
#define GR_TEXFMT_YUYV_422 0x13
34
#define GR_TEXFMT_UYVY_422 0x14
35
#define GR_TEXFMT_AYUV_444 0x15
36
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
37
#define GR_TEXFMT_ARGB_CMP_DXT2 0x17
38
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
39
#define GR_TEXFMT_ARGB_CMP_DXT4 0x19
40
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
41
#define GR_TEXTFMT_RGB_888 0xFF
42
43
int TMU_SIZE = 8*2048*2048;
44
static unsigned char* texture = NULL;
45
46
int packed_pixels_support = -1;
47
int ati_sucks = -1;
48
float largest_supported_anisotropy = 1.0f;
49
50
#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
51
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
52
#endif
53
54
int tex0_width, tex0_height, tex1_width, tex1_height;
55
float lambda;
56
57
static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
58
static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
59
60
unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
61
62
typedef struct _texlist
63
{
64
unsigned int id;
65
struct _texlist *next;
66
} texlist;
67
68
static int nbTex = 0;
69
static texlist *list = NULL;
70
71
#ifdef _WIN32
72
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
73
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
74
extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
75
#endif
76
void remove_tex(unsigned int idmin, unsigned int idmax)
77
{
78
unsigned int *t;
79
int n = 0;
80
texlist *aux = list;
81
int sz = nbTex;
82
if (aux == NULL) return;
83
t = (unsigned int*)malloc(sz * sizeof(int));
84
while (aux && aux->id >= idmin && aux->id < idmax)
85
{
86
if (n >= sz)
87
t = (unsigned int *) realloc(t, ++sz*sizeof(int));
88
t[n++] = aux->id;
89
aux = aux->next;
90
free(list);
91
list = aux;
92
nbTex--;
93
}
94
while (aux != NULL && aux->next != NULL)
95
{
96
if (aux->next->id >= idmin && aux->next->id < idmax)
97
{
98
texlist *aux2 = aux->next->next;
99
if (n >= sz)
100
t = (unsigned int *) realloc(t, ++sz*sizeof(int));
101
t[n++] = aux->next->id;
102
free(aux->next);
103
aux->next = aux2;
104
nbTex--;
105
}
106
aux = aux->next;
107
}
108
glDeleteTextures(n, t);
109
free(t);
110
//printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);
111
}
112
113
114
void add_tex(unsigned int id)
115
{
116
texlist *aux = list;
117
texlist *aux2;
118
//printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);
119
if (list == NULL || id < list->id)
120
{
121
nbTex++;
122
list = (texlist*)malloc(sizeof(texlist));
123
list->next = aux;
124
list->id = id;
125
return;
126
}
127
while (aux->next != NULL && aux->next->id < id) aux = aux->next;
128
// ZIGGY added this test so that add_tex now accept re-adding an existing texture
129
if (aux->next != NULL && aux->next->id == id) return;
130
nbTex++;
131
aux2 = aux->next;
132
aux->next = (texlist*)malloc(sizeof(texlist));
133
aux->next->id = id;
134
aux->next->next = aux2;
135
}
136
137
void init_textures()
138
{
139
tex0_width = tex0_height = tex1_width = tex1_height = 2;
140
// ZIGGY because remove_tex isn't called (Pj64 doesn't like it), it's better
141
// to leave these so that they'll be reused (otherwise we have a memory leak)
142
// list = NULL;
143
// nbTex = 0;
144
145
if (!texture) texture = (unsigned char*)malloc(2048*2048*4);
146
}
147
148
void free_textures()
149
{
150
#ifndef WIN32
151
// ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
152
remove_tex(0x00000000, 0xFFFFFFFF);
153
#endif
154
if (texture != NULL) {
155
free(texture);
156
texture = NULL;
157
}
158
}
159
160
FX_ENTRY FxU32 FX_CALL
161
grTexMinAddress( GrChipID_t tmu )
162
{
163
LOG("grTexMinAddress(%d)\r\n", tmu);
164
if (UMAmode)
165
return 0;
166
else
167
return tmu*TMU_SIZE;
168
}
169
170
FX_ENTRY FxU32 FX_CALL
171
grTexMaxAddress( GrChipID_t tmu )
172
{
173
LOG("grTexMaxAddress(%d)\r\n", tmu);
174
if (UMAmode)
175
return TMU_SIZE*2 - 1;
176
else
177
return tmu*TMU_SIZE + TMU_SIZE - 1;
178
}
179
180
FX_ENTRY FxU32 FX_CALL
181
grTexTextureMemRequired( FxU32 evenOdd,
182
GrTexInfo *info )
183
{
184
int width, height;
185
LOG("grTextureMemRequired(%d)\r\n", evenOdd);
186
if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD");
187
188
if (info->aspectRatioLog2 < 0)
189
{
190
height = 1 << info->largeLodLog2;
191
width = height >> -info->aspectRatioLog2;
192
}
193
else
194
{
195
width = 1 << info->largeLodLog2;
196
height = width >> info->aspectRatioLog2;
197
}
198
199
switch(info->format)
200
{
201
case GR_TEXFMT_ALPHA_8:
202
case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
203
case GR_TEXFMT_ALPHA_INTENSITY_44:
204
return width*height;
205
break;
206
case GR_TEXFMT_ARGB_1555:
207
case GR_TEXFMT_ARGB_4444:
208
case GR_TEXFMT_ALPHA_INTENSITY_88:
209
case GR_TEXFMT_RGB_565:
210
return (width*height)<<1;
211
break;
212
case GR_TEXFMT_ARGB_8888:
213
return (width*height)<<2;
214
break;
215
case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
216
return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
217
case GR_TEXFMT_ARGB_CMP_DXT3:
218
return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
219
case GR_TEXFMT_ARGB_CMP_DXT5:
220
return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
221
case GR_TEXFMT_ARGB_CMP_FXT1:
222
return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
223
default:
224
display_warning("grTexTextureMemRequired : unknown texture format: %x", info->format);
225
}
226
return 0;
227
}
228
229
FX_ENTRY FxU32 FX_CALL
230
grTexCalcMemRequired(
231
GrLOD_t lodmin, GrLOD_t lodmax,
232
GrAspectRatio_t aspect, GrTextureFormat_t fmt)
233
{
234
int width, height;
235
LOG("grTexCalcMemRequired(%d, %d, %d, %d)\r\n", lodmin, lodmax, aspect, fmt);
236
if (lodmax != lodmin) display_warning("grTexCalcMemRequired : loading more than one LOD");
237
238
if (aspect < 0)
239
{
240
height = 1 << lodmax;
241
width = height >> -aspect;
242
}
243
else
244
{
245
width = 1 << lodmax;
246
height = width >> aspect;
247
}
248
249
switch(fmt)
250
{
251
case GR_TEXFMT_ALPHA_8:
252
case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
253
case GR_TEXFMT_ALPHA_INTENSITY_44:
254
return width*height;
255
break;
256
case GR_TEXFMT_ARGB_1555:
257
case GR_TEXFMT_ARGB_4444:
258
case GR_TEXFMT_ALPHA_INTENSITY_88:
259
case GR_TEXFMT_RGB_565:
260
return (width*height)<<1;
261
break;
262
case GR_TEXFMT_ARGB_8888:
263
return (width*height)<<2;
264
break;
265
case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
266
return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);
267
case GR_TEXFMT_ARGB_CMP_DXT3:
268
return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
269
case GR_TEXFMT_ARGB_CMP_DXT5:
270
return ((width+0x3)&~0x3)*((height+0x3)&~0x3);
271
case GR_TEXFMT_ARGB_CMP_FXT1:
272
return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);
273
default:
274
display_warning("grTexTextureMemRequired : unknown texture format: %x", fmt);
275
}
276
return 0;
277
}
278
279
int grTexFormatSize(int fmt)
280
{
281
int factor = -1;
282
switch(fmt) {
283
case GR_TEXFMT_ALPHA_8:
284
case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
285
factor = 1;
286
break;
287
case GR_TEXFMT_ALPHA_INTENSITY_44:
288
factor = 1;
289
break;
290
case GR_TEXFMT_RGB_565:
291
factor = 2;
292
break;
293
case GR_TEXFMT_ARGB_1555:
294
factor = 2;
295
break;
296
case GR_TEXFMT_ALPHA_INTENSITY_88:
297
factor = 2;
298
break;
299
case GR_TEXFMT_ARGB_4444:
300
factor = 2;
301
break;
302
case GR_TEXFMT_ARGB_8888:
303
factor = 4;
304
break;
305
case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
306
factor = 8; // HACKALERT: factor holds block bytes
307
break;
308
case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
309
factor = 16; // HACKALERT: factor holds block bytes
310
break;
311
case GR_TEXFMT_ARGB_CMP_DXT5:
312
factor = 16;
313
break;
314
case GR_TEXFMT_ARGB_CMP_FXT1:
315
factor = 8;
316
break;
317
default:
318
display_warning("grTexFormatSize : unknown texture format: %x", fmt);
319
}
320
return factor;
321
}
322
323
int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)
324
{
325
int factor = -1;
326
switch(fmt) {
327
case GR_TEXFMT_ALPHA_8:
328
factor = 1;
329
*gltexfmt = GL_INTENSITY8;
330
*glpixfmt = GL_LUMINANCE;
331
*glpackfmt = GL_UNSIGNED_BYTE;
332
break;
333
case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
334
factor = 1;
335
*gltexfmt = GL_LUMINANCE8;
336
*glpixfmt = GL_LUMINANCE;
337
*glpackfmt = GL_UNSIGNED_BYTE;
338
break;
339
case GR_TEXFMT_ALPHA_INTENSITY_44:
340
break;
341
case GR_TEXFMT_RGB_565:
342
factor = 2;
343
*gltexfmt = GL_RGB;
344
*glpixfmt = GL_RGB;
345
*glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
346
break;
347
case GR_TEXFMT_ARGB_1555:
348
if (ati_sucks > 0) return -1; // ATI sucks as usual (fixes slowdown on ATI)
349
factor = 2;
350
*gltexfmt = GL_RGB5_A1;
351
*glpixfmt = GL_BGRA;
352
*glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
353
break;
354
case GR_TEXFMT_ALPHA_INTENSITY_88:
355
factor = 2;
356
*gltexfmt = GL_LUMINANCE8_ALPHA8;
357
*glpixfmt = GL_LUMINANCE_ALPHA;
358
*glpackfmt = GL_UNSIGNED_BYTE;
359
break;
360
case GR_TEXFMT_ARGB_4444:
361
factor = 2;
362
*gltexfmt = GL_RGBA4;
363
*glpixfmt = GL_BGRA;
364
*glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
365
break;
366
case GR_TEXFMT_ARGB_8888:
367
factor = 4;
368
*gltexfmt = GL_RGBA8;
369
*glpixfmt = GL_BGRA;
370
*glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;
371
break;
372
case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
373
// HACKALERT: 3Dfx Glide uses GR_TEXFMT_ARGB_CMP_DXT1 for both opaque DXT1 and DXT1 with 1bit alpha.
374
// GlideHQ compiled with GLIDE64_DXTN option enabled, uses opaqe DXT1 only.
375
factor = 8; // HACKALERT: factor holds block bytes
376
*gltexfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // these variables aren't used
377
*glpixfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
378
*glpackfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
379
break;
380
case GR_TEXFMT_ARGB_CMP_DXT3:
381
factor = 16;
382
*gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
383
*glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
384
*glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
385
break;
386
case GR_TEXFMT_ARGB_CMP_DXT5:
387
factor = 16;
388
*gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
389
*glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
390
*glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
391
break;
392
case GR_TEXFMT_ARGB_CMP_FXT1:
393
factor = 8;
394
*gltexfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
395
*glpixfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
396
*glpackfmt = GL_COMPRESSED_RGBA_FXT1_3DFX; // XXX: what should we do about GL_COMPRESSED_RGB_FXT1_3DFX?
397
break;
398
default:
399
display_warning("grTexFormat2GLPackedFmt : unknown texture format: %x", fmt);
400
}
401
return factor;
402
}
403
404
FX_ENTRY void FX_CALL
405
grTexDownloadMipMap( GrChipID_t tmu,
406
FxU32 startAddress,
407
FxU32 evenOdd,
408
GrTexInfo *info )
409
{
410
int width, height, i, j;
411
int factor;
412
int glformat = 0;
413
int gltexfmt, glpixfmt, glpackfmt;
414
LOG("grTexDownloadMipMap(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
415
if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexDownloadMipMap : loading more than one LOD");
416
417
if (info->aspectRatioLog2 < 0)
418
{
419
height = 1 << info->largeLodLog2;
420
width = height >> -info->aspectRatioLog2;
421
}
422
else
423
{
424
width = 1 << info->largeLodLog2;
425
height = width >> info->aspectRatioLog2;
426
}
427
428
if (!packed_pixels_support)
429
factor = -1;
430
else
431
factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);
432
433
if (factor < 0) {
434
435
// VP fixed the texture conversions to be more accurate, also swapped
436
// the for i/j loops so that is is less likely to break the memory cache
437
register int n = 0, m = 0;
438
switch(info->format)
439
{
440
case GR_TEXFMT_ALPHA_8:
441
for (i=0; i<height; i++)
442
{
443
for (j=0; j<width; j++)
444
{
445
unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
446
texel |= (texel << 8);
447
texel |= (texel << 16);
448
((unsigned int*)texture)[n] = texel;
449
m++;
450
n++;
451
}
452
}
453
factor = 1;
454
glformat = GL_INTENSITY8;
455
break;
456
case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii
457
for (i=0; i<height; i++)
458
{
459
for (j=0; j<width; j++)
460
{
461
unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
462
texel |= (0xFF000000 | (texel << 16) | (texel << 8));
463
((unsigned int*)texture)[n] = texel;
464
m++;
465
n++;
466
}
467
}
468
factor = 1;
469
glformat = GL_LUMINANCE8;
470
break;
471
case GR_TEXFMT_ALPHA_INTENSITY_44:
472
#if 1
473
for (i=0; i<height; i++)
474
{
475
for (j=0; j<width; j++)
476
{
477
unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
478
#if 1
479
/* accurate conversion */
480
unsigned int texel_hi = (texel & 0x000000F0) << 20;
481
unsigned int texel_low = texel & 0x0000000F;
482
texel_low |= (texel_low << 4);
483
texel_hi |= ((texel_hi << 4) | (texel_low << 16) | (texel_low << 8) | texel_low);
484
#else
485
unsigned int texel_hi = (texel & 0x000000F0) << 24;
486
unsigned int texel_low = (texel & 0x0000000F) << 4;
487
texel_hi |= ((texel_low << 16) | (texel_low << 8) | texel_low);
488
#endif
489
((unsigned int*)texture)[n] = texel_hi;
490
m++;
491
n++;
492
}
493
}
494
factor = 1;
495
glformat = GL_LUMINANCE4_ALPHA4;
496
#endif
497
break;
498
case GR_TEXFMT_RGB_565:
499
for (i=0; i<height; i++)
500
{
501
for (j=0; j<width; j++)
502
{
503
unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
504
unsigned int B = texel & 0x0000F800;
505
unsigned int G = texel & 0x000007E0;
506
unsigned int R = texel & 0x0000001F;
507
#if 0
508
/* accurate conversion */
509
((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | ((R >> 2) << 16) | (G << 5) | ((G >> 9) << 8) | (B >> 8) | (B >> 13);
510
#else
511
((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8);
512
#endif
513
m++;
514
n++;
515
}
516
}
517
factor = 2;
518
glformat = GL_RGB;
519
break;
520
case GR_TEXFMT_ARGB_1555:
521
for (i=0; i<height; i++)
522
{
523
for (j=0; j<width; j++)
524
{
525
unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
526
unsigned int A = texel & 0x00008000 ? 0xFF000000 : 0;
527
unsigned int B = texel & 0x00007C00;
528
unsigned int G = texel & 0x000003E0;
529
unsigned int R = texel & 0x0000001F;
530
#if 0
531
/* accurate conversion */
532
((unsigned int*)texture)[n] = A | (R << 19) | ((R >> 2) << 16) | (G << 6) | ((G >> 8) << 8) | (B >> 7) | (B >> 12);
533
#else
534
((unsigned int*)texture)[n] = A | (R << 19) | (G << 6) | (B >> 7);
535
#endif
536
m++;
537
n++;
538
}
539
}
540
factor = 2;
541
glformat = GL_RGB5_A1;
542
break;
543
case GR_TEXFMT_ALPHA_INTENSITY_88:
544
for (i=0; i<height; i++)
545
{
546
for (j=0; j<width; j++)
547
{
548
unsigned int AI = (unsigned int)((unsigned short*)info->data)[m];
549
unsigned int I = (unsigned int)(AI & 0x000000FF);
550
((unsigned int*)texture)[n] = (AI << 16) | (I << 8) | I;
551
m++;
552
n++;
553
}
554
}
555
factor = 2;
556
glformat = GL_LUMINANCE8_ALPHA8;
557
break;
558
case GR_TEXFMT_ARGB_4444:
559
560
for (i=0; i<height; i++)
561
{
562
for (j=0; j<width; j++)
563
{
564
unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
565
unsigned int A = texel & 0x0000F000;
566
unsigned int B = texel & 0x00000F00;
567
unsigned int G = texel & 0x000000F0;
568
unsigned int R = texel & 0x0000000F;
569
#if 0
570
/* accurate conversion */
571
((unsigned int*)texture)[n] = (A << 16) | (A << 12) | (R << 20) | (R << 16) | (G << 8) | (G << 4) | (B >> 4) | (B >> 8);
572
#else
573
((unsigned int*)texture)[n] = (A << 16) | (R << 20) | (G << 8) | (B >> 4);
574
#endif
575
m++;
576
n++;
577
}
578
}
579
factor = 2;
580
glformat = GL_RGBA4;
581
break;
582
case GR_TEXFMT_ARGB_8888:
583
for (i=0; i<height; i++)
584
{
585
for (j=0; j<width; j++)
586
{
587
unsigned int texel = ((unsigned int*)info->data)[m];
588
unsigned int A = texel & 0xFF000000;
589
unsigned int B = texel & 0x00FF0000;
590
unsigned int G = texel & 0x0000FF00;
591
unsigned int R = texel & 0x000000FF;
592
((unsigned int*)texture)[n] = A | (R << 16) | G | (B >> 16);
593
m++;
594
n++;
595
}
596
}
597
factor = 4;
598
glformat = GL_RGBA8;
599
break;
600
case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
601
factor = 8; // HACKALERT: factor holds block bytes
602
glformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
603
break;
604
case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
605
factor = 16; // HACKALERT: factor holds block bytes
606
glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
607
break;
608
case GR_TEXFMT_ARGB_CMP_DXT5:
609
factor = 16;
610
glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
611
break;
612
case GR_TEXFMT_ARGB_CMP_FXT1:
613
factor = 8;
614
glformat = GL_COMPRESSED_RGBA_FXT1_3DFX;
615
break;
616
default:
617
display_warning("grTexDownloadMipMap : unknown texture format: %x", info->format);
618
factor = 0;
619
}
620
}
621
622
if (nbTextureUnits <= 2)
623
glActiveTextureARB(GL_TEXTURE1_ARB);
624
else
625
glActiveTextureARB(GL_TEXTURE2_ARB);
626
627
switch(info->format)
628
{
629
case GR_TEXFMT_ARGB_CMP_DXT1:
630
case GR_TEXFMT_ARGB_CMP_DXT3:
631
case GR_TEXFMT_ARGB_CMP_DXT5:
632
case GR_TEXFMT_ARGB_CMP_FXT1:
633
remove_tex(startAddress+1, startAddress+1+((width*height*factor)>>4));
634
break;
635
default:
636
remove_tex(startAddress+1, startAddress+1+(width*height*factor));
637
}
638
639
add_tex(startAddress+1);
640
glBindTexture(GL_TEXTURE_2D, startAddress+1);
641
642
if (largest_supported_anisotropy > 1.0f)
643
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
644
645
switch(info->format)
646
{
647
case GR_TEXFMT_ARGB_CMP_DXT1:
648
case GR_TEXFMT_ARGB_CMP_DXT3:
649
case GR_TEXFMT_ARGB_CMP_DXT5:
650
case GR_TEXFMT_ARGB_CMP_FXT1:
651
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, (glformat ? glformat : gltexfmt), width, height, 0, (width*height*factor)>>4, info->data);
652
break;
653
default:
654
if (glformat) {
655
glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
656
} else
657
glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);
658
}
659
660
glBindTexture(GL_TEXTURE_2D, default_texture);
661
}
662
663
int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );
664
665
FX_ENTRY void FX_CALL
666
grTexSource( GrChipID_t tmu,
667
FxU32 startAddress,
668
FxU32 evenOdd,
669
GrTexInfo *info )
670
{
671
LOG("grTexSource(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
672
673
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
674
{
675
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
676
glActiveTextureARB(GL_TEXTURE0_ARB);
677
678
if (info->aspectRatioLog2 < 0)
679
{
680
tex0_height = 256;
681
tex0_width = tex0_height >> -info->aspectRatioLog2;
682
}
683
else
684
{
685
tex0_width = 256;
686
tex0_height = tex0_width >> info->aspectRatioLog2;
687
}
688
689
glBindTexture(GL_TEXTURE_2D, startAddress+1);
690
#ifdef VPDEBUG
691
dump_tex(startAddress+1);
692
#endif
693
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
694
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
695
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
696
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
697
}
698
else
699
{
700
glActiveTextureARB(GL_TEXTURE1_ARB);
701
702
if (info->aspectRatioLog2 < 0)
703
{
704
tex1_height = 256;
705
tex1_width = tex1_height >> -info->aspectRatioLog2;
706
}
707
else
708
{
709
tex1_width = 256;
710
tex1_height = tex1_width >> info->aspectRatioLog2;
711
}
712
713
glBindTexture(GL_TEXTURE_2D, startAddress+1);
714
#ifdef VPDEBUG
715
dump_tex(startAddress+1);
716
#endif
717
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
718
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
719
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
720
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
721
}
722
if(!CheckTextureBufferFormat(tmu, startAddress+1, info))
723
{
724
if(tmu == 0 && blackandwhite1 != 0)
725
{
726
blackandwhite1 = 0;
727
need_to_compile = 1;
728
}
729
if(tmu == 1 && blackandwhite0 != 0)
730
{
731
blackandwhite0 = 0;
732
need_to_compile = 1;
733
}
734
}
735
736
#if 0
737
extern int auxbuffer;
738
static int oldbuffer;
739
FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
740
if (auxbuffer == GR_BUFFER_AUXBUFFER && auxbuffer != oldbuffer)
741
grAuxBufferExt(auxbuffer);
742
oldbuffer = auxbuffer;
743
#endif
744
}
745
746
FX_ENTRY void FX_CALL
747
grTexDetailControl(
748
GrChipID_t tmu,
749
int lod_bias,
750
FxU8 detail_scale,
751
float detail_max
752
)
753
{
754
LOG("grTexDetailControl(%d,%d,%d,%d)\r\n", tmu, lod_bias, detail_scale, detail_max);
755
if (lod_bias != 31 && detail_scale != 7)
756
{
757
if (!lod_bias && !detail_scale && !detail_max) return;
758
else
759
display_warning("grTexDetailControl : %d, %d, %f", lod_bias, detail_scale, detail_max);
760
}
761
lambda = detail_max;
762
if(lambda > 1.0f)
763
{
764
lambda = 1.0f - (255.0f - lambda);
765
}
766
if(lambda > 1.0f) display_warning("lambda:%f", lambda);
767
768
set_lambda();
769
}
770
771
FX_ENTRY void FX_CALL
772
grTexLodBiasValue(GrChipID_t tmu, float bias )
773
{
774
LOG("grTexLodBiasValue(%d,%f)\r\n", tmu, bias);
775
}
776
777
FX_ENTRY void FX_CALL
778
grTexFilterMode(
779
GrChipID_t tmu,
780
GrTextureFilterMode_t minfilter_mode,
781
GrTextureFilterMode_t magfilter_mode
782
)
783
{
784
LOG("grTexFilterMode(%d,%d,%d)\r\n", tmu, minfilter_mode, magfilter_mode);
785
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
786
{
787
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
788
if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;
789
else min_filter0 = GL_LINEAR;
790
791
if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;
792
else mag_filter0 = GL_LINEAR;
793
794
glActiveTextureARB(GL_TEXTURE0_ARB);
795
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
796
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
797
}
798
else
799
{
800
if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;
801
else min_filter1 = GL_LINEAR;
802
803
if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;
804
else mag_filter1 = GL_LINEAR;
805
806
glActiveTextureARB(GL_TEXTURE1_ARB);
807
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
808
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
809
}
810
}
811
812
FX_ENTRY void FX_CALL
813
grTexClampMode(
814
GrChipID_t tmu,
815
GrTextureClampMode_t s_clampmode,
816
GrTextureClampMode_t t_clampmode
817
)
818
{
819
LOG("grTexClampMode(%d, %d, %d)\r\n", tmu, s_clampmode, t_clampmode);
820
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
821
{
822
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
823
switch(s_clampmode)
824
{
825
case GR_TEXTURECLAMP_WRAP:
826
wrap_s0 = GL_REPEAT;
827
break;
828
case GR_TEXTURECLAMP_CLAMP:
829
wrap_s0 = GL_CLAMP_TO_EDGE;
830
break;
831
case GR_TEXTURECLAMP_MIRROR_EXT:
832
wrap_s0 = GL_MIRRORED_REPEAT_ARB;
833
break;
834
default:
835
display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
836
}
837
switch(t_clampmode)
838
{
839
case GR_TEXTURECLAMP_WRAP:
840
wrap_t0 = GL_REPEAT;
841
break;
842
case GR_TEXTURECLAMP_CLAMP:
843
wrap_t0 = GL_CLAMP_TO_EDGE;
844
break;
845
case GR_TEXTURECLAMP_MIRROR_EXT:
846
wrap_t0 = GL_MIRRORED_REPEAT_ARB;
847
break;
848
default:
849
display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
850
}
851
glActiveTextureARB(GL_TEXTURE0_ARB);
852
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
853
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
854
}
855
else
856
{
857
switch(s_clampmode)
858
{
859
case GR_TEXTURECLAMP_WRAP:
860
wrap_s1 = GL_REPEAT;
861
break;
862
case GR_TEXTURECLAMP_CLAMP:
863
wrap_s1 = GL_CLAMP_TO_EDGE;
864
break;
865
case GR_TEXTURECLAMP_MIRROR_EXT:
866
wrap_s1 = GL_MIRRORED_REPEAT_ARB;
867
break;
868
default:
869
display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
870
}
871
switch(t_clampmode)
872
{
873
case GR_TEXTURECLAMP_WRAP:
874
wrap_t1 = GL_REPEAT;
875
break;
876
case GR_TEXTURECLAMP_CLAMP:
877
wrap_t1 = GL_CLAMP_TO_EDGE;
878
break;
879
case GR_TEXTURECLAMP_MIRROR_EXT:
880
wrap_t1 = GL_MIRRORED_REPEAT_ARB;
881
break;
882
default:
883
display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
884
}
885
glActiveTextureARB(GL_TEXTURE1_ARB);
886
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
887
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
888
}
889
}
890
891