From 1446fb33d515fc300c33afd535b22f441544b86e Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 29 Jan 2012 20:24:23 +0100 Subject: [PATCH] TextureCacheBase: Replace the efbcopy_state member variable of texture cache entries with a more general "texture type" --- .../Core/VideoCommon/Src/TextureCacheBase.cpp | 32 +++++++++---------- .../Core/VideoCommon/Src/TextureCacheBase.h | 18 +++++------ .../Plugin_VideoDX11/Src/TextureCache.cpp | 2 +- .../Plugin_VideoDX9/Src/TextureCache.cpp | 2 +- .../Plugin_VideoOGL/Src/TextureCache.cpp | 2 +- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 0a59aeefa4..885116ae18 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -157,7 +157,7 @@ void TextureCache::ClearRenderTargets() iter = textures.begin(), tcend = textures.end(); for (; iter!=tcend; ++iter) - iter->second->efbcopy_state = EC_NO_COPY; + iter->second->type = TCET_AUTOFETCH; } TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, @@ -236,8 +236,8 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // // TODO: Don't we need to force texture decoding to RGBA8 for dynamic EFB copies? // TODO: Actually, it should be enough if the internal texture format matches... - if ((entry->efbcopy_state == EC_NO_COPY && width == entry->native_width && height == entry->native_height && full_format == entry->format && entry->num_mipmaps == maxlevel) - || (entry->efbcopy_state == EC_VRAM_DYNAMIC && entry->native_width == width && entry->native_height == height)) + if ((entry->type == TCET_AUTOFETCH && width == entry->native_width && height == entry->native_height && full_format == entry->format && entry->num_mipmaps == maxlevel) + || (entry->type == TCET_EC_DYNAMIC && entry->native_width == width && entry->native_height == height)) { // reuse the texture } @@ -291,7 +291,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // // TODO: Won't we end up recreating textures all the time because maxlevel doesn't necessarily equal texLevels? entry->num_mipmaps = maxlevel; // TODO: Does this actually work? We can't really adjust mipmap settings per-stage... - entry->efbcopy_state = EC_NO_COPY; + entry->type = TCET_AUTOFETCH; GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); } @@ -299,8 +299,8 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, entry->SetGeneralParameters(address, texture_size, full_format, entry->num_mipmaps); entry->SetDimensions(nativeW, nativeH, width, height); entry->hash = tex_hash; - if (g_ActiveConfig.bCopyEFBToTexture) entry->efbcopy_state = EC_NO_COPY; - else if (entry->IsEfbCopy()) entry->efbcopy_state = EC_VRAM_DYNAMIC; + if (g_ActiveConfig.bCopyEFBToTexture) entry->type = TCET_AUTOFETCH; + else if (entry->IsEfbCopy()) entry->type = TCET_EC_DYNAMIC; // load texture entry->Load(width, height, expandedWidth, 0, (texLevels == 0)); @@ -382,23 +382,23 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat // It also allows enhancing the visual quality by doing scaled EFB copies. // - hybrid EFB copies: // 1a) Whenever this function gets called, encode the requested EFB data to RAM (like EFB to RAM) - // 1b) Set efbcopy_state to EC_VRAM_DYNAMIC for all texture cache entries in the destination address range. + // 1b) Set type to TCET_EC_DYNAMIC for all texture cache entries in the destination address range. // If EFB copy caching is enabled, further checks will (try to) prevent redundant EFB copies. // 2) Check if a texture cache entry for the specified dstAddr already exists (i.e. if an EFB copy was triggered to that address before): // 2a) Entry doesn't exist: // - Also copy the requested EFB data to a texture object in VRAM (like EFB to texture) - // - Create a texture cache entry for the target (efbcopy_state = EC_VRAM_READY) + // - Create a texture cache entry for the target (type = TCET_EC_VRAM) // - Store a hash of the encoded RAM data in the texcache entry. - // 2b) Entry exists AND efbcopy_state is EC_VRAM_READY: + // 2b) Entry exists AND type is TCET_EC_VRAM: // - Like case 2a, but reuse the old texcache entry instead of creating a new one. - // 2c) Entry exists AND efbcopy_state is EC_VRAM_DYNAMIC: + // 2c) Entry exists AND type is TCET_EC_DYNAMIC: // - Only encode the texture to RAM (like EFB to RAM) and store a hash of the encoded data in the existing texcache entry. // - Do NOT copy the requested EFB data to a VRAM object. Reason: the texture is dynamic, i.e. the CPU is modifying it. Storing a VRAM copy is useless, because we'd always end up deleting it and reloading the data from RAM anyway. // 3) If the EFB copy gets used as a texture, compare the source RAM hash with the hash you stored when encoding the EFB data to RAM. - // 3a) If the two hashes match AND efbcopy_state is EC_VRAM_READY, reuse the VRAM copy you created - // 3b) If the two hashes differ AND efbcopy_state is EC_VRAM_READY, screw your existing VRAM copy. Set efbcopy_state to EC_VRAM_DYNAMIC. + // 3a) If the two hashes match AND type is TCET_EC_VRAM, reuse the VRAM copy you created + // 3b) If the two hashes differ AND type is TCET_EC_VRAM, screw your existing VRAM copy. Set type to TCET_EC_DYNAMIC. // Redecode the source RAM data to a VRAM object. The entry basically behaves like a normal texture now. - // 3c) If efbcopy_state is EC_VRAM_DYNAMIC, treat the EFB copy like a normal texture. + // 3c) If type is TCET_EC_DYNAMIC, treat the EFB copy like a normal texture. // Advantage: Non-dynamic EFB copies can be visually enhanced like with EFB to texture. // Compatibility is as good as EFB to RAM. // Disadvantage: Slower than EFB to texture and often even slower than EFB to RAM. @@ -614,8 +614,8 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat TCacheEntryBase *entry = textures[dstAddr]; if (entry) { - if ((entry->efbcopy_state == EC_VRAM_READY && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h) - || (entry->efbcopy_state == EC_VRAM_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h)) + if ((entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h) + || (entry->type == TCET_EC_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h)) { scaled_tex_w = tex_w; scaled_tex_h = tex_h; @@ -637,7 +637,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat entry->SetGeneralParameters(dstAddr, 0, dstFormat, 0); entry->SetDimensions(tex_w, tex_h, scaled_tex_w, scaled_tex_h); entry->SetHashes(TEXHASH_INVALID); - entry->efbcopy_state = EC_VRAM_READY; + entry->type = TCET_EC_VRAM; } entry->frameCount = frameCount; diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index 59960c7fb8..b27663dd81 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -14,11 +14,12 @@ class TextureCache { public: - enum EFBCopyState + enum TexCacheEntryType { - EC_NO_COPY, // regular texture - EC_VRAM_READY, // EFB copy sits in VRAM and is ready to use - EC_VRAM_DYNAMIC, // EFB copy sits in RAM and needs to be decoded before using it as a texture + TCET_AUTOFETCH, // Most textures, automatically fetched whenever they change +// TCET_PRELOADED, // Textures which reside in TMEM areas which are manually managed by the game + TCET_EC_VRAM, // EFB copy which sits in VRAM and is ready to be used + TCET_EC_DYNAMIC, // EFB copy which sits in RAM and needs to be decoded before being used }; struct TCacheEntryBase @@ -32,17 +33,12 @@ public: //u32 pal_hash; u32 format; - //bool is_preloaded; + enum TexCacheEntryType type; unsigned int num_mipmaps; unsigned int native_width, native_height; // Texture dimensions from the GameCube's point of view unsigned int virtual_width, virtual_height; // Texture dimensions from OUR point of view - for hires textures or scaled EFB copies - // EFB copies - enum EFBCopyState efbcopy_state; - - bool IsEfbCopy() { return efbcopy_state != EC_NO_COPY; } - // used to delete textures which haven't been used for TEXTURE_KILL_THRESHOLD frames int frameCount; @@ -83,6 +79,8 @@ public: const float *colmat) = 0; int IntersectsMemoryRange(u32 range_address, u32 range_size) const; + + bool IsEfbCopy() { return (type == TCET_EC_VRAM || type == TCET_EC_DYNAMIC); } }; virtual ~TextureCache(); // needs virtual for DX11 dtor diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index ce9bee771e..e59fbd496e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -102,7 +102,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) { - if (efbcopy_state != EC_VRAM_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) + if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) { g_renderer->ResetAPIState(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index bc84857795..2a3f12ddcf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -79,7 +79,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture(); - if (efbcopy_state != EC_VRAM_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) + if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) { LPDIRECT3DSURFACE9 Rendersurf = NULL; texture->GetSurfaceLevel(0, &Rendersurf); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index a1a7691907..f78eb11905 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -279,7 +279,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo GL_REPORT_ERRORD(); - if (efbcopy_state != EC_VRAM_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) + if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) { if (s_TempFramebuffer == 0) glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer);