From 862bec001b7ada13ba0e97f95d6ad108ae8a8d0c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 19 Jul 2019 10:50:40 -0400 Subject: Video_Core: Implement a new Buffer Cache --- src/video_core/renderer_opengl/gl_buffer_cache.cpp | 47 +++++++++++++--------- src/video_core/renderer_opengl/gl_buffer_cache.h | 33 +++++++++++---- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- 3 files changed, 55 insertions(+), 27 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index 2a9b523f5..a45d2771b 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -13,22 +13,31 @@ namespace OpenGL { +CachedBufferBlock::CachedBufferBlock(CacheAddr cache_addr, const std::size_t size) + : VideoCommon::BufferBlock{cache_addr, size} { + gl_buffer.Create(); + glNamedBufferData(gl_buffer.handle, static_cast(size), nullptr, GL_DYNAMIC_DRAW); +} + +CachedBufferBlock::~CachedBufferBlock() = default; + OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, std::size_t stream_size) - : VideoCommon::BufferCache{ + : VideoCommon::BufferCache{ rasterizer, system, std::make_unique(stream_size, true)} {} OGLBufferCache::~OGLBufferCache() = default; -OGLBuffer OGLBufferCache::CreateBuffer(std::size_t size) { - OGLBuffer buffer; - buffer.Create(); - glNamedBufferData(buffer.handle, static_cast(size), nullptr, GL_DYNAMIC_DRAW); - return buffer; +Buffer OGLBufferCache::CreateBlock(CacheAddr cache_addr, std::size_t size) { + return std::make_shared(cache_addr, size); +} + +void OGLBufferCache::WriteBarrier() { + glMemoryBarrier(GL_ALL_BARRIER_BITS); } -const GLuint* OGLBufferCache::ToHandle(const OGLBuffer& buffer) { - return &buffer.handle; +const GLuint* OGLBufferCache::ToHandle(const Buffer& buffer) { + return buffer->GetHandle(); } const GLuint* OGLBufferCache::GetEmptyBuffer(std::size_t) { @@ -36,23 +45,23 @@ const GLuint* OGLBufferCache::GetEmptyBuffer(std::size_t) { return &null_buffer; } -void OGLBufferCache::UploadBufferData(const OGLBuffer& buffer, std::size_t offset, std::size_t size, - const u8* data) { - glNamedBufferSubData(buffer.handle, static_cast(offset), +void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, + const u8* data) { + glNamedBufferSubData(*buffer->GetHandle(), static_cast(offset), static_cast(size), data); } -void OGLBufferCache::DownloadBufferData(const OGLBuffer& buffer, std::size_t offset, - std::size_t size, u8* data) { - glGetNamedBufferSubData(buffer.handle, static_cast(offset), +void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, + u8* data) { + glGetNamedBufferSubData(*buffer->GetHandle(), static_cast(offset), static_cast(size), data); } -void OGLBufferCache::CopyBufferData(const OGLBuffer& src, const OGLBuffer& dst, - std::size_t src_offset, std::size_t dst_offset, - std::size_t size) { - glCopyNamedBufferSubData(src.handle, dst.handle, static_cast(src_offset), - static_cast(dst_offset), static_cast(size)); +void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, + std::size_t dst_offset, std::size_t size) { + glCopyNamedBufferSubData(*src->GetHandle(), *dst->GetHandle(), + static_cast(src_offset), static_cast(dst_offset), + static_cast(size)); } } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 8c8ac4038..fb93f22dd 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -7,7 +7,7 @@ #include #include "common/common_types.h" -#include "video_core/buffer_cache.h" +#include "video_core/buffer_cache/buffer_cache.h" #include "video_core/rasterizer_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" @@ -21,7 +21,24 @@ namespace OpenGL { class OGLStreamBuffer; class RasterizerOpenGL; -class OGLBufferCache final : public VideoCommon::BufferCache { +class CachedBufferBlock; + +using Buffer = std::shared_ptr; + +class CachedBufferBlock : public VideoCommon::BufferBlock { +public: + explicit CachedBufferBlock(CacheAddr cache_addr, const std::size_t size); + ~CachedBufferBlock(); + + const GLuint* GetHandle() const { + return &gl_buffer.handle; + } + +private: + OGLBuffer gl_buffer{}; +}; + +class OGLBufferCache final : public VideoCommon::BufferCache { public: explicit OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, std::size_t stream_size); @@ -30,17 +47,19 @@ public: const GLuint* GetEmptyBuffer(std::size_t) override; protected: - OGLBuffer CreateBuffer(std::size_t size) override; + Buffer CreateBlock(CacheAddr cache_addr, std::size_t size) override; + + void WriteBarrier() override; - const GLuint* ToHandle(const OGLBuffer& buffer) override; + const GLuint* ToHandle(const Buffer& buffer) override; - void UploadBufferData(const OGLBuffer& buffer, std::size_t offset, std::size_t size, + void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, const u8* data) override; - void DownloadBufferData(const OGLBuffer& buffer, std::size_t offset, std::size_t size, + void DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, u8* data) override; - void CopyBufferData(const OGLBuffer& src, const OGLBuffer& dst, std::size_t src_offset, + void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, std::size_t dst_offset, std::size_t size) override; }; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 80cfda7e4..019583718 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -980,7 +980,7 @@ void RasterizerOpenGL::SetupGlobalMemory(const GLShader::GlobalMemoryEntry& entr GPUVAddr gpu_addr, std::size_t size) { const auto alignment{device.GetShaderStorageBufferAlignment()}; const auto [ssbo, buffer_offset] = - buffer_cache.UploadMemory(gpu_addr, size, alignment, true, entry.IsWritten()); + buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten()); bind_ssbo_pushbuffer.Push(ssbo, buffer_offset, static_cast(size)); } -- cgit v1.2.3 From 6ce2c850470e4d0600d69a11ae2347a643a44a65 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 20 Jul 2019 12:54:31 -0400 Subject: Buffer_Cache: Implement flushing. --- src/video_core/buffer_cache/buffer_cache.h | 27 +++++++++++++++++++++- src/video_core/renderer_opengl/gl_buffer_cache.cpp | 4 ++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl') 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); } -- cgit v1.2.3 From 83ec2091c1836bf32e9070d0ddf2a53288871d69 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 10 Aug 2019 12:50:38 -0400 Subject: Buffer Cache: Adress Feedback. --- src/video_core/buffer_cache/buffer_block.h | 7 +++---- src/video_core/renderer_opengl/gl_buffer_cache.h | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/buffer_cache/buffer_block.h b/src/video_core/buffer_cache/buffer_block.h index 2c739a586..d2124443f 100644 --- a/src/video_core/buffer_cache/buffer_block.h +++ b/src/video_core/buffer_cache/buffer_block.h @@ -19,8 +19,8 @@ public: return (cache_addr < end) && (cache_addr_end > start); } - bool IsInside(const CacheAddr other_start, const CacheAddr other_end) { - return (cache_addr <= other_start && other_end <= cache_addr_end); + bool IsInside(const CacheAddr other_start, const CacheAddr other_end) const { + return cache_addr <= other_start && other_end <= cache_addr_end; } u8* GetWritableHostPtr() const { @@ -61,8 +61,7 @@ public: } protected: - explicit BufferBlock(CacheAddr cache_addr,const std::size_t size) - : size{size} { + explicit BufferBlock(CacheAddr cache_addr, const std::size_t size) : size{size} { SetCacheAddr(cache_addr); } ~BufferBlock() = default; diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index fb93f22dd..022e7bfa9 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -54,13 +54,13 @@ protected: const GLuint* ToHandle(const Buffer& buffer) override; void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, - const u8* data) override; + const u8* data) override; void DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, - u8* data) override; + u8* data) override; void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, - std::size_t dst_offset, std::size_t size) override; + std::size_t dst_offset, std::size_t size) override; }; } // namespace OpenGL -- cgit v1.2.3