pvr,rend: more refactoring out of gles. Change texture id to 64b

This commit is contained in:
Flyinghead 2019-10-04 13:33:08 +02:00
parent 24b973f763
commit 8202ac420b
11 changed files with 103 additions and 112 deletions

View File

@ -20,14 +20,6 @@ void rend_set_fb_scale(float x,float y);
void rend_resize(int width, int height); void rend_resize(int width, int height);
void rend_text_invl(vram_block* bl); void rend_text_invl(vram_block* bl);
#ifdef GLuint
GLuint
#else
u32
#endif
GetTexture(TSP tsp,TCW tcw);
/////// ///////
extern TA_context* _pvrrc; extern TA_context* _pvrrc;
@ -50,7 +42,7 @@ struct Renderer
virtual void DrawOSD(bool clear_screen) { } virtual void DrawOSD(bool clear_screen) { }
virtual u32 GetTexture(TSP tsp, TCW tcw) { return 0; } virtual u64 GetTexture(TSP tsp, TCW tcw) { return 0; }
}; };
extern Renderer* renderer; extern Renderer* renderer;
@ -64,6 +56,9 @@ Renderer* rend_GL4();
#endif #endif
Renderer* rend_norend(); Renderer* rend_norend();
Renderer* rend_softrend(); Renderer* rend_softrend();
#ifdef USE_VULKAN
Renderer* rend_Vulkan();
#endif
extern u32 fb_watch_addr_start; extern u32 fb_watch_addr_start;
extern u32 fb_watch_addr_end; extern u32 fb_watch_addr_end;

View File

@ -30,7 +30,7 @@ struct PolyParam
u32 first; //entry index , holds vertex/pos data u32 first; //entry index , holds vertex/pos data
u32 count; u32 count;
u32 texid; u64 texid;
TSP tsp; TSP tsp;
TCW tcw; TCW tcw;
@ -41,7 +41,7 @@ struct PolyParam
//float zMin,zMax; //float zMin,zMax;
TSP tsp1; TSP tsp1;
TCW tcw1; TCW tcw1;
u32 texid1; u64 texid1;
}; };
struct ModifierVolumeParam struct ModifierVolumeParam

View File

@ -1,3 +1,5 @@
#include <memory>
#include <unordered_map>
#ifndef TARGET_NO_OPENMP #ifndef TARGET_NO_OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
@ -727,3 +729,79 @@ void BaseTextureCacheData::CheckCustomTexture()
custom_image_data = NULL; custom_image_data = NULL;
} }
} }
static std::unordered_map<u64, std::unique_ptr<BaseTextureCacheData>> TexCache;
typedef std::unordered_map<u64, std::unique_ptr<BaseTextureCacheData>>::iterator TexCacheIter;
// Only use TexU and TexV from TSP in the cache key
// TexV : 7, TexU : 7
static const TSP TSPTextureCacheMask = { { 7, 7 } };
// TexAddr : 0x1FFFFF, Reserved : 0, StrideSel : 0, ScanOrder : 1, PixelFmt : 7, VQ_Comp : 1, MipMapped : 1
static const TCW TCWTextureCacheMask = { { 0x1FFFFF, 0, 0, 1, 7, 1, 1 } };
BaseTextureCacheData *getTextureCacheData(TSP tsp, TCW tcw, BaseTextureCacheData *(*factory)())
{
u64 key = tsp.full & TSPTextureCacheMask.full;
if (tcw.PixelFmt == PixelPal4 || tcw.PixelFmt == PixelPal8)
// Paletted textures have a palette selection that must be part of the key
// We also add the palette type to the key to avoid thrashing the cache
// when the palette type is changed. If the palette type is changed back in the future,
// this texture will stil be available.
key |= ((u64)tcw.full << 32) | ((PAL_RAM_CTRL & 3) << 6);
else
key |= (u64)(tcw.full & TCWTextureCacheMask.full) << 32;
TexCacheIter tx = TexCache.find(key);
BaseTextureCacheData* tf;
if (tx != TexCache.end())
{
tf = tx->second.get();
// Needed if the texture is updated
tf->tcw.StrideSel = tcw.StrideSel;
}
else //create if not existing
{
tf = factory();
TexCache[key] = std::unique_ptr<BaseTextureCacheData>(tf);
tf->tsp = tsp;
tf->tcw = tcw;
}
return tf;
}
void CollectCleanup()
{
vector<u64> list;
u32 TargetFrame = max((u32)120,FrameCount) - 120;
for (const auto& pair : TexCache)
{
if (pair.second->dirty && pair.second->dirty < TargetFrame)
list.push_back(pair.first);
if (list.size() > 5)
break;
}
for (u64 id : list) {
if (TexCache[id]->Delete())
{
//printf("Deleting %d\n", TexCache[list[i]].texID);
TexCache.erase(id);
}
}
}
void killtex()
{
for (auto& pair : TexCache)
pair.second->Delete();
TexCache.clear();
KillTex = false;
INFO_LOG(RENDERER, "Texture cache cleared");
}

