From 877a978a221d0418953338fe9644dc2b1d8b7b15 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 9 Jan 2019 02:40:19 -0300 Subject: [PATCH] gl_rasterizer: Workaround Intel VAO DSA bug There is a bug on Intel's blob driver where it fails to properly build a vertex array object if it's not bound even after creating it with glCreateVertexArrays. This workaround binds it after creating it to bypass the issue. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 ++++++ src/video_core/renderer_opengl/gl_state.cpp | 13 +++++++------ src/video_core/renderer_opengl/gl_state.h | 4 +++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7ce8c2bcc5..61ccfa1048 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -153,6 +153,12 @@ GLuint RasterizerOpenGL::SetupVertexFormat() { 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(); + glVertexArrayElementBuffer(vao, buffer_cache.GetHandle()); // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 79bb52ddf7..b7ba59350d 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -503,7 +503,6 @@ void OpenGLState::ApplySamplers() const { } void OpenGLState::ApplyFramebufferState() const { - // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); } @@ -512,6 +511,12 @@ void OpenGLState::ApplyFramebufferState() const { } } +void OpenGLState::ApplyVertexArrayState() const { + if (draw.vertex_array != cur_state.draw.vertex_array) { + glBindVertexArray(draw.vertex_array); + } +} + void OpenGLState::ApplyDepthClamp() const { if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { @@ -529,11 +534,7 @@ void OpenGLState::ApplyDepthClamp() const { void OpenGLState::Apply() const { ApplyFramebufferState(); - - // Vertex array - if (draw.vertex_array != cur_state.draw.vertex_array) { - glBindVertexArray(draw.vertex_array); - } + ApplyVertexArrayState(); // Shader program if (draw.shader_program != cur_state.draw.shader_program) { diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 9dc3f0cc89..a5a7c09205 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -204,8 +204,10 @@ public: } /// Apply this state as the current OpenGL state void Apply() const; - /// Apply only the state afecting the framebuffer + /// Apply only the state affecting the framebuffer void ApplyFramebufferState() const; + /// Apply only the state affecting the vertex array + void ApplyVertexArrayState() const; /// Set the initial OpenGL state static void ApplyDefaultState(); /// Resets any references to the given resource