Просмотр исходного кода

gl_state: Remove VAO cache and tracking

ReinUsesLisp 6 лет назад
Родитель
Сommit
d5ab0358b6

+ 37 - 63
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -107,7 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
     state.draw.shader_program = 0;
     state.Apply();
 
-    LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
     CheckExtensions();
 }
 
@@ -121,66 +120,41 @@ void RasterizerOpenGL::CheckExtensions() {
     }
 }
 
-GLuint RasterizerOpenGL::SetupVertexFormat() {
+void RasterizerOpenGL::SetupVertexFormat() {
     auto& gpu = system.GPU().Maxwell3D();
     const auto& regs = gpu.regs;
 
     MICROPROFILE_SCOPE(OpenGL_VAO);
 
-    auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
-    auto& vao_entry = iter->second;
-
-    if (is_cache_miss) {
-        vao_entry.Create();
-        const GLuint vao = vao_entry.handle;
-
-        // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob
-        // that fails to properly create the vertex array if it's not bound even after creating it
-        // with glCreateVertexArrays
-        state.draw.vertex_array = vao;
-        state.ApplyVertexArrayState();
-
-        // 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
-        // for now to avoid OpenGL errors.
-        // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
-        // assume every shader uses them all.
-        for (u32 index = 0; index < 16; ++index) {
-            const auto& attrib = regs.vertex_attrib_format[index];
-
-            // Ignore invalid attributes.
-            if (!attrib.IsValid())
-                continue;
-
-            const auto& buffer = regs.vertex_array[attrib.buffer];
-            LOG_TRACE(Render_OpenGL,
-                      "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
-                      index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
-                      attrib.offset.Value(), attrib.IsNormalized());
-
-            ASSERT(buffer.IsEnabled());
-
-            glEnableVertexArrayAttrib(vao, index);
-            if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
-                attrib.type ==
-                    Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
-                glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
-                                           MaxwellToGL::VertexType(attrib), attrib.offset);
-            } else {
-                glVertexArrayAttribFormat(
-                    vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
-                    attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
-            }
-            glVertexArrayAttribBinding(vao, index, attrib.buffer);
+    // 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 for now to
+    // avoid OpenGL errors.
+    // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
+    // assume every shader uses them all.
+    for (u32 index = 0; index < 16; ++index) {
+        const auto& attrib = regs.vertex_attrib_format[index];
+
+        // Ignore invalid attributes.
+        if (!attrib.IsValid()) {
+            glDisableVertexAttribArray(index);
+            continue;
         }
-    }
+        glEnableVertexAttribArray(index);
 
-    state.draw.vertex_array = vao_entry.handle;
-    return vao_entry.handle;
+        if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
+            attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
+            glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+                                  attrib.offset);
+        } else {
+            glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+                                 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
+        }
+        glVertexAttribBinding(index, attrib.buffer);
+    }
 }
 
-void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
+void RasterizerOpenGL::SetupVertexBuffer() {
     auto& gpu = system.GPU().Maxwell3D();
     const auto& regs = gpu.regs;
 
@@ -189,8 +163,9 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
     // Upload all guest vertex arrays sequentially to our buffer
     for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
         const auto& vertex_array = regs.vertex_array[index];
-        if (!vertex_array.IsEnabled())
+        if (!vertex_array.IsEnabled()) {
             continue;
+        }
 
         const GPUVAddr start = vertex_array.StartAddress();
         const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
@@ -205,15 +180,15 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
 
         if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
             // Enable vertex buffer instancing with the specified divisor.
-            glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
+            glVertexBindingDivisor(index, vertex_array.divisor);
         } else {
             // Disable the vertex buffer instancing.
-            glVertexArrayBindingDivisor(vao, index, 0);
+            glVertexBindingDivisor(index, 0);
         }
     }
 }
 
-void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
+void RasterizerOpenGL::SetupVertexInstances() {
     auto& gpu = system.GPU().Maxwell3D();
     const auto& regs = gpu.regs;
 
@@ -222,10 +197,10 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
         if (regs.instanced_arrays.IsInstancingEnabled(index) &&
             regs.vertex_array[index].divisor != 0) {
             // Enable vertex buffer instancing with the specified divisor.
-            glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor);
+            glVertexBindingDivisor(index, regs.vertex_array[index].divisor);
         } else {
             // Disable the vertex buffer instancing.
-            glVertexArrayBindingDivisor(vao, index, 0);
+            glVertexBindingDivisor(index, 0);
         }
     }
 }
