Просмотр исходного кода

Merge pull request #4175 from ReinUsesLisp/read-buffer

gl_buffer_cache: Copy to buffers created as STREAM_READ before downloading
bunnei 6 лет назад
Родитель
Сommit
41a333321a

+ 2 - 4
src/video_core/buffer_cache/buffer_cache.h

@@ -322,8 +322,7 @@ protected:
     }
 
 private:
-    MapInterval* MapAddress(const Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr,
-                            std::size_t size) {
+    MapInterval* MapAddress(Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size) {
         const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size);
         if (overlaps.empty()) {
             auto& memory_manager = system.GPU().MemoryManager();
@@ -377,8 +376,7 @@ private:
         return map;
     }
 
-    void UpdateBlock(const Buffer* block, VAddr start, VAddr end,
-                     const VectorMapInterval& overlaps) {
+    void UpdateBlock(Buffer* block, VAddr start, VAddr end, const VectorMapInterval& overlaps) {
         const IntervalType base_interval{start, end};
         IntervalSet interval_set{};
         interval_set.add(base_interval);

+ 12 - 5
src/video_core/renderer_opengl/gl_buffer_cache.cpp

@@ -34,20 +34,27 @@ Buffer::Buffer(const Device& device, VAddr cpu_addr, std::size_t size)
 
 Buffer::~Buffer() = default;
 
-void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const {
+void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) {
     glNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size),
                          data);
 }
 
-void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const {
+void Buffer::Download(std::size_t offset, std::size_t size, u8* data) {
     MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
+    const GLsizeiptr gl_size = static_cast<GLsizeiptr>(size);
+    const GLintptr gl_offset = static_cast<GLintptr>(offset);
+    if (read_buffer.handle == 0) {
+        read_buffer.Create();
+        glNamedBufferData(read_buffer.handle, static_cast<GLsizeiptr>(Size()), nullptr,
+                          GL_STREAM_READ);
+    }
     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
-    glGetNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size),
-                            data);
+    glCopyNamedBufferSubData(gl_buffer.handle, read_buffer.handle, gl_offset, gl_offset, gl_size);
+    glGetNamedBufferSubData(read_buffer.handle, gl_offset, gl_size, data);
 }
 
 void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
-                      std::size_t size) const {
+                      std::size_t size) {
     glCopyNamedBufferSubData(src.Handle(), Handle(), static_cast<GLintptr>(src_offset),
                              static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
 }

+ 4 - 3
src/video_core/renderer_opengl/gl_buffer_cache.h

@@ -28,12 +28,12 @@ public:
     explicit Buffer(const Device& device, VAddr cpu_addr, std::size_t size);
     ~Buffer();
 
-    void Upload(std::size_t offset, std::size_t size, const u8* data) const;
+    void Upload(std::size_t offset, std::size_t size, const u8* data);
 
-    void Download(std::size_t offset, std::size_t size, u8* data) const;
+    void Download(std::size_t offset, std::size_t size, u8* data);
 
     void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
-                  std::size_t size) const;
+                  std::size_t size);
 
     GLuint Handle() const noexcept {
         return gl_buffer.handle;
@@ -45,6 +45,7 @@ public:
 
 private:
     OGLBuffer gl_buffer;
+    OGLBuffer read_buffer;
     u64 gpu_address = 0;
 };
 

+ 3 - 3
src/video_core/renderer_vulkan/vk_buffer_cache.cpp

@@ -56,7 +56,7 @@ Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VKSchedu
 
 Buffer::~Buffer() = default;
 
-void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const {
+void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) {
     const auto& staging = staging_pool.GetUnusedBuffer(size, true);
     std::memcpy(staging.commit->Map(size), data, size);
 
@@ -81,7 +81,7 @@ void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const
     });
 }
 
-void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const {
+void Buffer::Download(std::size_t offset, std::size_t size, u8* data) {
     const auto& staging = staging_pool.GetUnusedBuffer(size, true);
     scheduler.RequestOutsideRenderPassOperationContext();
 
@@ -110,7 +110,7 @@ void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const {
 }
 
 void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
-                      std::size_t size) const {
+                      std::size_t size) {
     scheduler.RequestOutsideRenderPassOperationContext();
 
     const VkBuffer dst_buffer = Handle();

+ 3 - 3
src/video_core/renderer_vulkan/vk_buffer_cache.h

@@ -29,12 +29,12 @@ public:
                     VKStagingBufferPool& staging_pool, VAddr cpu_addr, std::size_t size);
     ~Buffer();
 
-    void Upload(std::size_t offset, std::size_t size, const u8* data) const;
+    void Upload(std::size_t offset, std::size_t size, const u8* data);
 
-    void Download(std::size_t offset, std::size_t size, u8* data) const;
+    void Download(std::size_t offset, std::size_t size, u8* data);
 
     void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset,
-                  std::size_t size) const;
+                  std::size_t size);
 
     VkBuffer Handle() const {
         return *buffer.handle;