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

gl_buffer_cache: Return used buffer from Upload function

ReinUsesLisp 7 лет назад
Родитель
Сommit
b54fb8fc4c

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

@@ -4,6 +4,7 @@
 
 
 #include <cstring>
 #include <cstring>
 #include <memory>
 #include <memory>
+#include <utility>
 
 
 #include "common/alignment.h"
 #include "common/alignment.h"
 #include "core/core.h"
 #include "core/core.h"
@@ -21,9 +22,10 @@ CachedBufferEntry::CachedBufferEntry(VAddr cpu_addr, std::size_t size, GLintptr
 OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size)
 OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size)
     : RasterizerCache{rasterizer}, stream_buffer(size, true) {}
     : RasterizerCache{rasterizer}, stream_buffer(size, true) {}
 
 
-GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment,
-                                      bool cache) {
+std::pair<GLuint, GLintptr> OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size,
+                                                         std::size_t alignment, bool cache) {
     std::lock_guard lock{mutex};
     std::lock_guard lock{mutex};
+
     auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
     auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
 
 
     // Cache management is a big overhead, so only cache entries with a given size.
     // Cache management is a big overhead, so only cache entries with a given size.
@@ -35,7 +37,7 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::
         auto entry = TryGet(host_ptr);
         auto entry = TryGet(host_ptr);
         if (entry) {
         if (entry) {
             if (entry->GetSize() >= size && entry->GetAlignment() == alignment) {
             if (entry->GetSize() >= size && entry->GetAlignment() == alignment) {
-                return entry->GetOffset();
+                return {stream_buffer.GetHandle(), entry->GetOffset()};
             }
             }
             Unregister(entry);
             Unregister(entry);
         }
         }
@@ -45,7 +47,7 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::
     const GLintptr uploaded_offset = buffer_offset;
     const GLintptr uploaded_offset = buffer_offset;
 
 
     if (!host_ptr) {
     if (!host_ptr) {
-        return uploaded_offset;
+        return {stream_buffer.GetHandle(), uploaded_offset};
     }
     }
 
 
     std::memcpy(buffer_ptr, host_ptr, size);
     std::memcpy(buffer_ptr, host_ptr, size);
@@ -58,11 +60,12 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::
         Register(entry);
         Register(entry);
     }
     }
 
 
-    return uploaded_offset;
+    return {stream_buffer.GetHandle(), uploaded_offset};
 }
 }
 
 
-GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t size,
-                                          std::size_t alignment) {
+std::pair<GLuint, GLintptr> OGLBufferCache::UploadHostMemory(const void* raw_pointer,
+                                                             std::size_t size,
+                                                             std::size_t alignment) {
     std::lock_guard lock{mutex};
     std::lock_guard lock{mutex};
     AlignBuffer(alignment);
     AlignBuffer(alignment);
     std::memcpy(buffer_ptr, raw_pointer, size);
     std::memcpy(buffer_ptr, raw_pointer, size);
@@ -70,7 +73,7 @@ GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t s
 
 
     buffer_ptr += size;
     buffer_ptr += size;
     buffer_offset += size;
     buffer_offset += size;
-    return uploaded_offset;
+    return {stream_buffer.GetHandle(), uploaded_offset};
 }
 }
 
 
 bool OGLBufferCache::Map(std::size_t max_size) {
 bool OGLBufferCache::Map(std::size_t max_size) {
@@ -89,10 +92,6 @@ void OGLBufferCache::Unmap() {
     stream_buffer.Unmap(buffer_offset - buffer_offset_base);
     stream_buffer.Unmap(buffer_offset - buffer_offset_base);
 }
 }
 
 
-GLuint OGLBufferCache::GetHandle() const {
-    return stream_buffer.GetHandle();
-}
-
 void OGLBufferCache::AlignBuffer(std::size_t alignment) {
 void OGLBufferCache::AlignBuffer(std::size_t alignment) {
     // Align the offset, not the mapped pointer
     // Align the offset, not the mapped pointer
     const GLintptr offset_aligned =
     const GLintptr offset_aligned =

+ 8 - 8
src/video_core/renderer_opengl/gl_buffer_cache.h

@@ -7,6 +7,7 @@
 #include <cstddef>
 #include <cstddef>
 #include <memory>
 #include <memory>
 #include <tuple>
 #include <tuple>
+#include <utility>
 
 
 #include "common/common_types.h"
 #include "common/common_types.h"
 #include "video_core/rasterizer_cache.h"
 #include "video_core/rasterizer_cache.h"
@@ -53,19 +54,18 @@ class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBuffer
 public:
 public:
     explicit OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size);
     explicit OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size);
 
 
-    /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been
-    /// allocated.
-    GLintptr UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4,
-                          bool cache = true);
+    /// Uploads data from a guest GPU address. Returns the OpenGL buffer where it's located and its
+    /// offset.
+    std::pair<GLuint, GLintptr> UploadMemory(GPUVAddr gpu_addr, std::size_t size,
+                                             std::size_t alignment = 4, bool cache = true);
 
 
-    /// Uploads from a host memory. Returns host's buffer offset where it's been allocated.
-    GLintptr UploadHostMemory(const void* raw_pointer, std::size_t size, std::size_t alignment = 4);
+    /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
+    std::pair<GLuint, GLintptr> UploadHostMemory(const void* raw_pointer, std::size_t size,
+                                                 std::size_t alignment = 4);
 
 
     bool Map(std::size_t max_size);
     bool Map(std::size_t max_size);
     void Unmap();
     void Unmap();
 
 
-    GLuint GetHandle() const;
-
 protected:
 protected:
     void AlignBuffer(std::size_t alignment);
     void AlignBuffer(std::size_t alignment);
 
 