@@ -559,13 +534,12 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
     buffer_cache.Map(buffer_size);
 
     // Prepare vertex array format.
-    const GLuint vao = SetupVertexFormat();
-    vertex_array_pushbuffer.Setup(vao);
+    SetupVertexFormat();
+    vertex_array_pushbuffer.Setup();
 
     // Upload vertex and index data.
-    SetupVertexBuffer(vao);
-    SetupVertexInstances(vao);
-
+    SetupVertexBuffer();
+    SetupVertexInstances();
     GLintptr index_buffer_offset;
     if (is_indexed) {
         index_buffer_offset = SetupIndexBuffer();

+ 4 - 8
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -194,11 +194,11 @@ private:
 
     std::size_t CalculateIndexBufferSize() const;
 
-    /// Updates and returns a vertex array object representing current vertex format
-    GLuint SetupVertexFormat();
+    /// Updates the current vertex format
+    void SetupVertexFormat();
 
-    void SetupVertexBuffer(GLuint vao);
-    void SetupVertexInstances(GLuint vao);
+    void SetupVertexBuffer();
+    void SetupVertexInstances();
 
     GLintptr SetupIndexBuffer();
 
@@ -217,10 +217,6 @@ private:
     ScreenInfo& screen_info;
 
     std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
-    std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute,
-                        Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>,
-             OGLVertexArray>
-        vertex_array_cache;
 
     static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
     OGLBufferCache buffer_cache;

+ 0 - 18
src/video_core/renderer_opengl/gl_resource_manager.cpp

@@ -189,24 +189,6 @@ void OGLSync::Release() {
     handle = 0;
 }
 
-void OGLVertexArray::Create() {
-    if (handle != 0)
-        return;
-
-    MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
-    glCreateVertexArrays(1, &handle);
-}
-
-void OGLVertexArray::Release() {
-    if (handle == 0)
-        return;
-
-    MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
-    glDeleteVertexArrays(1, &handle);
-    OpenGLState::GetCurState().ResetVertexArray(handle).Apply();
-    handle = 0;
-}
-
 void OGLFramebuffer::Create() {
     if (handle != 0)
         return;

+ 0 - 25
src/video_core/renderer_opengl/gl_resource_manager.h

@@ -241,31 +241,6 @@ public:
     GLsync handle = 0;
 };
 
-class OGLVertexArray : private NonCopyable {
-public:
-    OGLVertexArray() = default;
-
-    OGLVertexArray(OGLVertexArray&& o) noexcept : handle(std::exchange(o.handle, 0)) {}
-
-    ~OGLVertexArray() {
-        Release();
-    }
-
-    OGLVertexArray& operator=(OGLVertexArray&& o) noexcept {
-        Release();
-        handle = std::exchange(o.handle, 0);
-        return *this;
-    }
-
-    /// Creates a new internal OpenGL resource and stores the handle
-    void Create();
-
-    /// Deletes the internal OpenGL resource
-    void Release();
-
-    GLuint handle = 0;
-};
-
 class OGLFramebuffer : private NonCopyable {
 public:
     OGLFramebuffer() = default;

+ 0 - 14
src/video_core/renderer_opengl/gl_state.cpp

@@ -98,12 +98,6 @@ void OpenGLState::ApplyFramebufferState() {
     }
 }
 
-void OpenGLState::ApplyVertexArrayState() {
-    if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) {
-        glBindVertexArray(draw.vertex_array);
-    }
-}
-
 void OpenGLState::ApplyShaderProgram() {
     if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
         glUseProgram(draw.shader_program);
@@ -338,7 +332,6 @@ void OpenGLState::ApplyImages() {
 void OpenGLState::Apply() {
     MICROPROFILE_SCOPE(OpenGL_State);
     ApplyFramebufferState();
-    ApplyVertexArrayState();
     ApplyShaderProgram();
     ApplyProgramPipeline();
     ApplyClipDistances();
@@ -411,13 +404,6 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
     return *this;
 }
 
-OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) {
-    if (draw.vertex_array == handle) {
-        draw.vertex_array = 0;
-    }
-    return *this;
-}
-
 OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) {
     if (draw.read_framebuffer == handle) {
         draw.read_framebuffer = 0;

+ 0 - 3
src/video_core/renderer_opengl/gl_state.h

@@ -74,7 +74,6 @@ public:
     struct {
         GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
         GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
-        GLuint vertex_array = 0;     // GL_VERTEX_ARRAY_BINDING
         GLuint shader_program = 0;   // GL_CURRENT_PROGRAM
         GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
     } draw;
@@ -117,7 +116,6 @@ public:
     void Apply();
 
     void ApplyFramebufferState();
-    void ApplyVertexArrayState();
     void ApplyShaderProgram();
     void ApplyProgramPipeline();
     void ApplyClipDistances();
@@ -142,7 +140,6 @@ public:
     OpenGLState& ResetSampler(GLuint handle);
     OpenGLState& ResetProgram(GLuint handle);
     OpenGLState& ResetPipeline(GLuint handle);
-    OpenGLState& ResetVertexArray(GLuint handle);
     OpenGLState& ResetFramebuffer(GLuint handle);
     OpenGLState& ResetRenderbuffer(GLuint handle);
 

+ 8 - 14
src/video_core/renderer_opengl/renderer_opengl.cpp

@@ -441,22 +441,8 @@ void RendererOpenGL::InitOpenGLObjects() {
     // Generate VBO handle for drawing
     vertex_buffer.Create();
 
-    // Generate VAO
-    vertex_array.Create();
-    state.draw.vertex_array = vertex_array.handle;
-
     // Attach vertex data to VAO
     glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
-    glVertexArrayAttribFormat(vertex_array.handle, PositionLocation, 2, GL_FLOAT, GL_FALSE,
-                              offsetof(ScreenRectVertex, position));
-    glVertexArrayAttribFormat(vertex_array.handle, TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
-                              offsetof(ScreenRectVertex, tex_coord));
-    glVertexArrayAttribBinding(vertex_array.handle, PositionLocation, 0);
-    glVertexArrayAttribBinding(vertex_array.handle, TexCoordLocation, 0);
-    glEnableVertexArrayAttrib(vertex_array.handle, PositionLocation);
-    glEnableVertexArrayAttrib(vertex_array.handle, TexCoordLocation);
-    glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0,
-                              sizeof(ScreenRectVertex));
 
     // Allocate textures for the screen
     screen_info.texture.resource.Create(GL_TEXTURE_2D);
@@ -581,6 +567,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     glCullFace(GL_BACK);
     glFrontFace(GL_CW);
 
+    glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
+                         offsetof(ScreenRectVertex, position));
+    glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
+                         offsetof(ScreenRectVertex, tex_coord));
+    glVertexAttribBinding(PositionLocation, 0);
+    glVertexAttribBinding(TexCoordLocation, 0);
+    glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
+
     glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     // Restore default state

