summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-06-20 03:44:06 -0300
committerGravatar ReinUsesLisp2019-07-06 00:37:55 -0300
commit9cdc576f6055cbb308551f09e3566b34233b226e (patch)
tree7106c6ef615e0771a070afc3180d30cade558e74 /src
parentgl_buffer_cache: Implement with generic buffer cache (diff)
downloadyuzu-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.cpp14
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/utils.cpp31
-rw-r--r--src/video_core/renderer_opengl/utils.h27
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
217GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) { 216GLintptr 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
14namespace OpenGL { 14namespace OpenGL {
15 15
16VertexArrayPushBuffer::VertexArrayPushBuffer() = default;
17
18VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
19
20void VertexArrayPushBuffer::Setup(GLuint vao_) {
21 vao = vao_;
22 index_buffer = nullptr;
23 vertex_buffers.clear();
24}
25
26void VertexArrayPushBuffer::SetIndexBuffer(const GLuint* buffer) {
27 index_buffer = buffer;
28}
29
30void 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
35void 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
16BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {} 47BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
17 48
18BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default; 49BindBuffersRangePushBuffer::~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
12namespace OpenGL { 12namespace OpenGL {
13 13
14class VertexArrayPushBuffer final {
15public:
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
28private:
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
14class BindBuffersRangePushBuffer final { 41class BindBuffersRangePushBuffer final {
15public: 42public:
16 explicit BindBuffersRangePushBuffer(GLenum target); 43 explicit BindBuffersRangePushBuffer(GLenum target);