summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_buffer_cache.cpp
diff options
context:
space:
mode:
authorMarkus Wick <markus@selfnet.de>2018-08-29 00:27:03 +0200
committerMarkus Wick <markus@selfnet.de>2018-09-05 08:03:50 +0200
commit50a806ea671114c92b7905182a0a9140148415b2 (patch)
tree9a70d16050f9ee4edb84e923ed92fc15ed9d4482 /src/video_core/renderer_opengl/gl_buffer_cache.cpp
parentMerge pull request #1240 from degasus/optimizations (diff)
downloadyuzu-50a806ea671114c92b7905182a0a9140148415b2.tar
yuzu-50a806ea671114c92b7905182a0a9140148415b2.tar.gz
yuzu-50a806ea671114c92b7905182a0a9140148415b2.tar.bz2
yuzu-50a806ea671114c92b7905182a0a9140148415b2.tar.lz
yuzu-50a806ea671114c92b7905182a0a9140148415b2.tar.xz
yuzu-50a806ea671114c92b7905182a0a9140148415b2.tar.zst
yuzu-50a806ea671114c92b7905182a0a9140148415b2.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
new file mode 100644
index 000000000..c85fbd306
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -0,0 +1,90 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/alignment.h"
+#include "common/assert.h"
+#include "core/core.h"
+#include "core/memory.h"
+#include "video_core/renderer_opengl/gl_buffer_cache.h"
+
+namespace OpenGL {
+
+OGLBufferCache::OGLBufferCache(size_t size) : stream_buffer(GL_ARRAY_BUFFER, size) {}
+
+GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, size_t size, size_t alignment,
+ bool cache) {
+ auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
+ const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)};
+
+ // Cache management is a big overhead, so only cache entries with a given size.
+ // TODO: Figure out which size is the best for given games.
+ cache &= size >= 2048;
+
+ if (cache) {
+ auto entry = TryGet(*cpu_addr);
+ if (entry) {
+ if (entry->size >= size && entry->alignment == alignment) {
+ return entry->offset;
+ }
+ Unregister(entry);
+ }
+ }
+
+ AlignBuffer(alignment);
+ GLintptr uploaded_offset = buffer_offset;
+
+ Memory::ReadBlock(*cpu_addr, buffer_ptr, size);
+
+ buffer_ptr += size;
+ buffer_offset += size;
+
+ if (cache) {
+ auto entry = std::make_shared<CachedBufferEntry>();
+ entry->offset = uploaded_offset;
+ entry->size = size;
+ entry->alignment = alignment;
+ entry->addr = *cpu_addr;
+ Register(entry);
+ }
+
+ return uploaded_offset;
+}
+
+GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, size_t size, size_t alignment) {
+ AlignBuffer(alignment);
+ std::memcpy(buffer_ptr, raw_pointer, size);
+ GLintptr uploaded_offset = buffer_offset;
+
+ buffer_ptr += size;
+ buffer_offset += size;
+ return uploaded_offset;
+}
+
+void OGLBufferCache::Map(size_t max_size) {
+ bool invalidate;
+ std::tie(buffer_ptr, buffer_offset_base, invalidate) =
+ stream_buffer.Map(static_cast<GLsizeiptr>(max_size), 4);
+ buffer_offset = buffer_offset_base;
+
+ if (invalidate) {
+ InvalidateAll();
+ }
+}
+void OGLBufferCache::Unmap() {
+ stream_buffer.Unmap(buffer_offset - buffer_offset_base);
+}
+
+GLuint OGLBufferCache::GetHandle() {
+ return stream_buffer.GetHandle();
+}
+
+void OGLBufferCache::AlignBuffer(size_t alignment) {
+ // Align the offset, not the mapped pointer
+ GLintptr offset_aligned =
+ static_cast<GLintptr>(Common::AlignUp(static_cast<size_t>(buffer_offset), alignment));
+ buffer_ptr += offset_aligned - buffer_offset;
+ buffer_offset = offset_aligned;
+}
+
+} // namespace OpenGL