View File

@ -700,3 +700,6 @@ struct BaseTextureCacheData
virtual bool Delete(); virtual bool Delete();
virtual ~BaseTextureCacheData() {} virtual ~BaseTextureCacheData() {}
}; };
BaseTextureCacheData *getTextureCacheData(TSP tsp, TCW tcw, BaseTextureCacheData *(*factory)());
void CollectCleanup();
void killtex();

View File

@ -119,7 +119,8 @@ void setFragDepth(void) \n\
struct PolyParam { \n\ struct PolyParam { \n\
int first; \n\ int first; \n\
int count; \n\ int count; \n\
int texid; \n\ int texid_low; \n\
int texid_high; \n\
int tsp; \n\ int tsp; \n\
int tcw; \n\ int tcw; \n\
int pcw; \n\ int pcw; \n\
@ -128,7 +129,8 @@ struct PolyParam { \n\
int tileclip; \n\ int tileclip; \n\
int tsp1; \n\ int tsp1; \n\
int tcw1; \n\ int tcw1; \n\
int texid1; \n\ int texid1_low; \n\
int texid1_high; \n\
}; \n\ }; \n\
layout (binding = 1, std430) readonly buffer TrPolyParamBuffer { \n\ layout (binding = 1, std430) readonly buffer TrPolyParamBuffer { \n\
PolyParam tr_poly_params[]; \n\ PolyParam tr_poly_params[]; \n\

View File

@ -174,7 +174,7 @@ template <u32 Type, bool SortingEnabled>
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
glActiveTexture(GL_TEXTURE0 + i); glActiveTexture(GL_TEXTURE0 + i);
GLuint texid = i == 0 ? gp->texid : gp->texid1; GLuint texid = (GLuint)(i == 0 ? gp->texid : gp->texid1);
glBindTexture(GL_TEXTURE_2D, texid == -1 ? 0 : texid); glBindTexture(GL_TEXTURE_2D, texid == -1 ? 0 : texid);

View File

@ -1034,7 +1034,8 @@ struct gl4rend : Renderer
OSD_DRAW(clear_screen); OSD_DRAW(clear_screen);
} }
virtual u32 GetTexture(TSP tsp, TCW tcw) { virtual u64 GetTexture(TSP tsp, TCW tcw) override
{
return gl_GetTexture(tsp, tcw); return gl_GetTexture(tsp, tcw);
} }
}; };

View File

