diff options
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 23 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 16 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 30 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 2 |
4 files changed, 35 insertions, 36 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index 2b9bd142e..ea8b4c99f 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -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 = diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index f2347581b..544f3b010 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -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); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index bfc3c4df9..d694dacfb 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -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, diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 8f1757e25..a03bc759f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -220,7 +220,7 @@ private: void SetupVertexBuffer(GLuint vao); - GLintptr SetupIndexBuffer(); + GLintptr SetupIndexBuffer(GLuint vao); DrawParameters SetupDraw(GLintptr index_buffer_offset); |