summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp100
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h12
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h25
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp14
-rw-r--r--src/video_core/renderer_opengl/gl_state.h3
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp22
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h1
-rw-r--r--src/video_core/renderer_opengl/utils.cpp8
-rw-r--r--src/video_core/renderer_opengl/utils.h3
10 files changed, 53 insertions, 153 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index acdae849c..9658d379c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -107,7 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
107 state.draw.shader_program = 0; 107 state.draw.shader_program = 0;
108 state.Apply(); 108 state.Apply();
109 109
110 LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
111 CheckExtensions(); 110 CheckExtensions();
112} 111}
113 112
@@ -121,66 +120,41 @@ void RasterizerOpenGL::CheckExtensions() {
121 } 120 }
122} 121}
123 122
124GLuint RasterizerOpenGL::SetupVertexFormat() { 123void RasterizerOpenGL::SetupVertexFormat() {
125 auto& gpu = system.GPU().Maxwell3D(); 124 auto& gpu = system.GPU().Maxwell3D();
126 const auto& regs = gpu.regs; 125 const auto& regs = gpu.regs;
127 126
128 MICROPROFILE_SCOPE(OpenGL_VAO); 127 MICROPROFILE_SCOPE(OpenGL_VAO);
129 128
130 auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); 129 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. Enables
131 auto& vao_entry = iter->second; 130 // the first 16 vertex attributes always, as we don't know which ones are actually used until
132 131 // shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now to
133 if (is_cache_miss) { 132 // avoid OpenGL errors.
134 vao_entry.Create(); 133 // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
135 const GLuint vao = vao_entry.handle; 134 // assume every shader uses them all.
136 135 for (u32 index = 0; index < 16; ++index) {
137 // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob 136 const auto& attrib = regs.vertex_attrib_format[index];
138 // that fails to properly create the vertex array if it's not bound even after creating it 137
139 // with glCreateVertexArrays 138 // Ignore invalid attributes.
140 state.draw.vertex_array = vao; 139 if (!attrib.IsValid()) {
141 state.ApplyVertexArrayState(); 140 glDisableVertexAttribArray(index);
142 141 continue;
143 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
144 // Enables the first 16 vertex attributes always, as we don't know which ones are actually
145 // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
146 // for now to avoid OpenGL errors.
147 // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
148 // assume every shader uses them all.
149 for (u32 index = 0; index < 16; ++index) {
150 const auto& attrib = regs.vertex_attrib_format[index];
151
152 // Ignore invalid attributes.
153 if (!attrib.IsValid())
154 continue;
155
156 const auto& buffer = regs.vertex_array[attrib.buffer];
157 LOG_TRACE(Render_OpenGL,
158 "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
159 index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
160 attrib.offset.Value(), attrib.IsNormalized());
161
162 ASSERT(buffer.IsEnabled());
163
164 glEnableVertexArrayAttrib(vao, index);
165 if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
166 attrib.type ==
167 Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
168 glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
169 MaxwellToGL::VertexType(attrib), attrib.offset);
170 } else {
171 glVertexArrayAttribFormat(
172 vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
173 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
174 }
175 glVertexArrayAttribBinding(vao, index, attrib.buffer);
176 } 142 }
177 } 143 glEnableVertexAttribArray(index);
178 144
179 state.draw.vertex_array = vao_entry.handle; 145 if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
180 return vao_entry.handle; 146 attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
147 glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
148 attrib.offset);
149 } else {
150 glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
151 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
152 }
153 glVertexAttribBinding(index, attrib.buffer);
154 }
181} 155}
182 156
183void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { 157void RasterizerOpenGL::SetupVertexBuffer() {
184 auto& gpu = system.GPU().Maxwell3D(); 158 auto& gpu = system.GPU().Maxwell3D();
185 const auto& regs = gpu.regs; 159 const auto& regs = gpu.regs;
186 160
@@ -189,8 +163,9 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
189 // Upload all guest vertex arrays sequentially to our buffer 163 // Upload all guest vertex arrays sequentially to our buffer
190 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { 164 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
191 const auto& vertex_array = regs.vertex_array[index]; 165 const auto& vertex_array = regs.vertex_array[index];
192 if (!vertex_array.IsEnabled()) 166 if (!vertex_array.IsEnabled()) {
193 continue; 167 continue;
168 }
194 169
195 const GPUVAddr start = vertex_array.StartAddress(); 170 const GPUVAddr start = vertex_array.StartAddress();
196 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 171 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
@@ -205,15 +180,15 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
205 180
206 if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { 181 if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
207 // Enable vertex buffer instancing with the specified divisor. 182 // Enable vertex buffer instancing with the specified divisor.
208 glVertexArrayBindingDivisor(vao, index, vertex_array.divisor); 183 glVertexBindingDivisor(index, vertex_array.divisor);
209 } else { 184 } else {
210 // Disable the vertex buffer instancing. 185 // Disable the vertex buffer instancing.
211 glVertexArrayBindingDivisor(vao, index, 0); 186 glVertexBindingDivisor(index, 0);
212 } 187 }
213 } 188 }
214} 189}
215 190
216void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { 191void RasterizerOpenGL::SetupVertexInstances() {
217 auto& gpu = system.GPU().Maxwell3D(); 192 auto& gpu = system.GPU().Maxwell3D();
218 const auto& regs = gpu.regs; 193 const auto& regs = gpu.regs;
219 194
@@ -222,10 +197,10 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
222 if (regs.instanced_arrays.IsInstancingEnabled(index) && 197 if (regs.instanced_arrays.IsInstancingEnabled(index) &&
223 regs.vertex_array[index].divisor != 0) { 198 regs.vertex_array[index].divisor != 0) {
224 // Enable vertex buffer instancing with the specified divisor. 199 // Enable vertex buffer instancing with the specified divisor.
225 glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor); 200 glVertexBindingDivisor(index, regs.vertex_array[index].divisor);
226 } else { 201 } else {
227 // Disable the vertex buffer instancing. 202 // Disable the vertex buffer instancing.
228 glVertexArrayBindingDivisor(vao, index, 0); 203 glVertexBindingDivisor(index, 0);
229 } 204 }
230 } 205 }
231} 206}
@@ -559,13 +534,12 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
559 buffer_cache.Map(buffer_size); 534 buffer_cache.Map(buffer_size);
560 535
561 // Prepare vertex array format. 536 // Prepare vertex array format.
562 const GLuint vao = SetupVertexFormat(); 537 SetupVertexFormat();
563 vertex_array_pushbuffer.Setup(vao); 538 vertex_array_pushbuffer.Setup();
564 539
565 // Upload vertex and index data. 540 // Upload vertex and index data.
566 SetupVertexBuffer(vao); 541 SetupVertexBuffer();
567 SetupVertexInstances(vao); 542 SetupVertexInstances();
568
569 GLintptr index_buffer_offset; 543 GLintptr index_buffer_offset;
570 if (is_indexed) { 544 if (is_indexed) {
571 index_buffer_offset = SetupIndexBuffer(); 545 index_buffer_offset = SetupIndexBuffer();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 8afc3c205..b97f9f518 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -194,11 +194,11 @@ private:
194 194
195 std::size_t CalculateIndexBufferSize() const; 195 std::size_t CalculateIndexBufferSize() const;
196 196
197 /// Updates and returns a vertex array object representing current vertex format 197 /// Updates the current vertex format
198 GLuint SetupVertexFormat(); 198 void SetupVertexFormat();
199 199
200 void SetupVertexBuffer(GLuint vao); 200 void SetupVertexBuffer();
201 void SetupVertexInstances(GLuint vao); 201 void SetupVertexInstances();
202 202
203 GLintptr SetupIndexBuffer(); 203 GLintptr SetupIndexBuffer();
204 204
@@ -217,10 +217,6 @@ private:
217 ScreenInfo& screen_info; 217 ScreenInfo& screen_info;
218 218
219 std::unique_ptr<GLShader::ProgramManager> shader_program_manager; 219 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
220 std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute,
221 Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>,
222 OGLVertexArray>
223 vertex_array_cache;
224 220
225 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 221 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
226 OGLBufferCache buffer_cache; 222 OGLBufferCache buffer_cache;
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index c0aee770f..00355c1da 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -189,24 +189,6 @@ void OGLSync::Release() {
189 handle = 0; 189 handle = 0;
190} 190}
191 191
192void OGLVertexArray::Create() {
193 if (handle != 0)
194 return;
195
196 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
197 glCreateVertexArrays(1, &handle);
198}
199
200void OGLVertexArray::Release() {
201 if (handle == 0)
202 return;
203
204 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
205 glDeleteVertexArrays(1, &handle);
206 OpenGLState::GetCurState().ResetVertexArray(handle).Apply();
207 handle = 0;
208}
209
210void OGLFramebuffer::Create() { 192void OGLFramebuffer::Create() {
211 if (handle != 0) 193 if (handle != 0)
212 return; 194 return;
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index 995a4e45e..de93f4212 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.h
+++ b/src/video_core/renderer_opengl/gl_resource_manager.h
@@ -241,31 +241,6 @@ public:
241 GLsync handle = 0; 241 GLsync handle = 0;
242}; 242};
243 243
244class OGLVertexArray : private NonCopyable {
245public:
246 OGLVertexArray() = default;
247
248 OGLVertexArray(OGLVertexArray&& o) noexcept : handle(std::exchange(o.handle, 0)) {}
249
250 ~OGLVertexArray() {
251 Release();
252 }
253
254 OGLVertexArray& operator=(OGLVertexArray&& o) noexcept {
255 Release();
256 handle = std::exchange(o.handle, 0);
257 return *this;
258 }
259
260 /// Creates a new internal OpenGL resource and stores the handle
261 void Create();
262
263 /// Deletes the internal OpenGL resource
264 void Release();
265
266 GLuint handle = 0;
267};
268
269class OGLFramebuffer : private NonCopyable { 244class OGLFramebuffer : private NonCopyable {
270public: 245public:
271 OGLFramebuffer() = default; 246 OGLFramebuffer() = default;
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 6b5eea342..1c39e7fba 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -98,12 +98,6 @@ void OpenGLState::ApplyFramebufferState() {
98 } 98 }
99} 99}
100 100
101void OpenGLState::ApplyVertexArrayState() {
102 if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) {
103 glBindVertexArray(draw.vertex_array);
104 }
105}
106
107void OpenGLState::ApplyShaderProgram() { 101void OpenGLState::ApplyShaderProgram() {
108 if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { 102 if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
109 glUseProgram(draw.shader_program); 103 glUseProgram(draw.shader_program);
@@ -338,7 +332,6 @@ void OpenGLState::ApplyImages() {
338void OpenGLState::Apply() { 332void OpenGLState::Apply() {
339 MICROPROFILE_SCOPE(OpenGL_State); 333 MICROPROFILE_SCOPE(OpenGL_State);
340 ApplyFramebufferState(); 334 ApplyFramebufferState();
341 ApplyVertexArrayState();
342 ApplyShaderProgram(); 335 ApplyShaderProgram();
343 ApplyProgramPipeline(); 336 ApplyProgramPipeline();
344 ApplyClipDistances(); 337 ApplyClipDistances();
@@ -411,13 +404,6 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
411 return *this; 404 return *this;
412} 405}
413 406
414OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) {
415 if (draw.vertex_array == handle) {
416 draw.vertex_array = 0;
417 }
418 return *this;
419}
420
421OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) { 407OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) {
422 if (draw.read_framebuffer == handle) { 408 if (draw.read_framebuffer == handle) {
423 draw.read_framebuffer = 0; 409 draw.read_framebuffer = 0;
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 366753714..f7c722b36 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -74,7 +74,6 @@ public:
74 struct { 74 struct {
75 GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING 75 GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
76 GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING 76 GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
77 GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING
78 GLuint shader_program = 0; // GL_CURRENT_PROGRAM 77 GLuint shader_program = 0; // GL_CURRENT_PROGRAM
79 GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING 78 GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
80 } draw; 79 } draw;
@@ -117,7 +116,6 @@ public:
117 void Apply(); 116 void Apply();
118 117
119 void ApplyFramebufferState(); 118 void ApplyFramebufferState();
120 void ApplyVertexArrayState();
121 void ApplyShaderProgram(); 119 void ApplyShaderProgram();
122 void ApplyProgramPipeline(); 120 void ApplyProgramPipeline();
123 void ApplyClipDistances(); 121 void ApplyClipDistances();
@@ -142,7 +140,6 @@ public:
142 OpenGLState& ResetSampler(GLuint handle); 140 OpenGLState& ResetSampler(GLuint handle);
143 OpenGLState& ResetProgram(GLuint handle); 141 OpenGLState& ResetProgram(GLuint handle);
144 OpenGLState& ResetPipeline(GLuint handle); 142 OpenGLState& ResetPipeline(GLuint handle);
145 OpenGLState& ResetVertexArray(GLuint handle);
146 OpenGLState& ResetFramebuffer(GLuint handle); 143 OpenGLState& ResetFramebuffer(GLuint handle);
147 OpenGLState& ResetRenderbuffer(GLuint handle); 144 OpenGLState& ResetRenderbuffer(GLuint handle);
148 145
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 9cd67e05e..2fb5938e2 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -441,22 +441,8 @@ void RendererOpenGL::InitOpenGLObjects() {
441 // Generate VBO handle for drawing 441 // Generate VBO handle for drawing
442 vertex_buffer.Create(); 442 vertex_buffer.Create();
443 443
444 // Generate VAO
445 vertex_array.Create();
446 state.draw.vertex_array = vertex_array.handle;
447
448 // Attach vertex data to VAO 444 // Attach vertex data to VAO
449 glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); 445 glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
450 glVertexArrayAttribFormat(vertex_array.handle, PositionLocation, 2, GL_FLOAT, GL_FALSE,
451 offsetof(ScreenRectVertex, position));
452 glVertexArrayAttribFormat(vertex_array.handle, TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
453 offsetof(ScreenRectVertex, tex_coord));
454 glVertexArrayAttribBinding(vertex_array.handle, PositionLocation, 0);
455 glVertexArrayAttribBinding(vertex_array.handle, TexCoordLocation, 0);
456 glEnableVertexArrayAttrib(vertex_array.handle, PositionLocation);
457 glEnableVertexArrayAttrib(vertex_array.handle, TexCoordLocation);
458 glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0,
459 sizeof(ScreenRectVertex));
460 446
461 // Allocate textures for the screen 447 // Allocate textures for the screen
462 screen_info.texture.resource.Create(GL_TEXTURE_2D); 448 screen_info.texture.resource.Create(GL_TEXTURE_2D);
@@ -581,6 +567,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
581 glCullFace(GL_BACK); 567 glCullFace(GL_BACK);
582 glFrontFace(GL_CW); 568 glFrontFace(GL_CW);
583 569
570 glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
571 offsetof(ScreenRectVertex, position));
572 glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
573 offsetof(ScreenRectVertex, tex_coord));
574 glVertexAttribBinding(PositionLocation, 0);
575 glVertexAttribBinding(TexCoordLocation, 0);
576 glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
577
584 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); 578 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
585 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 579 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
586 // Restore default state 580 // Restore default state
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index d45e69cbc..978a4d0eb 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -96,7 +96,6 @@ private:
96 OpenGLState state; 96 OpenGLState state;
97 97
98 // OpenGL object IDs 98 // OpenGL object IDs
99 OGLVertexArray vertex_array;
100 OGLBuffer vertex_buffer; 99 OGLBuffer vertex_buffer;
101 OGLProgram shader; 100 OGLProgram shader;
102 OGLFramebuffer screenshot_framebuffer; 101 OGLFramebuffer screenshot_framebuffer;
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp
index ac99e6385..f2aaf06db 100644
--- a/src/video_core/renderer_opengl/utils.cpp
+++ b/src/video_core/renderer_opengl/utils.cpp
@@ -24,8 +24,7 @@ VertexArrayPushBuffer::VertexArrayPushBuffer() = default;
24 24
25VertexArrayPushBuffer::~VertexArrayPushBuffer() = default; 25VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
26 26
27void VertexArrayPushBuffer::Setup(GLuint vao_) { 27void VertexArrayPushBuffer::Setup() {
28 vao = vao_;
29 index_buffer = nullptr; 28 index_buffer = nullptr;
30 vertex_buffers.clear(); 29 vertex_buffers.clear();
31} 30}
@@ -41,13 +40,12 @@ void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint*
41 40
42void VertexArrayPushBuffer::Bind() { 41void VertexArrayPushBuffer::Bind() {
43 if (index_buffer) { 42 if (index_buffer) {
44 glVertexArrayElementBuffer(vao, *index_buffer); 43 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *index_buffer);
45 } 44 }
46 45
47 // TODO(Rodrigo): Find a way to ARB_multi_bind this 46 // TODO(Rodrigo): Find a way to ARB_multi_bind this
48 for (const auto& entry : vertex_buffers) { 47 for (const auto& entry : vertex_buffers) {
49 glVertexArrayVertexBuffer(vao, entry.binding_index, *entry.buffer, entry.offset, 48 glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
50 entry.stride);
51 } 49 }
52} 50}
53 51
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h
index 3ad7c02d4..e8612a9ec 100644
--- a/src/video_core/renderer_opengl/utils.h
+++ b/src/video_core/renderer_opengl/utils.h
@@ -16,7 +16,7 @@ public:
16 explicit VertexArrayPushBuffer(); 16 explicit VertexArrayPushBuffer();
17 ~VertexArrayPushBuffer(); 17 ~VertexArrayPushBuffer();
18 18
19 void Setup(GLuint vao_); 19 void Setup();
20 20
21 void SetIndexBuffer(const GLuint* buffer); 21 void SetIndexBuffer(const GLuint* buffer);
22 22
@@ -28,7 +28,6 @@ public:
28private: 28private:
29 struct Entry; 29 struct Entry;
30 30
31 GLuint vao{};
32 const GLuint* index_buffer{}; 31 const GLuint* index_buffer{};
33 std::vector<Entry> vertex_buffers; 32 std::vector<Entry> vertex_buffers;
34}; 33};