@ -212,7 +212,7 @@ __forceinline
glcache.StencilFunc(GL_ALWAYS,stencil,stencil); glcache.StencilFunc(GL_ALWAYS,stencil,stencil);
glcache.BindTexture(GL_TEXTURE_2D, gp->texid == -1 ? 0 : gp->texid); glcache.BindTexture(GL_TEXTURE_2D, gp->texid == -1 ? 0 : (GLuint)gp->texid);
SetTextureRepeatMode(GL_TEXTURE_WRAP_S, gp->tsp.ClampU, gp->tsp.FlipU); SetTextureRepeatMode(GL_TEXTURE_WRAP_S, gp->tsp.ClampU, gp->tsp.FlipU);
SetTextureRepeatMode(GL_TEXTURE_WRAP_T, gp->tsp.ClampV, gp->tsp.FlipV); SetTextureRepeatMode(GL_TEXTURE_WRAP_T, gp->tsp.ClampV, gp->tsp.FlipV);

View File

@ -2109,7 +2109,8 @@ struct glesrend : Renderer
OSD_DRAW(clear_screen); OSD_DRAW(clear_screen);
} }
virtual u32 GetTexture(TSP tsp, TCW tcw) { virtual u64 GetTexture(TSP tsp, TCW tcw) override
{
return gl_GetTexture(tsp, tcw); return gl_GetTexture(tsp, tcw);
} }
}; };

View File

