diff options
| author | 2015-08-27 19:13:33 -0400 | |
|---|---|---|
| committer | 2015-08-27 19:13:33 -0400 | |
| commit | 5831fe6a60befe33e6834eeeb8657d5e31ebfa9c (patch) | |
| tree | ed5eee0ce141f13ac7b1cc81347da61848cda75e /src | |
| parent | Merge pull request #1079 from aroulin/albw-jit-bug (diff) | |
| parent | gl_rasterizer_cache: Detect and ignore unnecessary texture flushes. (diff) | |
| download | yuzu-5831fe6a60befe33e6834eeeb8657d5e31ebfa9c.tar.gz yuzu-5831fe6a60befe33e6834eeeb8657d5e31ebfa9c.tar.xz yuzu-5831fe6a60befe33e6834eeeb8657d5e31ebfa9c.zip | |
Merge pull request #1068 from bunnei/gl-hash-textures
gl_rasterizer_cache: Cache textures based on hash in addition to address.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 4 |
3 files changed, 18 insertions, 8 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index deb9971bb..f0ccc2397 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -231,8 +231,8 @@ void RasterizerOpenGL::DrawTriangles() { | |||
| 231 | u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) | 231 | u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) |
| 232 | * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); | 232 | * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |
| 233 | 233 | ||
| 234 | res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size); | 234 | res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size, true); |
| 235 | res_cache.NotifyFlush(cur_fb_depth_addr, cur_fb_depth_size); | 235 | res_cache.NotifyFlush(cur_fb_depth_addr, cur_fb_depth_size, true); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | void RasterizerOpenGL::CommitFramebuffer() { | 238 | void RasterizerOpenGL::CommitFramebuffer() { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index e4247051c..1e38c2e6d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/hash.h" | ||
| 5 | #include "common/make_unique.h" | 6 | #include "common/make_unique.h" |
| 6 | #include "common/math_util.h" | 7 | #include "common/math_util.h" |
| 7 | #include "common/microprofile.h" | 8 | #include "common/microprofile.h" |
| @@ -21,7 +22,6 @@ MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128 | |||
| 21 | 22 | ||
| 22 | void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { | 23 | void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { |
| 23 | PAddr texture_addr = config.config.GetPhysicalAddress(); | 24 | PAddr texture_addr = config.config.GetPhysicalAddress(); |
| 24 | |||
| 25 | const auto cached_texture = texture_cache.find(texture_addr); | 25 | const auto cached_texture = texture_cache.find(texture_addr); |
| 26 | 26 | ||
| 27 | if (cached_texture != texture_cache.end()) { | 27 | if (cached_texture != texture_cache.end()) { |
| @@ -51,12 +51,14 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); | 53 | const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); |
| 54 | u8* texture_src_data = Memory::GetPhysicalPointer(texture_addr); | ||
| 54 | 55 | ||
| 55 | new_texture->width = info.width; | 56 | new_texture->width = info.width; |
| 56 | new_texture->height = info.height; | 57 | new_texture->height = info.height; |
| 57 | new_texture->size = info.width * info.height * Pica::Regs::NibblesPerPixel(info.format); | 58 | new_texture->size = info.stride * info.height; |
| 59 | new_texture->addr = texture_addr; | ||
| 60 | new_texture->hash = Common::ComputeHash64(texture_src_data, new_texture->size); | ||
| 58 | 61 | ||
| 59 | u8* texture_src_data = Memory::GetPhysicalPointer(texture_addr); | ||
| 60 | std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); | 62 | std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); |
| 61 | 63 | ||
| 62 | for (int y = 0; y < info.height; ++y) { | 64 | for (int y = 0; y < info.height; ++y) { |
| @@ -71,12 +73,18 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text | |||
| 71 | } | 73 | } |
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) { | 76 | void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size, bool ignore_hash) { |
| 75 | // Flush any texture that falls in the flushed region | 77 | // Flush any texture that falls in the flushed region |
| 76 | // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound | 78 | // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound |
| 77 | auto cache_upper_bound = texture_cache.upper_bound(addr + size); | 79 | auto cache_upper_bound = texture_cache.upper_bound(addr + size); |
| 80 | |||
| 78 | for (auto it = texture_cache.begin(); it != cache_upper_bound;) { | 81 | for (auto it = texture_cache.begin(); it != cache_upper_bound;) { |
| 79 | if (MathUtil::IntervalsIntersect(addr, size, it->first, it->second->size)) { | 82 | const auto& info = *it->second; |
| 83 | |||
| 84 | // Flush the texture only if the memory region intersects and a change is detected | ||
| 85 | if (MathUtil::IntervalsIntersect(addr, size, info.addr, info.size) && | ||
| 86 | (ignore_hash || info.hash != Common::ComputeHash64(Memory::GetPhysicalPointer(info.addr), info.size))) { | ||
| 87 | |||
| 80 | it = texture_cache.erase(it); | 88 | it = texture_cache.erase(it); |
| 81 | } else { | 89 | } else { |
| 82 | ++it; | 90 | ++it; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 96f3a925c..d8f9edf59 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -19,7 +19,7 @@ public: | |||
| 19 | void LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config); | 19 | void LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config); |
| 20 | 20 | ||
| 21 | /// Flush any cached resource that touches the flushed region | 21 | /// Flush any cached resource that touches the flushed region |
| 22 | void NotifyFlush(PAddr addr, u32 size); | 22 | void NotifyFlush(PAddr addr, u32 size, bool ignore_hash = false); |
| 23 | 23 | ||
| 24 | /// Flush all cached OpenGL resources tracked by this cache manager | 24 | /// Flush all cached OpenGL resources tracked by this cache manager |
| 25 | void FullFlush(); | 25 | void FullFlush(); |
| @@ -30,6 +30,8 @@ private: | |||
| 30 | GLuint width; | 30 | GLuint width; |
| 31 | GLuint height; | 31 | GLuint height; |
| 32 | u32 size; | 32 | u32 size; |
| 33 | u64 hash; | ||
| 34 | PAddr addr; | ||
| 33 | }; | 35 | }; |
| 34 | 36 | ||
| 35 | std::map<PAddr, std::unique_ptr<CachedTexture>> texture_cache; | 37 | std::map<PAddr, std::unique_ptr<CachedTexture>> texture_cache; |