gl_buffer_cache: Return used buffer from Upload function
This commit is contained in:
		| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| #include <cstring> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
|  | ||||
| #include "common/alignment.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) | ||||
|     : 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}; | ||||
|  | ||||
|     auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); | ||||
|  | ||||
|     // 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); | ||||
|         if (entry) { | ||||
|             if (entry->GetSize() >= size && entry->GetAlignment() == alignment) { | ||||
|                 return entry->GetOffset(); | ||||
|                 return {stream_buffer.GetHandle(), entry->GetOffset()}; | ||||
|             } | ||||
|             Unregister(entry); | ||||
|         } | ||||
| @@ -45,7 +47,7 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std:: | ||||
|     const GLintptr uploaded_offset = buffer_offset; | ||||
|  | ||||
|     if (!host_ptr) { | ||||
|         return uploaded_offset; | ||||
|         return {stream_buffer.GetHandle(), uploaded_offset}; | ||||
|     } | ||||
|  | ||||
|     std::memcpy(buffer_ptr, host_ptr, size); | ||||
| @@ -58,11 +60,12 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std:: | ||||
|         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}; | ||||
|     AlignBuffer(alignment); | ||||
|     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_offset += size; | ||||
|     return uploaded_offset; | ||||
|     return {stream_buffer.GetHandle(), uploaded_offset}; | ||||
| } | ||||
|  | ||||
| bool OGLBufferCache::Map(std::size_t max_size) { | ||||
| @@ -89,10 +92,6 @@ void OGLBufferCache::Unmap() { | ||||
|     stream_buffer.Unmap(buffer_offset - buffer_offset_base); | ||||
| } | ||||
|  | ||||
| GLuint OGLBufferCache::GetHandle() const { | ||||
|     return stream_buffer.GetHandle(); | ||||
| } | ||||
|  | ||||
| void OGLBufferCache::AlignBuffer(std::size_t alignment) { | ||||
|     // Align the offset, not the mapped pointer | ||||
|     const GLintptr offset_aligned = | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include <cstddef> | ||||
| #include <memory> | ||||
| #include <tuple> | ||||
| #include <utility> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "video_core/rasterizer_cache.h" | ||||
| @@ -53,19 +54,18 @@ class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBuffer | ||||
| public: | ||||
|     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); | ||||
|     void Unmap(); | ||||
|  | ||||
|     GLuint GetHandle() const; | ||||
|  | ||||
| protected: | ||||
|     void AlignBuffer(std::size_t alignment); | ||||
|  | ||||
|   | ||||
| @@ -129,8 +129,6 @@ GLuint RasterizerOpenGL::SetupVertexFormat() { | ||||
|         state.draw.vertex_array = vao; | ||||
|         state.ApplyVertexArrayState(); | ||||
|  | ||||
|         glVertexArrayElementBuffer(vao, buffer_cache.GetHandle()); | ||||
|  | ||||
|         // 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 | ||||
|         // 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); | ||||
|         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. | ||||
|         glVertexArrayVertexBuffer(vao, index, buffer_cache.GetHandle(), vertex_buffer_offset, | ||||
|         glVertexArrayVertexBuffer(vao, index, vertex_buffer, vertex_buffer_offset, | ||||
|                                   vertex_array.stride); | ||||
|  | ||||
|         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(); | ||||
| } | ||||
|  | ||||
| GLintptr RasterizerOpenGL::SetupIndexBuffer() { | ||||
| GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) { | ||||
|     if (accelerate_draw != AccelDraw::Indexed) { | ||||
|         return 0; | ||||
|     } | ||||
|     MICROPROFILE_SCOPE(OpenGL_Index); | ||||
|     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) { | ||||
| @@ -235,7 +237,6 @@ DrawParameters RasterizerOpenGL::SetupDraw(GLintptr index_buffer_offset) { | ||||
|     params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); | ||||
|  | ||||
|     if (is_indexed) { | ||||
|         MICROPROFILE_SCOPE(OpenGL_Index); | ||||
|         params.index_format = MaxwellToGL::IndexFormat(regs.index_array.format); | ||||
|         params.count = regs.index_array.count; | ||||
|         params.index_buffer_offset = index_buffer_offset; | ||||
| @@ -278,12 +279,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | ||||
|  | ||||
|         GLShader::MaxwellUniformData ubo{}; | ||||
|         ubo.SetFromRegs(gpu, stage); | ||||
|         const GLintptr offset = | ||||
|         const auto [buffer, offset] = | ||||
|             buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); | ||||
|  | ||||
|         // 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)}; | ||||
|  | ||||
| @@ -651,11 +651,11 @@ void RasterizerOpenGL::DrawArrays() { | ||||
|     } | ||||
|  | ||||
|     // Prepare vertex array format. | ||||
|     const GLuint vertex_array = SetupVertexFormat(); | ||||
|     const GLuint vao = SetupVertexFormat(); | ||||
|  | ||||
|     // 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. | ||||
|     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"); | ||||
|  | ||||
|     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, | ||||
|   | ||||
| @@ -220,7 +220,7 @@ private: | ||||
|  | ||||
|     void SetupVertexBuffer(GLuint vao); | ||||
|  | ||||
|     GLintptr SetupIndexBuffer(); | ||||
|     GLintptr SetupIndexBuffer(GLuint vao); | ||||
|  | ||||
|     DrawParameters SetupDraw(GLintptr index_buffer_offset); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp