diff options
| author | 2019-06-20 03:44:06 -0300 | |
|---|---|---|
| committer | 2019-07-06 00:37:55 -0300 | |
| commit | 9cdc576f6055cbb308551f09e3566b34233b226e (patch) | |
| tree | 7106c6ef615e0771a070afc3180d30cade558e74 /src | |
| parent | gl_buffer_cache: Implement with generic buffer cache (diff) | |
| download | yuzu-9cdc576f6055cbb308551f09e3566b34233b226e.tar.gz yuzu-9cdc576f6055cbb308551f09e3566b34233b226e.tar.xz yuzu-9cdc576f6055cbb308551f09e3566b34233b226e.zip | |
gl_rasterizer: Fix vertex and index data invalidations
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/utils.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/utils.h | 27 |
4 files changed, 67 insertions, 8 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b57d60856..f3527d65b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -198,9 +198,8 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | |||
| 198 | const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); | 198 | const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); |
| 199 | 199 | ||
| 200 | // Bind the vertex array to the buffer at the current offset. | 200 | // Bind the vertex array to the buffer at the current offset. |
| 201 | // FIXME(Rodrigo): This dereferenced pointer might be invalidated in future uploads. | 201 | vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset, |
| 202 | glVertexArrayVertexBuffer(vao, index, *vertex_buffer, vertex_buffer_offset, | 202 | vertex_array.stride); |
| 203 | vertex_array.stride); | ||
| 204 | 203 | ||
| 205 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { | 204 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { |
| 206 | // Enable vertex buffer instancing with the specified divisor. | 205 | // Enable vertex buffer instancing with the specified divisor. |
| @@ -214,7 +213,7 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | |||
| 214 | gpu.dirty_flags.vertex_array.reset(); | 213 | gpu.dirty_flags.vertex_array.reset(); |
| 215 | } | 214 | } |
| 216 | 215 | ||
| 217 | GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) { | 216 | GLintptr RasterizerOpenGL::SetupIndexBuffer() { |
| 218 | if (accelerate_draw != AccelDraw::Indexed) { | 217 | if (accelerate_draw != AccelDraw::Indexed) { |
| 219 | return 0; | 218 | return 0; |
| 220 | } | 219 | } |
| @@ -222,8 +221,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) { | |||
| 222 | const auto& regs = system.GPU().Maxwell3D().regs; | 221 | const auto& regs = system.GPU().Maxwell3D().regs; |
| 223 | const std::size_t size = CalculateIndexBufferSize(); | 222 | const std::size_t size = CalculateIndexBufferSize(); |
| 224 | const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); | 223 | const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); |
| 225 | // FIXME(Rodrigo): This dereferenced pointer might be invalidated in future uploads. | 224 | vertex_array_pushbuffer.SetIndexBuffer(buffer); |
| 226 | glVertexArrayElementBuffer(vao, *buffer); | ||
| 227 | return offset; | 225 | return offset; |
| 228 | } | 226 | } |
| 229 | 227 | ||
| @@ -644,10 +642,11 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 644 | 642 | ||
| 645 | // Prepare vertex array format. | 643 | // Prepare vertex array format. |
| 646 | const GLuint vao = SetupVertexFormat(); | 644 | const GLuint vao = SetupVertexFormat(); |
| 645 | vertex_array_pushbuffer.Setup(vao); | ||
| 647 | 646 | ||
| 648 | // Upload vertex and index data. | 647 | // Upload vertex and index data. |
| 649 | SetupVertexBuffer(vao); | 648 | SetupVertexBuffer(vao); |
| 650 | const GLintptr index_buffer_offset = SetupIndexBuffer(vao); | 649 | const GLintptr index_buffer_offset = SetupIndexBuffer(); |
| 651 | 650 | ||
| 652 | // Setup draw parameters. It will automatically choose what glDraw* method to use. | 651 | // Setup draw parameters. It will automatically choose what glDraw* method to use. |
| 653 | const DrawParameters params = SetupDraw(index_buffer_offset); | 652 | const DrawParameters params = SetupDraw(index_buffer_offset); |
| @@ -667,6 +666,7 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 667 | const bool invalidate = buffer_cache.Unmap(); | 666 | const bool invalidate = buffer_cache.Unmap(); |
| 668 | 667 | ||
| 669 | // Now that we are no longer uploading data, we can safely bind the buffers to OpenGL. | 668 | // Now that we are no longer uploading data, we can safely bind the buffers to OpenGL. |
| 669 | vertex_array_pushbuffer.Bind(); | ||
| 670 | bind_ubo_pushbuffer.Bind(); | 670 | bind_ubo_pushbuffer.Bind(); |
| 671 | bind_ssbo_pushbuffer.Bind(); | 671 | bind_ssbo_pushbuffer.Bind(); |
| 672 | 672 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 7067ad5b4..1c915fd7f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -207,6 +207,7 @@ private: | |||
| 207 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | 207 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; |
| 208 | OGLBufferCache buffer_cache; | 208 | OGLBufferCache buffer_cache; |
| 209 | 209 | ||
| 210 | VertexArrayPushBuffer vertex_array_pushbuffer; | ||
| 210 | BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; | 211 | BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; |
| 211 | BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; | 212 | BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; |
| 212 | 213 | ||
| @@ -219,7 +220,7 @@ private: | |||
| 219 | 220 | ||
| 220 | void SetupVertexBuffer(GLuint vao); | 221 | void SetupVertexBuffer(GLuint vao); |
| 221 | 222 | ||
| 222 | GLintptr SetupIndexBuffer(GLuint vao); | 223 | GLintptr SetupIndexBuffer(); |
| 223 | 224 | ||
| 224 | DrawParameters SetupDraw(GLintptr index_buffer_offset); | 225 | DrawParameters SetupDraw(GLintptr index_buffer_offset); |
| 225 | 226 | ||
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp index 22eefa1d7..c504a2c1a 100644 --- a/src/video_core/renderer_opengl/utils.cpp +++ b/src/video_core/renderer_opengl/utils.cpp | |||
| @@ -13,6 +13,37 @@ | |||
| 13 | 13 | ||
| 14 | namespace OpenGL { | 14 | namespace OpenGL { |
| 15 | 15 | ||
| 16 | VertexArrayPushBuffer::VertexArrayPushBuffer() = default; | ||
| 17 | |||
| 18 | VertexArrayPushBuffer::~VertexArrayPushBuffer() = default; | ||
| 19 | |||
| 20 | void VertexArrayPushBuffer::Setup(GLuint vao_) { | ||
| 21 | vao = vao_; | ||
| 22 | index_buffer = nullptr; | ||
| 23 | vertex_buffers.clear(); | ||
| 24 | } | ||
| 25 | |||
| 26 | void VertexArrayPushBuffer::SetIndexBuffer(const GLuint* buffer) { | ||
| 27 | index_buffer = buffer; | ||
| 28 | } | ||
| 29 | |||
| 30 | void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint* buffer, | ||
| 31 | GLintptr offset, GLsizei stride) { | ||
| 32 | vertex_buffers.push_back(Entry{binding_index, buffer, offset, stride}); | ||
| 33 | } | ||
| 34 | |||
| 35 | void VertexArrayPushBuffer::Bind() { | ||
| 36 | if (index_buffer) { | ||
| 37 | glVertexArrayElementBuffer(vao, *index_buffer); | ||
| 38 | } | ||
| 39 | |||
| 40 | // TODO(Rodrigo): Find a way to ARB_multi_bind this | ||
| 41 | for (const auto& entry : vertex_buffers) { | ||
| 42 | glVertexArrayVertexBuffer(vao, entry.binding_index, *entry.buffer, entry.offset, | ||
| 43 | entry.stride); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 16 | BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {} | 47 | BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {} |
| 17 | 48 | ||
| 18 | BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default; | 49 | BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default; |
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h index d2a3d25d9..6c2b45546 100644 --- a/src/video_core/renderer_opengl/utils.h +++ b/src/video_core/renderer_opengl/utils.h | |||
| @@ -11,6 +11,33 @@ | |||
| 11 | 11 | ||
| 12 | namespace OpenGL { | 12 | namespace OpenGL { |
| 13 | 13 | ||
| 14 | class VertexArrayPushBuffer final { | ||
| 15 | public: | ||
| 16 | explicit VertexArrayPushBuffer(); | ||
| 17 | ~VertexArrayPushBuffer(); | ||
| 18 | |||
| 19 | void Setup(GLuint vao_); | ||
| 20 | |||
| 21 | void SetIndexBuffer(const GLuint* buffer); | ||
| 22 | |||
| 23 | void SetVertexBuffer(GLuint binding_index, const GLuint* buffer, GLintptr offset, | ||
| 24 | GLsizei stride); | ||
| 25 | |||
| 26 | void Bind(); | ||
| 27 | |||
| 28 | private: | ||
| 29 | struct Entry { | ||
| 30 | GLuint binding_index{}; | ||
| 31 | const GLuint* buffer{}; | ||
| 32 | GLintptr offset{}; | ||
| 33 | GLsizei stride{}; | ||
| 34 | }; | ||
| 35 | |||
| 36 | GLuint vao{}; | ||
| 37 | const GLuint* index_buffer{}; | ||
| 38 | std::vector<Entry> vertex_buffers; | ||
| 39 | }; | ||
| 40 | |||
| 14 | class BindBuffersRangePushBuffer final { | 41 | class BindBuffersRangePushBuffer final { |
| 15 | public: | 42 | public: |
| 16 | explicit BindBuffersRangePushBuffer(GLenum target); | 43 | explicit BindBuffersRangePushBuffer(GLenum target); |