+ 0 - 1
src/video_core/renderer_opengl/renderer_opengl.h

@@ -96,7 +96,6 @@ private:
     OpenGLState state;
 
     // OpenGL object IDs
-    OGLVertexArray vertex_array;
     OGLBuffer vertex_buffer;
     OGLProgram shader;
     OGLFramebuffer screenshot_framebuffer;

+ 3 - 5
src/video_core/renderer_opengl/utils.cpp

@@ -24,8 +24,7 @@ VertexArrayPushBuffer::VertexArrayPushBuffer() = default;
 
 VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
 
-void VertexArrayPushBuffer::Setup(GLuint vao_) {
-    vao = vao_;
+void VertexArrayPushBuffer::Setup() {
     index_buffer = nullptr;
     vertex_buffers.clear();
 }
@@ -41,13 +40,12 @@ void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint*
 
 void VertexArrayPushBuffer::Bind() {
     if (index_buffer) {
-        glVertexArrayElementBuffer(vao, *index_buffer);
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *index_buffer);
     }
 
     // TODO(Rodrigo): Find a way to ARB_multi_bind this
     for (const auto& entry : vertex_buffers) {
-        glVertexArrayVertexBuffer(vao, entry.binding_index, *entry.buffer, entry.offset,
-                                  entry.stride);
+        glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
     }
 }
 

+ 1 - 2
src/video_core/renderer_opengl/utils.h

@@ -16,7 +16,7 @@ public:
     explicit VertexArrayPushBuffer();
     ~VertexArrayPushBuffer();
 
-    void Setup(GLuint vao_);
+    void Setup();
 
     void SetIndexBuffer(const GLuint* buffer);
 
@@ -28,7 +28,6 @@ public:
 private:
     struct Entry;
 
-    GLuint vao{};
     const GLuint* index_buffer{};
     std::vector<Entry> vertex_buffers;
 };