summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-08-27 19:13:33 -0400
committerGravatar bunnei2015-08-27 19:13:33 -0400
commit5831fe6a60befe33e6834eeeb8657d5e31ebfa9c (patch)
treeed5eee0ce141f13ac7b1cc81347da61848cda75e /src
parentMerge pull request #1079 from aroulin/albw-jit-bug (diff)
parentgl_rasterizer_cache: Detect and ignore unnecessary texture flushes. (diff)
downloadyuzu-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.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h4
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
238void RasterizerOpenGL::CommitFramebuffer() { 238void 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
22void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { 23void 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
74void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) { 76void 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;