@ -148,7 +148,7 @@ extern gl_ctx gl;
extern GLuint fbTextureId; extern GLuint fbTextureId;
extern float fb_scale_x, fb_scale_y; extern float fb_scale_x, fb_scale_y;
GLuint gl_GetTexture(TSP tsp,TCW tcw); u64 gl_GetTexture(TSP tsp,TCW tcw);
struct text_info { struct text_info {
u16* pdata; u16* pdata;
u32 width; u32 width;
@ -166,8 +166,6 @@ void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format
void findGLVersion(); void findGLVersion();
text_info raw_GetTexture(TSP tsp, TCW tcw); text_info raw_GetTexture(TSP tsp, TCW tcw);
void killtex();
void CollectCleanup();
void DoCleanup(); void DoCleanup();
void SetCull(u32 CullMode); void SetCull(u32 CullMode);
s32 SetTileClip(u32 val, GLint uniform); s32 SetTileClip(u32 val, GLint uniform);

View File

@ -152,11 +152,6 @@ bool TextureCacheData::Delete()
return true; return true;
} }
static std::unordered_map<u64, TextureCacheData> TexCache;
typedef std::unordered_map<u64, TextureCacheData>::iterator TexCacheIter;
static TextureCacheData *getTextureCacheData(TSP tsp, TCW tcw);
void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt) void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
{ {
if (gl.rtt.fbo) glDeleteFramebuffers(1,&gl.rtt.fbo); if (gl.rtt.fbo) glDeleteFramebuffers(1,&gl.rtt.fbo);
@ -348,7 +343,7 @@ void ReadRTTBuffer() {
for (tsp.TexU = 0; tsp.TexU <= 7 && (8 << tsp.TexU) < w; tsp.TexU++); for (tsp.TexU = 0; tsp.TexU <= 7 && (8 << tsp.TexU) < w; tsp.TexU++);
for (tsp.TexV = 0; tsp.TexV <= 7 && (8 << tsp.TexV) < h; tsp.TexV++); for (tsp.TexV = 0; tsp.TexV <= 7 && (8 << tsp.TexV) < h; tsp.TexV++);
TextureCacheData *texture_data = getTextureCacheData(tsp, tcw); TextureCacheData *texture_data = static_cast<TextureCacheData*>(getTextureCacheData(tsp, tcw, [](){ return (BaseTextureCacheData *)new TextureCacheData(); }));
if (texture_data->texID != 0) if (texture_data->texID != 0)
glcache.DeleteTextures(1, &texture_data->texID); glcache.DeleteTextures(1, &texture_data->texID);
else else
@ -369,49 +364,12 @@ static int TexCacheLookups;
static int TexCacheHits; static int TexCacheHits;
static float LastTexCacheStats; static float LastTexCacheStats;
// Only use TexU and TexV from TSP in the cache key u64 gl_GetTexture(TSP tsp, TCW tcw)
// TexV : 7, TexU : 7
static const TSP TSPTextureCacheMask = { { 7, 7 } };
// TexAddr : 0x1FFFFF, Reserved : 0, StrideSel : 0, ScanOrder : 1, PixelFmt : 7, VQ_Comp : 1, MipMapped : 1
static const TCW TCWTextureCacheMask = { { 0x1FFFFF, 0, 0, 1, 7, 1, 1 } };
static TextureCacheData *getTextureCacheData(TSP tsp, TCW tcw) {
u64 key = tsp.full & TSPTextureCacheMask.full;
if (tcw.PixelFmt == PixelPal4 || tcw.PixelFmt == PixelPal8)
// Paletted textures have a palette selection that must be part of the key
// We also add the palette type to the key to avoid thrashing the cache
// when the palette type is changed. If the palette type is changed back in the future,
// this texture will stil be available.
key |= ((u64)tcw.full << 32) | ((PAL_RAM_CTRL & 3) << 6);
else
key |= (u64)(tcw.full & TCWTextureCacheMask.full) << 32;
TexCacheIter tx = TexCache.find(key);
TextureCacheData* tf;
if (tx != TexCache.end())
{
tf = &tx->second;
// Needed if the texture is updated
tf->tcw.StrideSel = tcw.StrideSel;
}
else //create if not existing
{
tf=&TexCache[key];
tf->tsp = tsp;
tf->tcw = tcw;
}
return tf;
}
GLuint gl_GetTexture(TSP tsp, TCW tcw)
{ {
TexCacheLookups++; TexCacheLookups++;
//lookup texture //lookup texture
TextureCacheData* tf = getTextureCacheData(tsp, tcw); TextureCacheData* tf = static_cast<TextureCacheData*>(getTextureCacheData(tsp, tcw, [](){ return (BaseTextureCacheData *)new TextureCacheData(); }));
if (tf->texID == 0) if (tf->texID == 0)
{ {
@ -449,23 +407,10 @@ text_info raw_GetTexture(TSP tsp, TCW tcw)
text_info rv = { 0 }; text_info rv = { 0 };
//lookup texture //lookup texture
TextureCacheData* tf; TextureCacheData* tf = static_cast<TextureCacheData*>(getTextureCacheData(tsp, tcw, [](){ return (BaseTextureCacheData *)new TextureCacheData(); }));
u64 key = ((u64)(tcw.full & TCWTextureCacheMask.full) << 32) | (tsp.full & TSPTextureCacheMask.full);
TexCacheIter tx = TexCache.find(key); if (tf->pData == nullptr)
if (tx != TexCache.end())
{
tf = &tx->second;
}
else //create if not existing
{
tf = &TexCache[key];
tf->tsp = tsp;
tf->tcw = tcw;
tf->Create(); tf->Create();
}
//update if needed //update if needed
if (tf->NeedsUpdate()) if (tf->NeedsUpdate())
@ -484,41 +429,9 @@ text_info raw_GetTexture(TSP tsp, TCW tcw)
return rv; return rv;
} }
void CollectCleanup() {
vector<u64> list;
u32 TargetFrame = max((u32)120,FrameCount) - 120;
for (const auto& pair : TexCache)
{
if (pair.second.dirty && pair.second.dirty < TargetFrame)
list.push_back(pair.first);
if (list.size() > 5)
break;
}
for (u64 id : list) {
if (TexCache[id].Delete())
{
//printf("Deleting %d\n", TexCache[list[i]].texID);
TexCache.erase(id);
}
}
}
void DoCleanup() { void DoCleanup() {
} }
void killtex()
{
for (auto& pair : TexCache)
pair.second.Delete();
TexCache.clear();
KillTex = false;
INFO_LOG(RENDERER, "Texture cache cleared");
}
void rend_text_invl(vram_block* bl) void rend_text_invl(vram_block* bl)
{ {