2021-03-02 02:13:17 +00:00
|
|
|
// Project64 - A Nintendo 64 emulator
|
2021-05-18 11:51:36 +00:00
|
|
|
// https://www.pj64-emu.com/
|
2021-03-02 02:13:17 +00:00
|
|
|
// Copyright(C) 2001-2021 Project64
|
|
|
|
// Copyright(C) 2003-2009 Sergey 'Gonetz' Lipski
|
|
|
|
// Copyright(C) 2002 Dave2001
|
|
|
|
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
|
2021-05-18 11:51:36 +00:00
|
|
|
|
2017-05-17 08:13:04 +00:00
|
|
|
#include <Project64-video/Renderer/Renderer.h>
|
2013-04-10 07:08:48 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#else // _WIN32
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif // _WIN32
|
2015-10-09 04:53:16 +00:00
|
|
|
#include "glitchmain.h"
|
2013-04-10 07:08:48 +00:00
|
|
|
#include <stdio.h>
|
2013-04-10 10:41:32 +00:00
|
|
|
#include <stdlib.h>
|
2017-04-26 09:05:05 +00:00
|
|
|
#include <Project64-video/trace.h>
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2016-02-04 06:08:24 +00:00
|
|
|
int TMU_SIZE = 8 * 2048 * 2048;
|
2021-04-12 11:35:39 +00:00
|
|
|
static unsigned char* texture = nullptr;
|
2013-04-10 07:08:48 +00:00
|
|
|
|
|
|
|
int packed_pixels_support = -1;
|
|
|
|
int ati_sucks = -1;
|
|
|
|
float largest_supported_anisotropy = 1.0f;
|
|
|
|
|
|
|
|
#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
|
|
|
|
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int tex0_width, tex0_height, tex1_width, tex1_height;
|
|
|
|
float lambda;
|
|
|
|
|
|
|
|
static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
|
|
|
|
static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
|
|
|
|
|
|
|
|
unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
|
|
|
|
|
|
|
|
typedef struct _texlist
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
unsigned int id;
|
|
|
|
struct _texlist *next;
|
2013-04-10 07:08:48 +00:00
|
|
|
} texlist;
|
|
|
|
|
|
|
|
static int nbTex = 0;
|
2021-04-12 11:35:39 +00:00
|
|
|
static texlist *list = nullptr;
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2016-03-26 02:16:58 +00:00
|
|
|
#if !defined(__ANDROID__) && !defined(ANDROID)
|
2013-04-10 07:08:48 +00:00
|
|
|
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
|
|
|
|
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
|
|
|
|
extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
|
|
|
|
#endif
|
|
|
|
void remove_tex(unsigned int idmin, unsigned int idmax)
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
unsigned int *t;
|
|
|
|
int n = 0;
|
|
|
|
texlist *aux = list;
|
|
|
|
int sz = nbTex;
|
2021-04-12 11:35:39 +00:00
|
|
|
if (aux == nullptr) return;
|
2016-02-04 06:08:24 +00:00
|
|
|
t = (unsigned int*)malloc(sz * sizeof(int));
|
|
|
|
while (aux && aux->id >= idmin && aux->id < idmax)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
if (n >= sz)
|
2017-04-26 09:05:05 +00:00
|
|
|
t = (unsigned int *)realloc(t, ++sz * sizeof(int));
|
2016-02-04 06:08:24 +00:00
|
|
|
t[n++] = aux->id;
|
|
|
|
aux = aux->next;
|
|
|
|
free(list);
|
|
|
|
list = aux;
|
|
|
|
nbTex--;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
while (aux != nullptr && aux->next != nullptr)
|
2016-02-04 06:08:24 +00:00
|
|
|
{
|
|
|
|
if (aux->next->id >= idmin && aux->next->id < idmax)
|
|
|
|
{
|
|
|
|
texlist *aux2 = aux->next->next;
|
|
|
|
if (n >= sz)
|
2017-04-26 09:05:05 +00:00
|
|
|
t = (unsigned int *)realloc(t, ++sz * sizeof(int));
|
2016-02-04 06:08:24 +00:00
|
|
|
t[n++] = aux->next->id;
|
|
|
|
free(aux->next);
|
|
|
|
aux->next = aux2;
|
|
|
|
nbTex--;
|
|
|
|
}
|
|
|
|
aux = aux->next;
|
|
|
|
}
|
|
|
|
glDeleteTextures(n, t);
|
|
|
|
free(t);
|
|
|
|
//printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void add_tex(unsigned int id)
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
texlist *aux = list;
|
|
|
|
texlist *aux2;
|
|
|
|
//printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);
|
2021-04-12 11:35:39 +00:00
|
|
|
if (list == nullptr || id < list->id)
|
2016-02-04 06:08:24 +00:00
|
|
|
{
|
|
|
|
nbTex++;
|
|
|
|
list = (texlist*)malloc(sizeof(texlist));
|
|
|
|
list->next = aux;
|
|
|
|
list->id = id;
|
|
|
|
return;
|
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
while (aux->next != nullptr && aux->next->id < id) aux = aux->next;
|
2021-05-18 11:51:36 +00:00
|
|
|
// (Comment by Ziggy) Added this test so that add_tex now accepts re-adding an existing texture
|
2021-04-12 11:35:39 +00:00
|
|
|
if (aux->next != nullptr && aux->next->id == id) return;
|
2013-04-10 07:08:48 +00:00
|
|
|
nbTex++;
|
2016-02-04 06:08:24 +00:00
|
|
|
aux2 = aux->next;
|
|
|
|
aux->next = (texlist*)malloc(sizeof(texlist));
|
|
|
|
aux->next->id = id;
|
|
|
|
aux->next->next = aux2;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void init_textures()
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
tex0_width = tex0_height = tex1_width = tex1_height = 2;
|
2021-05-18 11:51:36 +00:00
|
|
|
// (Comment by Ziggy) Because remove_tex isn't called (Project64 doesn't like it), it's better
|
2016-02-04 06:08:24 +00:00
|
|
|
// to leave these so that they'll be reused (otherwise we have a memory leak)
|
2021-04-12 11:35:39 +00:00
|
|
|
// list = nullptr;
|
2016-02-04 06:08:24 +00:00
|
|
|
// nbTex = 0;
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2016-02-04 06:08:24 +00:00
|
|
|
if (!texture) texture = (unsigned char*)malloc(2048 * 2048 * 4);
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void free_textures()
|
|
|
|
{
|
|
|
|
#ifndef WIN32
|
2021-05-18 11:51:36 +00:00
|
|
|
// (Comment by Ziggy) For some reason, Project64 doesn't like remove_tex on exit
|
2016-02-04 06:08:24 +00:00
|
|
|
remove_tex(0x00000000, 0xFFFFFFFF);
|
2013-04-10 07:08:48 +00:00
|
|
|
#endif
|
2021-04-12 11:35:39 +00:00
|
|
|
if (texture != nullptr) {
|
2016-02-04 06:08:24 +00:00
|
|
|
free(texture);
|
2021-04-12 11:35:39 +00:00
|
|
|
texture = nullptr;
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 00:04:04 +00:00
|
|
|
uint32_t gfxTexMinAddress(gfxChipID_t tmu)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d", tmu);
|
2017-07-22 08:33:13 +00:00
|
|
|
return 0;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 00:04:04 +00:00
|
|
|
uint32_t gfxTexMaxAddress(gfxChipID_t tmu)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d", tmu);
|
2017-07-22 08:33:13 +00:00
|
|
|
return TMU_SIZE * 2 - 1;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 08:29:37 +00:00
|
|
|
uint32_t gfxTexTextureMemRequired(uint32_t evenOdd, gfxTexInfo *info)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "evenOdd = %d", evenOdd);
|
2016-02-04 06:08:24 +00:00
|
|
|
int width, height;
|
2021-05-18 11:51:36 +00:00
|
|
|
if (info->largeLodLog2 != info->smallLodLog2) WriteTrace(TraceGlitch, TraceWarning, "gfxTexTextureMemRequired: Loading more than one LOD");
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
if (info->aspectRatioLog2 < 0)
|
|
|
|
{
|
|
|
|
height = 1 << info->largeLodLog2;
|
|
|
|
width = height >> -info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width = 1 << info->largeLodLog2;
|
|
|
|
height = width >> info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (info->format)
|
|
|
|
{
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_8:
|
|
|
|
case GFX_TEXFMT_INTENSITY_8: // I8 support - H.Morii
|
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_44:
|
2016-02-04 06:08:24 +00:00
|
|
|
return width*height;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_1555:
|
|
|
|
case GFX_TEXFMT_ARGB_4444:
|
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_88:
|
|
|
|
case GFX_TEXFMT_RGB_565:
|
2016-02-04 06:08:24 +00:00
|
|
|
return (width*height) << 1;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_8888:
|
2016-02-04 06:08:24 +00:00
|
|
|
return (width*height) << 2;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((((width + 0x3)&~0x3)*((height + 0x3)&~0x3)) >> 1);
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3:
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((width + 0x3)&~0x3)*((height + 0x3)&~0x3);
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((width + 0x3)&~0x3)*((height + 0x3)&~0x3);
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((((width + 0x7)&~0x7)*((height + 0x3)&~0x3)) >> 1);
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexTextureMemRequired: Unknown texture format: %x", info->format);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
return 0;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-25 22:17:52 +00:00
|
|
|
uint32_t gfxTexCalcMemRequired(gfxLOD_t lodmin, gfxLOD_t lodmax, gfxAspectRatio_t aspect, gfxTextureFormat_t fmt)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "lodmin = %d, lodmax: %d aspect: %d fmt: %d", lodmin, lodmax, aspect, fmt);
|
2016-02-04 06:08:24 +00:00
|
|
|
int width, height;
|
2021-05-18 11:51:36 +00:00
|
|
|
if (lodmax != lodmin) WriteTrace(TraceGlitch, TraceWarning, "gfxTexCalcMemRequired: Loading more than one LOD");
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
if (aspect < 0)
|
|
|
|
{
|
|
|
|
height = 1 << lodmax;
|
|
|
|
width = height >> -aspect;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width = 1 << lodmax;
|
|
|
|
height = width >> aspect;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (fmt)
|
|
|
|
{
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_8:
|
|
|
|
case GFX_TEXFMT_INTENSITY_8: // I8 support - H.Morii
|
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_44:
|
2016-02-04 06:08:24 +00:00
|
|
|
return width*height;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_1555:
|
|
|
|
case GFX_TEXFMT_ARGB_4444:
|
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_88:
|
|
|
|
case GFX_TEXFMT_RGB_565:
|
2016-02-04 06:08:24 +00:00
|
|
|
return (width*height) << 1;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_8888:
|
2016-02-04 06:08:24 +00:00
|
|
|
return (width*height) << 2;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((((width + 0x3)&~0x3)*((height + 0x3)&~0x3)) >> 1);
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3:
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((width + 0x3)&~0x3)*((height + 0x3)&~0x3);
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((width + 0x3)&~0x3)*((height + 0x3)&~0x3);
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
return ((((width + 0x7)&~0x7)*((height + 0x3)&~0x3)) >> 1);
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexTextureMemRequired: Unknown texture format: %x", fmt);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
return 0;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int grTexFormatSize(int fmt)
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
int factor = -1;
|
|
|
|
switch (fmt) {
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_8:
|
|
|
|
case GFX_TEXFMT_INTENSITY_8: // I8 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 1;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_44:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 1;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_RGB_565:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_1555:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_88:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_4444:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_8888:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 4;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 8; // HACKALERT: factor holds block bytes
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 16; // HACKALERT: factor holds block bytes
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 16;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 8;
|
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "grTexFormatSize: Unknown texture format: %x", fmt);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
return factor;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
int factor = -1;
|
|
|
|
switch (fmt) {
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_8:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 1;
|
|
|
|
*gltexfmt = GL_INTENSITY8;
|
|
|
|
*glpixfmt = GL_LUMINANCE;
|
|
|
|
*glpackfmt = GL_UNSIGNED_BYTE;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_INTENSITY_8: // I8 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 1;
|
|
|
|
*gltexfmt = GL_LUMINANCE8;
|
|
|
|
*glpixfmt = GL_LUMINANCE;
|
|
|
|
*glpackfmt = GL_UNSIGNED_BYTE;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_44:
|
2016-02-04 06:08:24 +00:00
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_RGB_565:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
*gltexfmt = GL_RGB;
|
|
|
|
*glpixfmt = GL_RGB;
|
|
|
|
*glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_1555:
|
2016-02-04 06:08:24 +00:00
|
|
|
if (ati_sucks > 0) return -1; // ATI sucks as usual (fixes slowdown on ATI)
|
|
|
|
factor = 2;
|
|
|
|
*gltexfmt = GL_RGB5_A1;
|
|
|
|
*glpixfmt = GL_BGRA;
|
|
|
|
*glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_88:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
*gltexfmt = GL_LUMINANCE8_ALPHA8;
|
|
|
|
*glpixfmt = GL_LUMINANCE_ALPHA;
|
|
|
|
*glpackfmt = GL_UNSIGNED_BYTE;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_4444:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
*gltexfmt = GL_RGBA4;
|
|
|
|
*glpixfmt = GL_BGRA;
|
|
|
|
*glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_8888:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 4;
|
|
|
|
*gltexfmt = GL_RGBA8;
|
|
|
|
*glpixfmt = GL_BGRA;
|
|
|
|
*glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
|
|
|
|
// HACKALERT: 3Dfx Glide uses GFX_TEXFMT_ARGB_CMP_DXT1 for both opaque DXT1 and DXT1 with 1bit alpha.
|
2016-02-04 06:08:24 +00:00
|
|
|
// GlideHQ compiled with GLIDE64_DXTN option enabled, uses opaqe DXT1 only.
|
|
|
|
factor = 8; // HACKALERT: factor holds block bytes
|
2021-05-18 11:51:36 +00:00
|
|
|
*gltexfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // These variables aren't used
|
2016-02-04 06:08:24 +00:00
|
|
|
*glpixfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
|
|
|
*glpackfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 16;
|
|
|
|
*gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
|
|
|
*glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
|
|
|
*glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 16;
|
|
|
|
*gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
|
|
|
*glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
|
|
|
*glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 8;
|
|
|
|
*gltexfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
|
|
|
|
*glpixfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;
|
2021-05-18 11:51:36 +00:00
|
|
|
*glpackfmt = GL_COMPRESSED_RGBA_FXT1_3DFX; // what should we do about GL_COMPRESSED_RGB_FXT1_3DFX?
|
2016-02-04 06:08:24 +00:00
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "grTexFormat2GLPackedFmt: Unknown texture format: %x", fmt);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
return factor;
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 07:25:40 +00:00
|
|
|
void gfxTexDownloadMipMap(gfxChipID_t tmu, uint32_t startAddress, gfxMipMapLevelMask_t evenOdd, gfxTexInfo *info)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d, startAddress: %d evenOdd: %d", tmu, startAddress, evenOdd);
|
|
|
|
|
2016-02-04 06:08:24 +00:00
|
|
|
int width, height, i, j;
|
|
|
|
int factor;
|
|
|
|
int glformat = 0;
|
|
|
|
int gltexfmt = 0, glpixfmt = 0, glpackfmt = 0;
|
2021-05-18 11:51:36 +00:00
|
|
|
if (info->largeLodLog2 != info->smallLodLog2) WriteTrace(TraceGlitch, TraceWarning, "gfxTexDownloadMipMap: Loading more than one LOD");
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
if (info->aspectRatioLog2 < 0)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
height = 1 << info->largeLodLog2;
|
|
|
|
width = height >> -info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width = 1 << info->largeLodLog2;
|
|
|
|
height = width >> info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!packed_pixels_support)
|
|
|
|
factor = -1;
|
|
|
|
else
|
|
|
|
factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);
|
|
|
|
|
|
|
|
if (factor < 0) {
|
|
|
|
// VP fixed the texture conversions to be more accurate, also swapped
|
|
|
|
// the for i/j loops so that is is less likely to break the memory cache
|
|
|
|
register int n = 0, m = 0;
|
|
|
|
switch (info->format)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_8:
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
|
|
|
|
texel |= (texel << 8);
|
|
|
|
texel |= (texel << 16);
|
|
|
|
((unsigned int*)texture)[n] = texel;
|
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factor = 1;
|
|
|
|
glformat = GL_INTENSITY8;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_INTENSITY_8: // I8 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
|
|
|
|
texel |= (0xFF000000 | (texel << 16) | (texel << 8));
|
|
|
|
((unsigned int*)texture)[n] = texel;
|
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factor = 1;
|
|
|
|
glformat = GL_LUMINANCE8;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_44:
|
2013-04-10 07:08:48 +00:00
|
|
|
#if 1
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];
|
2013-04-10 07:08:48 +00:00
|
|
|
#if 1
|
2021-05-18 11:51:36 +00:00
|
|
|
// Accurate conversion
|
2016-02-04 06:08:24 +00:00
|
|
|
unsigned int texel_hi = (texel & 0x000000F0) << 20;
|
|
|
|
unsigned int texel_low = texel & 0x0000000F;
|
|
|
|
texel_low |= (texel_low << 4);
|
|
|
|
texel_hi |= ((texel_hi << 4) | (texel_low << 16) | (texel_low << 8) | texel_low);
|
2013-04-10 07:08:48 +00:00
|
|
|
#else
|
2016-02-04 06:08:24 +00:00
|
|
|
unsigned int texel_hi = (texel & 0x000000F0) << 24;
|
|
|
|
unsigned int texel_low = (texel & 0x0000000F) << 4;
|
|
|
|
texel_hi |= ((texel_low << 16) | (texel_low << 8) | texel_low);
|
2013-04-10 07:08:48 +00:00
|
|
|
#endif
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = texel_hi;
|
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factor = 1;
|
|
|
|
glformat = GL_LUMINANCE4_ALPHA4;
|
2013-04-10 07:08:48 +00:00
|
|
|
#endif
|
2016-02-04 06:08:24 +00:00
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_RGB_565:
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
|
|
|
|
unsigned int B = texel & 0x0000F800;
|
|
|
|
unsigned int G = texel & 0x000007E0;
|
|
|
|
unsigned int R = texel & 0x0000001F;
|
2013-04-10 07:08:48 +00:00
|
|
|
#if 0
|
2021-05-18 11:51:36 +00:00
|
|
|
// Accurate conversion
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | ((R >> 2) << 16) | (G << 5) | ((G >> 9) << 8) | (B >> 8) | (B >> 13);
|
2013-04-10 07:08:48 +00:00
|
|
|
#else
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8);
|
2013-04-10 07:08:48 +00:00
|
|
|
#endif
|
2016-02-04 06:08:24 +00:00
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
2017-07-22 22:42:02 +00:00
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
glformat = GL_RGB;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_1555:
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
|
|
|
|
unsigned int A = texel & 0x00008000 ? 0xFF000000 : 0;
|
|
|
|
unsigned int B = texel & 0x00007C00;
|
|
|
|
unsigned int G = texel & 0x000003E0;
|
|
|
|
unsigned int R = texel & 0x0000001F;
|
2013-04-10 07:08:48 +00:00
|
|
|
#if 0
|
2021-05-18 11:51:36 +00:00
|
|
|
// Accurate conversion
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = A | (R << 19) | ((R >> 2) << 16) | (G << 6) | ((G >> 8) << 8) | (B >> 7) | (B >> 12);
|
2013-04-10 07:08:48 +00:00
|
|
|
#else
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = A | (R << 19) | (G << 6) | (B >> 7);
|
2013-04-10 07:08:48 +00:00
|
|
|
#endif
|
2016-02-04 06:08:24 +00:00
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
2017-07-22 22:42:02 +00:00
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
glformat = GL_RGB5_A1;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ALPHA_INTENSITY_88:
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int AI = (unsigned int)((unsigned short*)info->data)[m];
|
|
|
|
unsigned int I = (unsigned int)(AI & 0x000000FF);
|
|
|
|
((unsigned int*)texture)[n] = (AI << 16) | (I << 8) | I;
|
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factor = 2;
|
|
|
|
glformat = GL_LUMINANCE8_ALPHA8;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_4444:
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];
|
|
|
|
unsigned int A = texel & 0x0000F000;
|
|
|
|
unsigned int B = texel & 0x00000F00;
|
|
|
|
unsigned int G = texel & 0x000000F0;
|
|
|
|
unsigned int R = texel & 0x0000000F;
|
2013-04-10 07:08:48 +00:00
|
|
|
#if 0
|
2021-05-18 11:51:36 +00:00
|
|
|
// Accurate conversion
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = (A << 16) | (A << 12) | (R << 20) | (R << 16) | (G << 8) | (G << 4) | (B >> 4) | (B >> 8);
|
2013-04-10 07:08:48 +00:00
|
|
|
#else
|
2016-02-04 06:08:24 +00:00
|
|
|
((unsigned int*)texture)[n] = (A << 16) | (R << 20) | (G << 8) | (B >> 4);
|
2013-04-10 07:08:48 +00:00
|
|
|
#endif
|
2016-02-04 06:08:24 +00:00
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
2017-07-22 22:42:02 +00:00
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 2;
|
|
|
|
glformat = GL_RGBA4;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_8888:
|
2016-02-04 06:08:24 +00:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
unsigned int texel = ((unsigned int*)info->data)[m];
|
|
|
|
unsigned int A = texel & 0xFF000000;
|
|
|
|
unsigned int B = texel & 0x00FF0000;
|
|
|
|
unsigned int G = texel & 0x0000FF00;
|
|
|
|
unsigned int R = texel & 0x000000FF;
|
|
|
|
((unsigned int*)texture)[n] = A | (R << 16) | G | (B >> 16);
|
|
|
|
m++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factor = 4;
|
|
|
|
glformat = GL_RGBA8;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 8; // HACKALERT: factor holds block bytes
|
|
|
|
glformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 16; // HACKALERT: factor holds block bytes
|
|
|
|
glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 16;
|
|
|
|
glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
|
|
|
break;
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 8;
|
|
|
|
glformat = GL_COMPRESSED_RGBA_FXT1_3DFX;
|
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexDownloadMipMap: Unknown texture format: %x", info->format);
|
2016-02-04 06:08:24 +00:00
|
|
|
factor = 0;
|
2017-07-22 22:42:02 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
if (nbTextureUnits <= 2)
|
|
|
|
glActiveTextureARB(GL_TEXTURE1_ARB);
|
|
|
|
else
|
|
|
|
glActiveTextureARB(GL_TEXTURE2_ARB);
|
|
|
|
|
|
|
|
switch (info->format)
|
|
|
|
{
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1:
|
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3:
|
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
remove_tex(startAddress + 1, startAddress + 1 + ((width*height*factor) >> 4));
|
|
|
|
break;
|
2013-04-10 07:08:48 +00:00
|
|
|
default:
|
2016-02-04 06:08:24 +00:00
|
|
|
remove_tex(startAddress + 1, startAddress + 1 + (width*height*factor));
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
add_tex(startAddress + 1);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, startAddress + 1);
|
|
|
|
|
|
|
|
if (largest_supported_anisotropy > 1.0f)
|
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
|
|
|
|
|
|
|
|
switch (info->format)
|
|
|
|
{
|
2017-05-17 10:34:55 +00:00
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT1:
|
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT3:
|
|
|
|
case GFX_TEXFMT_ARGB_CMP_DXT5:
|
|
|
|
case GFX_TEXFMT_ARGB_CMP_FXT1:
|
2016-02-04 06:08:24 +00:00
|
|
|
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, (glformat ? glformat : gltexfmt), width, height, 0, (width*height*factor) >> 4, info->data);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (glformat) {
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, default_texture);
|
2017-07-20 07:54:25 +00:00
|
|
|
grDisplayGLError("gfxTexDownloadMipMap");
|
2017-07-22 22:42:02 +00:00
|
|
|
}
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2017-07-25 08:29:37 +00:00
|
|
|
int CheckTextureBufferFormat(gfxChipID_t tmu, uint32_t startAddress, gfxTexInfo *info);
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2017-07-25 08:29:37 +00:00
|
|
|
void gfxTexSource(gfxChipID_t tmu, uint32_t startAddress, uint32_t evenOdd, gfxTexInfo *info)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d, startAddress: %d evenOdd: %d", tmu, startAddress, evenOdd);
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2017-07-23 00:04:04 +00:00
|
|
|
if (tmu == GFX_TMU1 || nbTextureUnits <= 2)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2017-07-23 00:04:04 +00:00
|
|
|
if (tmu == GFX_TMU1 && nbTextureUnits <= 2) return;
|
2016-02-04 06:08:24 +00:00
|
|
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2016-02-04 06:08:24 +00:00
|
|
|
if (info->aspectRatioLog2 < 0)
|
|
|
|
{
|
|
|
|
tex0_height = 256;
|
|
|
|
tex0_width = tex0_height >> -info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tex0_width = 256;
|
|
|
|
tex0_height = tex0_width >> info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, startAddress + 1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
glActiveTextureARB(GL_TEXTURE1_ARB);
|
|
|
|
|
|
|
|
if (info->aspectRatioLog2 < 0)
|
|
|
|
{
|
|
|
|
tex1_height = 256;
|
|
|
|
tex1_width = tex1_height >> -info->aspectRatioLog2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tex1_width = 256;
|
|
|
|
tex1_height = tex1_width >> info->aspectRatioLog2;
|
|
|
|
}
|
2013-04-10 07:08:48 +00:00
|
|
|
|
2016-02-04 06:08:24 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, startAddress + 1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
if (!CheckTextureBufferFormat(tmu, startAddress + 1, info))
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
if (tmu == 0 && blackandwhite1 != 0)
|
|
|
|
{
|
|
|
|
blackandwhite1 = 0;
|
|
|
|
need_to_compile = 1;
|
|
|
|
}
|
|
|
|
if (tmu == 1 && blackandwhite0 != 0)
|
|
|
|
{
|
|
|
|
blackandwhite0 = 0;
|
|
|
|
need_to_compile = 1;
|
|
|
|
}
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
2017-07-20 07:58:16 +00:00
|
|
|
grDisplayGLError("gfxTexSource");
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-08-08 22:38:00 +00:00
|
|
|
void gfxTexDetailControl(gfxChipID_t tmu, int lod_bias, uint8_t detail_scale, float detail_max)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d, lod_bias: %d detail_scale: %d detail_max: %d", tmu, lod_bias, detail_scale, detail_max);
|
2016-02-04 06:08:24 +00:00
|
|
|
if (lod_bias != 31 && detail_scale != 7)
|
|
|
|
{
|
|
|
|
if (!lod_bias && !detail_scale && !detail_max) return;
|
|
|
|
else
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexDetailControl: %d, %d, %f", lod_bias, detail_scale, detail_max);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
lambda = detail_max;
|
|
|
|
if (lambda > 1.0f)
|
|
|
|
{
|
|
|
|
lambda = 1.0f - (255.0f - lambda);
|
|
|
|
}
|
2016-02-14 08:59:33 +00:00
|
|
|
if (lambda > 1.0f) WriteTrace(TraceGlitch, TraceWarning, "lambda:%f", lambda);
|
2016-02-04 06:08:24 +00:00
|
|
|
|
|
|
|
set_lambda();
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-08-08 20:23:11 +00:00
|
|
|
void gfxTexFilterMode(gfxChipID_t tmu, gfxTextureFilterMode_t minfilter_mode, gfxTextureFilterMode_t magfilter_mode)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d, bias: %d magfilter_mode: %d", tmu, minfilter_mode, magfilter_mode);
|
2017-07-23 00:04:04 +00:00
|
|
|
if (tmu == GFX_TMU1 || nbTextureUnits <= 2)
|
2016-02-04 06:08:24 +00:00
|
|
|
{
|
2017-07-23 00:04:04 +00:00
|
|
|
if (tmu == GFX_TMU1 && nbTextureUnits <= 2) return;
|
2017-08-08 20:23:11 +00:00
|
|
|
if (minfilter_mode == GFX_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;
|
2016-02-04 06:08:24 +00:00
|
|
|
else min_filter0 = GL_LINEAR;
|
|
|
|
|
2017-08-08 20:23:11 +00:00
|
|
|
if (magfilter_mode == GFX_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;
|
2016-02-04 06:08:24 +00:00
|
|
|
else mag_filter0 = GL_LINEAR;
|
|
|
|
|
|
|
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-08-08 20:23:11 +00:00
|
|
|
if (minfilter_mode == GFX_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;
|
2016-02-04 06:08:24 +00:00
|
|
|
else min_filter1 = GL_LINEAR;
|
|
|
|
|
2017-08-08 20:23:11 +00:00
|
|
|
if (magfilter_mode == GFX_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;
|
2016-02-04 06:08:24 +00:00
|
|
|
else mag_filter1 = GL_LINEAR;
|
|
|
|
|
|
|
|
glActiveTextureARB(GL_TEXTURE1_ARB);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
|
|
|
|
}
|
2017-07-20 08:10:10 +00:00
|
|
|
grDisplayGLError("gfxTexFilterMode");
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
|
|
|
|
2017-08-08 19:55:25 +00:00
|
|
|
void gfxTexClampMode(gfxChipID_t tmu, gfxTextureClampMode_t s_clampmode, gfxTextureClampMode_t t_clampmode)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 10:22:19 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceDebug, "tmu = %d, s_clampmode: %d t_clampmode: %d", tmu, s_clampmode, t_clampmode);
|
2017-07-23 00:04:04 +00:00
|
|
|
if (tmu == GFX_TMU1 || nbTextureUnits <= 2)
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2017-07-23 00:04:04 +00:00
|
|
|
if (tmu == GFX_TMU1 && nbTextureUnits <= 2) return;
|
2016-02-04 06:08:24 +00:00
|
|
|
switch (s_clampmode)
|
|
|
|
{
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_WRAP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_s0 = GL_REPEAT;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_CLAMP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_s0 = GL_CLAMP_TO_EDGE;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_MIRROR_EXT:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_s0 = GL_MIRRORED_REPEAT_ARB;
|
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexClampMode: Unknown s_clampmode : %x", s_clampmode);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
switch (t_clampmode)
|
|
|
|
{
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_WRAP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_t0 = GL_REPEAT;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_CLAMP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_t0 = GL_CLAMP_TO_EDGE;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_MIRROR_EXT:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_t0 = GL_MIRRORED_REPEAT_ARB;
|
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexClampMode: Unknown t_clampmode : %x", t_clampmode);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
2016-02-04 06:08:24 +00:00
|
|
|
else
|
2013-04-10 07:08:48 +00:00
|
|
|
{
|
2016-02-04 06:08:24 +00:00
|
|
|
switch (s_clampmode)
|
|
|
|
{
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_WRAP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_s1 = GL_REPEAT;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_CLAMP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_s1 = GL_CLAMP_TO_EDGE;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_MIRROR_EXT:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_s1 = GL_MIRRORED_REPEAT_ARB;
|
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexClampMode: Unknown s_clampmode : %x", s_clampmode);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
switch (t_clampmode)
|
|
|
|
{
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_WRAP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_t1 = GL_REPEAT;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_CLAMP:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_t1 = GL_CLAMP_TO_EDGE;
|
|
|
|
break;
|
2017-08-08 19:55:25 +00:00
|
|
|
case GFX_TEXTURECLAMP_MIRROR_EXT:
|
2016-02-04 06:08:24 +00:00
|
|
|
wrap_t1 = GL_MIRRORED_REPEAT_ARB;
|
|
|
|
break;
|
|
|
|
default:
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceGlitch, TraceWarning, "gfxTexClampMode: Unknown t_clampmode : %x", t_clampmode);
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|
|
|
|
glActiveTextureARB(GL_TEXTURE1_ARB);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
|
2013-04-10 07:08:48 +00:00
|
|
|
}
|
2017-07-20 08:07:50 +00:00
|
|
|
grDisplayGLError("gfxTexClampMode");
|
2016-02-04 06:08:24 +00:00
|
|
|
}
|