From 6ce2c850470e4d0600d69a11ae2347a643a44a65 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 20 Jul 2019 12:54:31 -0400 Subject: [PATCH] Buffer_Cache: Implement flushing. --- src/video_core/buffer_cache/buffer_cache.h | 27 ++++++++++++++++++- .../renderer_opengl/gl_buffer_cache.cpp | 4 +++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 03b288233..38ce16ed5 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -79,12 +79,16 @@ public: } void Map(std::size_t max_size) { + std::lock_guard lock{mutex}; + std::tie(buffer_ptr, buffer_offset_base, invalidated) = stream_buffer->Map(max_size, 4); buffer_offset = buffer_offset_base; } /// Finishes the upload stream, returns true on bindings invalidation. bool Unmap() { + std::lock_guard lock{mutex}; + stream_buffer->Unmap(buffer_offset - buffer_offset_base); return std::exchange(invalidated, false); } @@ -103,7 +107,15 @@ public: void FlushRegion(CacheAddr addr, std::size_t size) { std::lock_guard lock{mutex}; - // TODO + std::vector objects = GetMapsInRange(addr, size); + std::sort(objects.begin(), objects.end(), [](const MapInterval& a, const MapInterval& b) { + return a->GetModificationTick() < b->GetModificationTick(); + }); + for (auto& object : objects) { + if (object->IsModified() && object->IsRegistered()) { + FlushMap(object); + } + } } /// Mark the specified region as being invalidated @@ -205,11 +217,13 @@ private: CacheAddr new_start = cache_addr; CacheAddr new_end = cache_addr_end; bool write_inheritance = false; + bool modified_inheritance = false; // Calculate new buffer parameters for (auto& overlap : overlaps) { new_start = std::min(overlap->GetStart(), new_start); new_end = std::max(overlap->GetEnd(), new_end); write_inheritance |= overlap->IsWritten(); + modified_inheritance |= overlap->IsModified(); } GPUVAddr new_gpu_addr = gpu_addr + new_start - cache_addr; for (auto& overlap : overlaps) { @@ -217,6 +231,9 @@ private: } UpdateBlock(block, new_start, new_end, overlaps); MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr); + if (modified_inheritance) { + new_map->MarkAsModified(true, GetModifiedTicks()); + } Register(new_map, write_inheritance); return new_map; } @@ -258,6 +275,14 @@ private: return ++modified_ticks; } + void FlushMap(MapInterval map) { + std::size_t size = map->GetEnd() - map->GetStart(); + TBuffer block = blocks[map->GetStart() >> block_page_bits]; + u8* host_ptr = FromCacheAddr(map->GetStart()); + DownloadBlockData(block, block->GetOffset(map->GetStart()), size, host_ptr); + map->MarkAsModified(false, 0); + } + BufferInfo StreamBufferUpload(const void* raw_pointer, std::size_t size, std::size_t alignment) { AlignBuffer(alignment); diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index a45d2771b..0781e6595 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -7,12 +7,15 @@ #include #include "common/assert.h" +#include "common/microprofile.h" #include "video_core/renderer_opengl/gl_buffer_cache.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_resource_manager.h" namespace OpenGL { +MICROPROFILE_DEFINE(OpenGL_Buffer_Download, "OpenGL", "Buffer Download", MP_RGB(192, 192, 128)); + CachedBufferBlock::CachedBufferBlock(CacheAddr cache_addr, const std::size_t size) : VideoCommon::BufferBlock{cache_addr, size} { gl_buffer.Create(); @@ -53,6 +56,7 @@ void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, s void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, u8* data) { + MICROPROFILE_SCOPE(OpenGL_Buffer_Download); glGetNamedBufferSubData(*buffer->GetHandle(), static_cast(offset), static_cast(size), data); }