From a5bfc0d045cada34248d3de493889371d22ade7c Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 31 Dec 2019 18:16:58 -0300
Subject: [PATCH] gl_state_tracker: Track state of index buffers

---
 src/video_core/renderer_opengl/gl_rasterizer.h    |  2 +-
 src/video_core/renderer_opengl/gl_state_tracker.h | 13 +++++++++++++
 src/video_core/renderer_opengl/utils.cpp          |  7 ++++---
 src/video_core/renderer_opengl/utils.h            |  6 +++++-
 4 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 11206f5579..b24c6661b4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -223,7 +223,7 @@ private:
     static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
     OGLBufferCache buffer_cache;
 
-    VertexArrayPushBuffer vertex_array_pushbuffer;
+    VertexArrayPushBuffer vertex_array_pushbuffer{state_tracker};
     BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
     BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
 
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index 5269dadff9..992b915fb2 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -6,7 +6,10 @@
 
 #include <limits>
 
+#include <glad/glad.h>
+
 #include "common/common_types.h"
+#include "core/core.h"
 #include "video_core/dirty_flags.h"
 #include "video_core/engines/maxwell_3d.h"
 
@@ -85,6 +88,14 @@ public:
 
     void Initialize();
 
+    void BindIndexBuffer(GLuint new_index_buffer) {
+        if (index_buffer == new_index_buffer) {
+            return;
+        }
+        index_buffer = new_index_buffer;
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, new_index_buffer);
+    }
+
     void NotifyScreenDrawVertexArray() {
         auto& flags = system.GPU().Maxwell3D().dirty.flags;
         flags[OpenGL::Dirty::VertexFormats] = true;
@@ -175,6 +186,8 @@ public:
 
 private:
     Core::System& system;
+
+    GLuint index_buffer = 0;
 };
 
 } // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp
index f2aaf06dbb..b751086fab 100644
--- a/src/video_core/renderer_opengl/utils.cpp
+++ b/src/video_core/renderer_opengl/utils.cpp
@@ -9,6 +9,7 @@
 #include <glad/glad.h>
 
 #include "common/common_types.h"
+#include "video_core/renderer_opengl/gl_state_tracker.h"
 #include "video_core/renderer_opengl/utils.h"
 
 namespace OpenGL {
@@ -20,7 +21,8 @@ struct VertexArrayPushBuffer::Entry {
     GLsizei stride{};
 };
 
-VertexArrayPushBuffer::VertexArrayPushBuffer() = default;
+VertexArrayPushBuffer::VertexArrayPushBuffer(StateTracker& state_tracker)
+    : state_tracker{state_tracker} {}
 
 VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
 
@@ -40,10 +42,9 @@ void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint*
 
 void VertexArrayPushBuffer::Bind() {
     if (index_buffer) {
-        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *index_buffer);
+        state_tracker.BindIndexBuffer(*index_buffer);
     }
 
-    // TODO(Rodrigo): Find a way to ARB_multi_bind this
     for (const auto& entry : vertex_buffers) {
         glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
     }
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h
index e8612a9ecc..47ee3177ba 100644
--- a/src/video_core/renderer_opengl/utils.h
+++ b/src/video_core/renderer_opengl/utils.h
@@ -11,9 +11,11 @@
 
 namespace OpenGL {
 
+class StateTracker;
+
 class VertexArrayPushBuffer final {
 public:
-    explicit VertexArrayPushBuffer();
+    explicit VertexArrayPushBuffer(StateTracker& state_tracker);
     ~VertexArrayPushBuffer();
 
     void Setup();
@@ -28,6 +30,8 @@ public:
 private:
     struct Entry;
 
+    StateTracker& state_tracker;
+
     const GLuint* index_buffer{};
     std::vector<Entry> vertex_buffers;
 };