+ 15 - 15
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -129,8 +129,6 @@ GLuint RasterizerOpenGL::SetupVertexFormat() {
         state.draw.vertex_array = vao;
         state.draw.vertex_array = vao;
         state.ApplyVertexArrayState();
         state.ApplyVertexArrayState();
 
 
-        glVertexArrayElementBuffer(vao, buffer_cache.GetHandle());
-
         // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
         // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
         // Enables the first 16 vertex attributes always, as we don't know which ones are actually
         // Enables the first 16 vertex attributes always, as we don't know which ones are actually
         // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
         // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
@@ -197,10 +195,10 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
 
 
         ASSERT(end > start);
         ASSERT(end > start);
         const u64 size = end - start + 1;
         const u64 size = end - start + 1;
-        const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size);
+        const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
 
 
         // Bind the vertex array to the buffer at the current offset.
         // Bind the vertex array to the buffer at the current offset.
-        glVertexArrayVertexBuffer(vao, index, buffer_cache.GetHandle(), vertex_buffer_offset,
+        glVertexArrayVertexBuffer(vao, index, vertex_buffer, vertex_buffer_offset,
                                   vertex_array.stride);
                                   vertex_array.stride);
 
 
         if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
         if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
@@ -215,12 +213,16 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
     gpu.dirty_flags.vertex_array.reset();
     gpu.dirty_flags.vertex_array.reset();
 }
 }
 
 
-GLintptr RasterizerOpenGL::SetupIndexBuffer() {
+GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) {
     if (accelerate_draw != AccelDraw::Indexed) {
     if (accelerate_draw != AccelDraw::Indexed) {
         return 0;
         return 0;
     }
     }
+    MICROPROFILE_SCOPE(OpenGL_Index);
     const auto& regs = system.GPU().Maxwell3D().regs;
     const auto& regs = system.GPU().Maxwell3D().regs;
-    return buffer_cache.UploadMemory(regs.index_array.IndexStart(), CalculateIndexBufferSize());
+    const std::size_t size = CalculateIndexBufferSize();
+    const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
+    glVertexArrayElementBuffer(vao, buffer);
+    return offset;
 }
 }
 
 
 DrawParameters RasterizerOpenGL::SetupDraw(GLintptr index_buffer_offset) {
 DrawParameters RasterizerOpenGL::SetupDraw(GLintptr index_buffer_offset) {
@@ -235,7 +237,6 @@ DrawParameters RasterizerOpenGL::SetupDraw(GLintptr index_buffer_offset) {
     params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
     params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
 
 
     if (is_indexed) {
     if (is_indexed) {
-        MICROPROFILE_SCOPE(OpenGL_Index);
         params.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
         params.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
         params.count = regs.index_array.count;
         params.count = regs.index_array.count;
         params.index_buffer_offset = index_buffer_offset;
         params.index_buffer_offset = index_buffer_offset;
@@ -278,12 +279,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
 
 
         GLShader::MaxwellUniformData ubo{};
         GLShader::MaxwellUniformData ubo{};
         ubo.SetFromRegs(gpu, stage);
         ubo.SetFromRegs(gpu, stage);
-        const GLintptr offset =
+        const auto [buffer, offset] =
             buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
             buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
 
 
         // Bind the emulation info buffer
         // Bind the emulation info buffer
-        bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset,
-                                 static_cast<GLsizeiptr>(sizeof(ubo)));
+        bind_ubo_pushbuffer.Push(buffer, offset, static_cast<GLsizeiptr>(sizeof(ubo)));
 
 
         Shader shader{shader_cache.GetStageProgram(program)};
         Shader shader{shader_cache.GetStageProgram(program)};
 
 
@@ -651,11 +651,11 @@ void RasterizerOpenGL::DrawArrays() {
     }
     }
 
 
     // Prepare vertex array format.
     // Prepare vertex array format.
-    const GLuint vertex_array = SetupVertexFormat();
+    const GLuint vao = SetupVertexFormat();
 
 
     // Upload vertex and index data.
     // Upload vertex and index data.
-    SetupVertexBuffer(vertex_array);
-    const GLintptr index_buffer_offset = SetupIndexBuffer();
+    SetupVertexBuffer(vao);
+    const GLintptr index_buffer_offset = SetupIndexBuffer(vao);
 
 
     // Setup draw parameters. It will automatically choose what glDraw* method to use.
     // Setup draw parameters. It will automatically choose what glDraw* method to use.
     const DrawParameters params = SetupDraw(index_buffer_offset);
     const DrawParameters params = SetupDraw(index_buffer_offset);
@@ -791,8 +791,8 @@ void RasterizerOpenGL::SetupConstBuffer(const Tegra::Engines::ConstBufferInfo& b
     ASSERT_MSG(size <= MaxConstbufferSize, "Constant buffer is too big");
     ASSERT_MSG(size <= MaxConstbufferSize, "Constant buffer is too big");
 
 
     const std::size_t alignment = device.GetUniformBufferAlignment();
     const std::size_t alignment = device.GetUniformBufferAlignment();
-    const GLintptr offset = buffer_cache.UploadMemory(buffer.address, size, alignment);
-    bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset, size);
+    const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment);
+    bind_ubo_pushbuffer.Push(cbuf, offset, size);
 }
 }
 
 
 void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
 void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,

+ 1 - 1
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -220,7 +220,7 @@ private:
 
 
     void SetupVertexBuffer(GLuint vao);
     void SetupVertexBuffer(GLuint vao);
 
 
-    GLintptr SetupIndexBuffer();
+    GLintptr SetupIndexBuffer(GLuint vao);
 
 
     DrawParameters SetupDraw(GLintptr index_buffer_offset);
     DrawParameters SetupDraw(GLintptr index_buffer_offset);