Commit fdc6796c authored by Libretro-Admin's avatar Libretro-Admin
Browse files

Backport this for GL3 renderer -

https://github.com/flyinghead/reicast-emulator/commit/d44b4284fdbf752f412e05a218803d96fd1617e0
- unfortunately crashes when selecting Çlose Content
parent da25128c
......@@ -11,6 +11,7 @@ HAVE_GENERIC_JIT := 1
HAVE_GL3 := 0
FORCE_GLES := 0
STATIC_LINKING:= 0
HAVE_TEXUPSCALE := 1
ifeq ($(HAVE_OIT), 1)
TARGET_NAME := reicast_oit
......@@ -533,6 +534,10 @@ ifeq ($(HAVE_CORE), 1)
CORE_DEFINES += -DCORE
endif
ifeq ($(HAVE_TEXUPSCALE), 1)
CORE_DEFINES += -DHAVE_TEXUPSCALE
endif
ifeq ($(HAVE_GL), 1)
ifeq ($(GLES),1)
CORE_DEFINES += -DHAVE_OPENGLES -DHAVE_OPENGLES2
......
......@@ -175,6 +175,10 @@ else
SOURCES_C += $(LIBRETRO_COMM_DIR)/rthreads/rthreads.c
endif
ifeq ($(HAVE_TEXUPSCALE),1)
SOURCES_CXX += $(DEPS_DIR)/xbrz/xbrz.cpp
endif
SOURCES_C += $(DEPS_DIR)/zlib/deflate.c \
$(DEPS_DIR)/zlib/gzlib.c \
$(DEPS_DIR)/zlib/uncompr.c \
......
......@@ -18,6 +18,7 @@
#include <cassert>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace xbrz;
......
......@@ -454,6 +454,10 @@ void LoadSettings(void)
#endif
settings.rend.RenderToTextureUpscale = 1;
settings.rend.Clipping = true;
settings.rend.TextureUpscale = 4;
settings.rend.MaxFilteredTextureSize = 1024;
settings.rend.ModifierVolumes = true;
settings.rend.TranslucentPolygonDepthMask = false;
settings.pvr.SynchronousRendering = 0;
......
#ifdef HAVE_TEXUPSCALE
#include <list>
#endif
#include "TexCache.h"
#include "hw/pvr/pvr_regs.h"
#include "hw/pvr/ta.h"
#include "hw/mem/_vmem.h"
#ifdef HAVE_TEXUPSCALE
#include "deps/ctpl/ctpl_stl.h"
#include "deps/xbrz/xbrz.h"
#endif
u8* vq_codebook;
u32 palette_index;
bool KillTex=false;
u32 palette16_ram[1024];
u32 palette32_ram[1024];
#ifdef HAVE_TEXUPSCALE
ctpl::thread_pool ThreadPool;
#endif
u32 detwiddle[2][8][1024];
//input : address in the yyyyyxxxxx format
......@@ -68,35 +81,38 @@ void palette_update(void)
memcpy(pal_rev_256,_pal_rev_256,sizeof(pal_rev_256));
memcpy(pal_rev_16,_pal_rev_16,sizeof(pal_rev_16));
#define PixelPacker pp_dx
pal_needs_update=false;
switch(PAL_RAM_CTRL&3)
{
case 0:
for (int i=0;i<1024;i++)
{
palette_ram[i]=ARGB1555(PALETTE_RAM[i]);
palette16_ram[i] = ARGB1555(PALETTE_RAM[i]);
palette32_ram[i] = ARGB1555_32(PALETTE_RAM[i]);
}
break;
case 1:
for (int i=0;i<1024;i++)
{
palette_ram[i]=ARGB565(PALETTE_RAM[i]);
palette16_ram[i] = ARGB565(PALETTE_RAM[i]);
palette32_ram[i] = ARGB565_32(PALETTE_RAM[i]);
}
break;
case 2:
for (int i=0;i<1024;i++)
{
palette_ram[i]=ARGB4444(PALETTE_RAM[i]);
palette16_ram[i] = ARGB4444(PALETTE_RAM[i]);
palette32_ram[i] = ARGB4444_32(PALETTE_RAM[i]);
}
break;
case 3:
for (int i=0;i<1024;i++)
{
palette_ram[i]=ARGB8888(PALETTE_RAM[i]);
palette16_ram[i] = ARGB8888(PALETTE_RAM[i]);
palette32_ram[i] = ARGB8888_32(PALETTE_RAM[i]);
}
break;
}
......@@ -267,3 +283,123 @@ void libCore_vramlock_Unlock_block_wb(vram_block* block)
free(block);
}
}
#ifdef HAVE_TEXUPSCALE
//
// deposterization: smoothes posterized gradients from low-color-depth (e.g. 444, 565, compressed) sources
// Shamelessly stolen from ppsspp
// Copyright (c) 2012- PPSSPP Project.
//
#define BLOCK_SIZE 32
static void deposterizeH(u32* data, u32* out, int w, int l, int u) {
static const int T = 8;
for (int y = l; y < u; ++y) {
for (int x = 0; x < w; ++x) {
int inpos = y*w + x;
u32 center = data[inpos];
if (x == 0 || x == w - 1) {
out[y*w + x] = center;
continue;
}
u32 left = data[inpos - 1];
u32 right = data[inpos + 1];
out[y*w + x] = 0;
for (int c = 0; c < 4; ++c) {
u8 lc = ((left >> c * 8) & 0xFF);
u8 cc = ((center >> c * 8) & 0xFF);
u8 rc = ((right >> c * 8) & 0xFF);
if ((lc != rc) && ((lc == cc && abs((int)((int)rc) - cc) <= T) || (rc == cc && abs((int)((int)lc) - cc) <= T))) {
// blend this component
out[y*w + x] |= ((rc + lc) / 2) << (c * 8);
} else {
// no change for this component
out[y*w + x] |= cc << (c * 8);
}
}
}
}
}
static void deposterizeV(u32* data, u32* out, int w, int h, int l, int u) {
static const int T = 8;
for (int xb = 0; xb < w / BLOCK_SIZE + 1; ++xb) {
for (int y = l; y < u; ++y) {
for (int x = xb*BLOCK_SIZE; x < (xb + 1)*BLOCK_SIZE && x < w; ++x) {
u32 center = data[y * w + x];
if (y == 0 || y == h - 1) {
out[y*w + x] = center;
continue;
}
u32 upper = data[(y - 1) * w + x];
u32 lower = data[(y + 1) * w + x];
out[y*w + x] = 0;
for (int c = 0; c < 4; ++c) {
u8 uc = ((upper >> c * 8) & 0xFF);
u8 cc = ((center >> c * 8) & 0xFF);
u8 lc = ((lower >> c * 8) & 0xFF);
if ((uc != lc) && ((uc == cc && abs((int)((int)lc) - cc) <= T) || (lc == cc && abs((int)((int)uc) - cc) <= T))) {
// blend this component
out[y*w + x] |= ((lc + uc) / 2) << (c * 8);
} else {
// no change for this component
out[y*w + x] |= cc << (c * 8);
}
}
}
}
}
}
void parallelize(const std::function<void(int,int)> &func, int start, int end, int width /* = 0 */)
{
if (ThreadPool.size() == 0)
ThreadPool.resize(max(1, (int)settings.pvr.MaxThreads));
static const int CHUNK = 8; // 32x32 best if not parall'ed (chunk >= 32)
// 8: 0.0481391 ms
// 16: 0.068005 ms
// 32: 0.0265986 ms
// 1024x512 best is 8 (or 16)
// 4: 2.19 ms
// 8: 229 - 241 Mpix/s 2.16 ms 2.185 2.183 2.11
// 16: 163 - 175 Mpix/s 2.16 ms 2.145 2.185 2.144
// 32: 129 - 142 Mpix/s 2.19 ms
// 64: 4.34 ms
const int chunk_size = width == 0 ? CHUNK : max(CHUNK, CHUNK * 128 / width);
if (end - start <= chunk_size)
{
// Don't parallelize if there isn't much to parallelize
func(start, end);
}
else
{
std::list<std::future<void>> futures;
for (int i = start; i < end; i += chunk_size)
futures.push_back(ThreadPool.push([func] (int id, int from, int to){ func(from, to); }, i, i + chunk_size));
for (auto it = futures.begin(); it != futures.end(); ++it)
it->wait();
}
}
void DePosterize(u32* source, u32* dest, int width, int height) {
u32 *tmpbuf = (u32 *)malloc(width * height * sizeof(u32));
parallelize(std::bind(&deposterizeH, source, tmpbuf, width, std::placeholders::_1, std::placeholders::_2), 0, height, width);
parallelize(std::bind(&deposterizeV, tmpbuf, dest, width, height, std::placeholders::_1, std::placeholders::_2), 0, height, width);
parallelize(std::bind(&deposterizeH, dest, tmpbuf, width, std::placeholders::_1, std::placeholders::_2), 0, height, width);
parallelize(std::bind(&deposterizeV, tmpbuf, dest, width, height, std::placeholders::_1, std::placeholders::_2), 0, height, width);
free(tmpbuf);
}
struct xbrz::ScalerCfg xbrz_cfg;
void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool has_alpha) {
parallelize(
std::bind(&xbrz::scale, factor, source, dest, width, height, has_alpha ? xbrz::ColorFormat::ARGB : xbrz::ColorFormat::RGB, xbrz_cfg,
std::placeholders::_1, std::placeholders::_2), 0, height, width);
// xbrz::scale(factor, source, dest, width, height, has_alpha ? xbrz::ColorFormat::ARGB : xbrz::ColorFormat::RGB, xbrz_cfg);
}
#endif
......@@ -3,7 +3,8 @@
extern u8* vq_codebook;
extern u32 palette_index;
extern u32 palette_ram[1024];
extern u32 palette16_ram[1024];
extern u32 palette32_ram[1024];
extern bool pal_needs_update,fog_needs_update;
extern u32 pal_rev_256[4];
extern u32 pal_rev_16[64];
......@@ -13,7 +14,7 @@ extern u32 _pal_rev_16[64];
extern u32 detwiddle[2][8][1024];
template<class pixel_type>
struct PixelBuffer
class PixelBuffer
{
pixel_type* p_buffer_start;
pixel_type* p_current_line;
......@@ -21,12 +22,45 @@ struct PixelBuffer
u32 pixels_per_line;
void init(void* data,u32 ppl_bytes)
public:
PixelBuffer()
{
p_buffer_start=p_current_line=p_current_pixel=(pixel_type*)data;
pixels_per_line=ppl_bytes/sizeof(pixel_type);
p_buffer_start = p_current_line = p_current_pixel = NULL;
}
~PixelBuffer()
{
deinit();
}
void init(u32 width, u32 height)
{
p_buffer_start = p_current_line = p_current_pixel = (pixel_type *)malloc(width * height * sizeof(pixel_type));
this->pixels_per_line = width;
}
void deinit()
{
if (p_buffer_start != NULL)
{
free(p_buffer_start);
p_buffer_start = p_current_line = p_current_pixel = NULL;
}
}
void steal_data(PixelBuffer &buffer)
{
deinit();
p_buffer_start = p_current_line = p_current_pixel = buffer.p_buffer_start;
pixels_per_line = buffer.pixels_per_line;
buffer.p_buffer_start = buffer.p_current_line = buffer.p_current_pixel = NULL;
}
__forceinline pixel_type *data(u32 x = 0, u32 y = 0)
{
return p_buffer_start + pixels_per_line * y + x;
}
__forceinline void prel(u32 x,pixel_type value)
{
p_current_pixel[x]=value;
......@@ -66,6 +100,9 @@ void palette_update(void);
#define ARGB4444( word ) ( (((word>>0)&0xF)<<4) | (((word>>4)&0xF)<<8) | (((word>>8)&0xF)<<12) | (((word>>12)&0xF)<<0) )
#define ARGB8888( word ) ( (((word>>4)&0xF)<<4) | (((word>>12)&0xF)<<8) | (((word>>20)&0xF)<<12) | (((word>>28)&0xF)<<0) )
// Unpack to 32-bit word
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && defined(GLES)
......@@ -75,6 +112,14 @@ void palette_update(void);
#define ARGB8888( word ) ( ((word >> 24) & 0xFF) | (((word >> 16) & 0xFF) << 24) | (((word >> 8) & 0xFF) << 16) | ((word & 0xFF) << 8) )
#endif
#define ARGB1555_32( word ) ( ((word & 0x8000) ? 0xFF : 0) | (((word>>10) & 0x1F)<<27) | (((word>>5) & 0x1F)<<19) | (((word>>0) & 0x1F)<<11) )
#define ARGB565_32( word ) ( (((word>>11)&0x1F)<<27) | (((word>>5)&0x3F)<<18) | (((word>>0)&0x1F)<<11) | 0xFF )
#define ARGB4444_32( word ) ( (((word>>12)&0xF)<<4) | (((word>>8)&0xF)<<28) | (((word>>4)&0xF)<<20) | (((word>>0)&0xF)<<12) )
#define ARGB8888_32( word ) ( ((word >> 24) & 0xFF) | (((word >> 16) & 0xFF) << 24) | (((word >> 8) & 0xFF) << 16) | ((word & 0xFF) << 8) )
template<class PixelPacker>
__forceinline u32 YUV422(s32 Y,s32 Yu,s32 Yv)
{
......@@ -140,7 +185,10 @@ struct name \
#define pixelcvt_end } }
#define pixelcvt_next(name,x,y) pixelcvt_end; pixelcvt_start(name,x,y)
//
//Non twiddled
//
// 16-bit pixel buffer
pixelcvt_start(conv565_PL,4,1)
{
//convert 4x1
......@@ -192,6 +240,50 @@ pixelcvt_next(convBMP_PL,4,1)
}
pixelcvt_end;
// 32-bit pixel buffer
pixelcvt32_start(conv565_PL32,4,1)
{
//convert 4x1
u16* p_in=(u16*)data;
//0,0
pb->prel(0,ARGB565_32(p_in[0]));
//1,0
pb->prel(1,ARGB565_32(p_in[1]));
//2,0
pb->prel(2,ARGB565_32(p_in[2]));
//3,0
pb->prel(3,ARGB565_32(p_in[3]));
}
pixelcvt_end;
pixelcvt32_start(conv1555_PL32,4,1)
{
//convert 4x1
u16* p_in=(u16*)data;
//0,0
pb->prel(0,ARGB1555_32(p_in[0]));
//1,0
pb->prel(1,ARGB1555_32(p_in[1]));
//2,0
pb->prel(2,ARGB1555_32(p_in[2]));
//3,0
pb->prel(3,ARGB1555_32(p_in[3]));
}
pixelcvt_end;
pixelcvt32_start(conv4444_PL32,4,1)
{
//convert 4x1
u16* p_in=(u16*)data;
//0,0
pb->prel(0,ARGB4444_32(p_in[0]));
//1,0
pb->prel(1,ARGB4444_32(p_in[1]));
//2,0
pb->prel(2,ARGB4444_32(p_in[2]));
//3,0
pb->prel(3,ARGB4444_32(p_in[3]));
}
pixelcvt_end;
pixelcvt32_start(convYUV_PL,4,1)
{
//convert 4x1 4444 to 4x1 8888
......@@ -223,7 +315,10 @@ pixelcvt32_start(convYUV_PL,4,1)
}
pixelcvt_end;
//
//twiddled
//
// 16-bit pixel buffer
pixelcvt_start(conv565_TW,2,2)
{
//convert 4x1 565 to 4x1 8888
......@@ -274,6 +369,51 @@ pixelcvt_next(convBMP_TW,2,2)
}
pixelcvt_end;
// 32-bit pixel buffer
pixelcvt32_start(conv565_TW32,2,2)
{
//convert 4x1 565 to 4x1 8888
u16* p_in=(u16*)data;
//0,0
pb->prel(0,0,ARGB565_32(p_in[0]));
//0,1
pb->prel(0,1,ARGB565_32(p_in[1]));
//1,0
pb->prel(1,0,ARGB565_32(p_in[2]));
//1,1
pb->prel(1,1,ARGB565_32(p_in[3]));
}
pixelcvt_end;
pixelcvt32_start(conv1555_TW32,2,2)
{
//convert 4x1 565 to 4x1 8888
u16* p_in=(u16*)data;
//0,0
pb->prel(0,0,ARGB1555_32(p_in[0]));
//0,1
pb->prel(0,1,ARGB1555_32(p_in[1]));
//1,0
pb->prel(1,0,ARGB1555_32(p_in[2]));
//1,1
pb->prel(1,1,ARGB1555_32(p_in[3]));
}
pixelcvt_end;
pixelcvt32_start(conv4444_TW32,2,2)
{
//convert 4x1 565 to 4x1 8888
u16* p_in=(u16*)data;
//0,0
pb->prel(0,0,ARGB4444_32(p_in[0]));
//0,1
pb->prel(0,1,ARGB4444_32(p_in[1]));
//1,0
pb->prel(1,0,ARGB4444_32(p_in[2]));
//1,1
pb->prel(1,1,ARGB4444_32(p_in[3]));
}
pixelcvt_end;
pixelcvt32_start(convYUV_TW,2,2)
{
//convert 4x1 4444 to 4x1 8888
......@@ -305,10 +445,11 @@ pixelcvt32_start(convYUV_TW,2,2)
}
pixelcvt_end;
// 16-bit && 32-bit pixel buffers
pixelcvt_size_start(convPAL4_TW,4,4)
{
u8* p_in=(u8*)data;
u32* pal=&palette_ram[palette_index];
u32* pal= sizeof(pixel_size) == 2 ? &palette16_ram[palette_index] : &palette32_ram[palette_index];
pb->prel(0,0,pal[p_in[0]&0xF]);
pb->prel(0,1,pal[(p_in[0]>>4)&0xF]);p_in++;
......@@ -335,7 +476,7 @@ pixelcvt_end;
pixelcvt_size_start(convPAL8_TW,2,4)
{
u8* p_in=(u8*)data;
u32* pal=&palette_ram[palette_index];
u32* pal= sizeof(pixel_size) == 2 ? &palette16_ram[palette_index] : &palette32_ram[palette_index];
pb->prel(0,0,pal[p_in[0]]);p_in++;
pb->prel(0,1,pal[p_in[0]]);p_in++;
......@@ -433,6 +574,10 @@ template void texture_PL<conv4444_PL<pp_565>, u16>(PixelBuffer<u16>* pb,u8* p_in
template void texture_PL<convYUV_PL<pp_8888>, u32>(PixelBuffer<u32>* pb,u8* p_in,u32 Width,u32 Height);
template void texture_PL<convBMP_PL<pp_565>, u16>(PixelBuffer<u16>* pb,u8* p_in,u32 Width,u32 Height);
#define tex565_PL32 texture_PL<conv565_PL32<pp_8888>, u32>
#define tex1555_PL32 texture_PL<conv1555_PL32<pp_8888>, u32>
#define tex4444_PL32 texture_PL<conv4444_PL32<pp_8888>, u32>
//twiddled formats !
template void texture_TW<conv565_TW<pp_565>, u16>(PixelBuffer<u16>* pb,u8* p_in,u32 Width,u32 Height);
template void texture_TW<conv1555_TW<pp_565>, u16>(PixelBuffer<u16>* pb,u8* p_in,u32 Width,u32 Height);
......@@ -470,12 +615,20 @@ template void texture_VQ<convBMP_TW<pp_565>, u16>(PixelBuffer<u16>* pb,u8* p_in,
#define texPAL4_TW32 texture_TW<convPAL4_TW<pp_8888, u32>, u32>
#define texPAL8_TW32 texture_TW<convPAL8_TW<pp_8888, u32>, u32>
#define tex565_TW32 texture_TW<conv565_TW32<pp_8888>, u32>
#define tex1555_TW32 texture_TW<conv1555_TW32<pp_8888>, u32>
#define tex4444_TW32 texture_TW<conv4444_TW32<pp_8888>, u32>
//VQ
#define tex565_VQ texture_VQ<conv565_TW<pp_565>, u16>
#define tex1555_VQ texture_VQ<conv1555_TW<pp_565>, u16>
#define tex4444_VQ texture_VQ<conv4444_TW<pp_565>, u16>
#define texYUV422_VQ texture_VQ<convYUV_TW<pp_8888>, u32>
#define texBMP_VQ texture_VQ<convBMP_TW<pp_565>, u16>
#define tex565_VQ32 texture_VQ<conv565_TW32<pp_8888>, u32>
#define tex1555_VQ32 texture_VQ<conv1555_TW32<pp_8888>, u32>
#define tex4444_VQ32 texture_VQ<conv4444_TW32<pp_8888>, u32>
#define Is_64_Bit(addr) ((addr &0x1000000)==0)
......@@ -490,3 +643,8 @@ vram_block* vramlock_Lock_32(u32 start_offset32,u32 end_offset32,void* userdata)
vram_block* vramlock_Lock_64(u32 start_offset64,u32 end_offset64,void* userdata);
void vram_LockedWrite(u32 offset64);
#ifdef HAVE_TEXUPSCALE
void DePosterize(u32* source, u32* dest, int width, int height);
void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool has_alpha);
#endif
......@@ -170,7 +170,7 @@ __forceinline void SetGPState(const PolyParam* gp, u32 cflip)
gp->pcw.Offset,
gp->tsp.FogCtrl,
gp->pcw.Gouraud,
gp->tcw.PixelFmt == 4)];
gp->tcw.PixelFmt == PixelBumpMap)];
if (CurrentShader->program == -1)
CompilePipelineShader(CurrentShader);
......
......@@ -938,6 +938,16 @@ struct glesrend : Renderer
glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
#endif
#ifdef HAVE_TEXUPSCALE
if (settings.rend.TextureUpscale > 1)
{
// Trick to preload the tables used by xBRZ
u32 src[] { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };
u32 dst[16];
UpscalexBRZ(2, src, dst, 2, 2, false);
}
#endif
return true;
}
void Resize(int w, int h) { screen_width=w; screen_height=h; }
......
......@@ -69,14 +69,14 @@ struct PvrTexInfo
PvrTexInfo format[8]=
{
// name bpp GL format Planar Twiddled VQ Planar(32b) Twiddled(32b) VQ (32b)
{"1555", 16, GL_UNSIGNED_SHORT_5_5_5_1, &tex1555_PL, &tex1555_TW, &tex1555_VQ, NULL }, //1555
{"565", 16, GL_UNSIGNED_SHORT_5_6_5, &tex565_PL, &tex565_TW, &tex565_VQ, NULL }, //565
{"4444", 16, GL_UNSIGNED_SHORT_4_4_4_4, &tex4444_PL, &tex4444_TW, &tex4444_VQ, NULL }, //4444
{"yuv", 16, GL_UNSIGNED_INT_8_8_8_8, NULL, NULL, NULL, &texYUV422_PL, &texYUV422_TW, &texYUV422_VQ }, //yuv
{"bumpmap", 16, GL_UNSIGNED_SHORT_4_4_4_4, &texBMP_PL, &texBMP_TW, &texBMP_VQ, NULL}, //bump map
{"pal4", 4, 0, 0, &texPAL4_TW, 0, NULL, &texPAL4_TW32, NULL }, //pal4
{"pal8", 8, 0, 0, &texPAL8_TW, 0, NULL, &texPAL8_TW32, NULL }, //pal8
{"ns/1555", 0}, //ns, 1555
{"1555", 16, GL_UNSIGNED_SHORT_5_5_5_1, tex1555_PL, tex1555_TW, tex1555_VQ, tex1555_PL32, tex1555_TW32, tex1555_VQ32 }, //1555
{"565", 16, GL_UNSIGNED_SHORT_5_6_5, tex565_PL, tex565_TW, tex565_VQ, tex565_PL32, tex565_TW32, tex565_VQ32 }, //565
{"4444", 16, GL_UNSIGNED_SHORT_4_4_4_4, tex4444_PL, tex4444_TW, tex4444_VQ, tex4444_PL32, tex4444_TW32, tex4444_VQ32 }, //4444
{"yuv", 16, GL_UNSIGNED_INT_8_8_8_8, NULL, NULL, NULL, texYUV422_PL, texYUV422_TW, texYUV422_VQ }, //yuv
{"bumpmap", 16, GL_UNSIGNED_SHORT_4_4_4_4, texBMP_PL, texBMP_TW, texBMP_VQ, NULL}, //bump map
{"pal4", 4, 0, 0, texPAL4_TW, 0, NULL, texPAL4_TW32, NULL }, //pal4
{"pal8", 8, 0, 0, texPAL8_TW, 0, NULL, texPAL8_TW32, NULL }, //pal8
{"ns/1555", 0},
};
const u32 MipPoint[8] =
......@@ -238,7 +238,6 @@ struct TextureCacheData
default:
printf("Unhandled texture %d\n",tcw.PixelFmt);
size=w*h*2;
memset(temp_tex_buffer,0xFFFFFFFF,size);
texconv = NULL;
texconv32 = NULL;
break;
......@@ -253,11 +252,14 @@ struct TextureCacheData
dirty = 0;
textype = tex->type;
bool has_alpha = false;
if (pal_table_rev)
{
textype = PAL_TYPE[PAL_RAM_CTRL&3];
pal_local_rev = *pal_table_rev; /* make sure to update the local rev,
so it won't have to redo the texture */
if (textype == GL_UNSIGNED_INT_8_8_8_8)
has_alpha = true;
}
palette_index = indirect_color_ptr; /* might be used if paletted texture */
......@@ -270,40 +272,84 @@ struct TextureCacheData
if (tcw.StrideSel && tcw.ScanOrder && (tex->PL || tex->PL32))
stride = (TEXT_CONTROL&31)*32; //I think this needs +1 ?
// For paletted formats, we have the choice of conversion type (16 or 32).
// Use the one that fits the palette entry size.
if (texconv32 != NULL && (pal_table_rev == NULL || textype == GL_UNSIGNED_INT_8_8_8_8))
//PrintTextureName();
if (sa_tex > VRAM_SIZE || size == 0 || sa + size > VRAM_SIZE)
{
PixelBuffer<u32> pbt;
pbt.p_buffer_start = pbt.p_current_line = pbt.p_current_pixel = (u32*)temp_tex_buffer;
pbt.pixels_per_line = w;
texconv32(&pbt, (u8*)&vram[sa], stride, h);
printf("Warning: invalid texture. Address %08X %08X size %d\n", sa_tex, sa, size);
return;
}
else if(texconv)
void *temp_tex_buffer = NULL;