diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index b53865f97..d6a79d9d7 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -20,14 +20,6 @@ void rend_set_fb_scale(float x,float y); void rend_resize(int width, int height); void rend_text_invl(vram_block* bl); -#ifdef GLuint -GLuint -#else -u32 -#endif -GetTexture(TSP tsp,TCW tcw); - - /////// extern TA_context* _pvrrc; @@ -50,7 +42,7 @@ struct Renderer 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; @@ -64,6 +56,9 @@ Renderer* rend_GL4(); #endif Renderer* rend_norend(); Renderer* rend_softrend(); +#ifdef USE_VULKAN +Renderer* rend_Vulkan(); +#endif extern u32 fb_watch_addr_start; extern u32 fb_watch_addr_end; diff --git a/core/hw/pvr/ta_ctx.h b/core/hw/pvr/ta_ctx.h index d91b37e31..4e9c2d902 100644 --- a/core/hw/pvr/ta_ctx.h +++ b/core/hw/pvr/ta_ctx.h @@ -30,7 +30,7 @@ struct PolyParam u32 first; //entry index , holds vertex/pos data u32 count; - u32 texid; + u64 texid; TSP tsp; TCW tcw; @@ -41,7 +41,7 @@ struct PolyParam //float zMin,zMax; TSP tsp1; TCW tcw1; - u32 texid1; + u64 texid1; }; struct ModifierVolumeParam diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index 26704bf3e..4a97e1cff 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -1,3 +1,5 @@ +#include +#include #ifndef TARGET_NO_OPENMP #include #endif @@ -727,3 +729,79 @@ void BaseTextureCacheData::CheckCustomTexture() custom_image_data = NULL; } } + +static std::unordered_map> TexCache; +typedef std::unordered_map>::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(tf); + + tf->tsp = tsp; + tf->tcw = tcw; + } + + return tf; +} + +void CollectCleanup() +{ + vector 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"); +} diff --git a/core/rend/TexCache.h b/core/rend/TexCache.h index eceb807ac..2b28d85c4 100644 --- a/core/rend/TexCache.h +++ b/core/rend/TexCache.h @@ -700,3 +700,6 @@ struct BaseTextureCacheData virtual bool Delete(); virtual ~BaseTextureCacheData() {} }; +BaseTextureCacheData *getTextureCacheData(TSP tsp, TCW tcw, BaseTextureCacheData *(*factory)()); +void CollectCleanup(); +void killtex(); diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 51c6343df..8e89a0902 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -119,7 +119,8 @@ void setFragDepth(void) \n\ struct PolyParam { \n\ int first; \n\ int count; \n\ - int texid; \n\ + int texid_low; \n\ + int texid_high; \n\ int tsp; \n\ int tcw; \n\ int pcw; \n\ @@ -128,7 +129,8 @@ struct PolyParam { \n\ int tileclip; \n\ int tsp1; \n\ int tcw1; \n\ - int texid1; \n\ + int texid1_low; \n\ + int texid1_high; \n\ }; \n\ layout (binding = 1, std430) readonly buffer TrPolyParamBuffer { \n\ PolyParam tr_poly_params[]; \n\ diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index 6a6533313..a0dd09294 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -174,7 +174,7 @@ template for (int i = 0; i < 2; 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); diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 83fac9be7..47cd78f75 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -1034,7 +1034,8 @@ struct gl4rend : Renderer OSD_DRAW(clear_screen); } - virtual u32 GetTexture(TSP tsp, TCW tcw) { + virtual u64 GetTexture(TSP tsp, TCW tcw) override + { return gl_GetTexture(tsp, tcw); } }; diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 0ba627480..04878176c 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -212,7 +212,7 @@ __forceinline 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_T, gp->tsp.ClampV, gp->tsp.FlipV); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index e6e2babf6..dd9d15e9d 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -2109,7 +2109,8 @@ struct glesrend : Renderer OSD_DRAW(clear_screen); } - virtual u32 GetTexture(TSP tsp, TCW tcw) { + virtual u64 GetTexture(TSP tsp, TCW tcw) override + { return gl_GetTexture(tsp, tcw); } }; diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index 233dca95c..254dcb2a8 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -148,7 +148,7 @@ extern gl_ctx gl; extern GLuint fbTextureId; 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 { u16* pdata; u32 width; @@ -166,8 +166,6 @@ void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format void findGLVersion(); text_info raw_GetTexture(TSP tsp, TCW tcw); -void killtex(); -void CollectCleanup(); void DoCleanup(); void SetCull(u32 CullMode); s32 SetTileClip(u32 val, GLint uniform); diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index 55a6ca8d3..86492f9b8 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -152,11 +152,6 @@ bool TextureCacheData::Delete() return true; } -static std::unordered_map TexCache; -typedef std::unordered_map::iterator TexCacheIter; - -static TextureCacheData *getTextureCacheData(TSP tsp, TCW tcw); - void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt) { 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.TexV = 0; tsp.TexV <= 7 && (8 << tsp.TexV) < h; tsp.TexV++); - TextureCacheData *texture_data = getTextureCacheData(tsp, tcw); + TextureCacheData *texture_data = static_cast(getTextureCacheData(tsp, tcw, [](){ return (BaseTextureCacheData *)new TextureCacheData(); })); if (texture_data->texID != 0) glcache.DeleteTextures(1, &texture_data->texID); else @@ -369,49 +364,12 @@ static int TexCacheLookups; static int TexCacheHits; static float LastTexCacheStats; -// 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 } }; - -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) +u64 gl_GetTexture(TSP tsp, TCW tcw) { TexCacheLookups++; //lookup texture - TextureCacheData* tf = getTextureCacheData(tsp, tcw); + TextureCacheData* tf = static_cast(getTextureCacheData(tsp, tcw, [](){ return (BaseTextureCacheData *)new TextureCacheData(); })); if (tf->texID == 0) { @@ -449,23 +407,10 @@ text_info raw_GetTexture(TSP tsp, TCW tcw) text_info rv = { 0 }; //lookup texture - TextureCacheData* tf; - u64 key = ((u64)(tcw.full & TCWTextureCacheMask.full) << 32) | (tsp.full & TSPTextureCacheMask.full); + TextureCacheData* tf = static_cast(getTextureCacheData(tsp, tcw, [](){ return (BaseTextureCacheData *)new TextureCacheData(); })); - TexCacheIter tx = TexCache.find(key); - - if (tx != TexCache.end()) - { - tf = &tx->second; - } - else //create if not existing - { - tf = &TexCache[key]; - - tf->tsp = tsp; - tf->tcw = tcw; + if (tf->pData == nullptr) tf->Create(); - } //update if needed if (tf->NeedsUpdate()) @@ -484,41 +429,9 @@ text_info raw_GetTexture(TSP tsp, TCW tcw) return rv; } -void CollectCleanup() { - vector 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 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) {