Parcourir la source

gl_shader_util: Grab latest upstream.

bunnei il y a 8 ans
Parent
commit
4f2b2d0bc5

+ 27 - 142
src/video_core/renderer_opengl/gl_shader_util.cpp

@@ -10,156 +10,41 @@
 
 namespace GLShader {
 
-GLuint LoadProgram(const char* vertex_shader, const char* geometry_shader,
-                   const char* fragment_shader, const std::vector<const char*>& feedback_vars,
-                   bool separable_program) {
-    // Create the shaders
-    GLuint vertex_shader_id = vertex_shader ? glCreateShader(GL_VERTEX_SHADER) : 0;
-    GLuint geometry_shader_id = geometry_shader ? glCreateShader(GL_GEOMETRY_SHADER) : 0;
-    GLuint fragment_shader_id = fragment_shader ? glCreateShader(GL_FRAGMENT_SHADER) : 0;
+GLuint LoadShader(const char* source, GLenum type) {
+    const char* debug_type;
+    switch (type) {
+    case GL_VERTEX_SHADER:
+        debug_type = "vertex";
+        break;
+    case GL_GEOMETRY_SHADER:
+        debug_type = "geometry";
+        break;
+    case GL_FRAGMENT_SHADER:
+        debug_type = "fragment";
+        break;
+    default:
+        UNREACHABLE();
+    }
+    GLuint shader_id = glCreateShader(type);
+    glShaderSource(shader_id, 1, &source, nullptr);
+    NGLOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type);
+    glCompileShader(shader_id);
 
     GLint result = GL_FALSE;
-    int info_log_length;
-
-    if (vertex_shader) {
-        // Compile Vertex Shader
-        LOG_DEBUG(Render_OpenGL, "Compiling vertex shader...");
-
-        glShaderSource(vertex_shader_id, 1, &vertex_shader, nullptr);
-        glCompileShader(vertex_shader_id);
-
-        // Check Vertex Shader
-        glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &result);
-        glGetShaderiv(vertex_shader_id, GL_INFO_LOG_LENGTH, &info_log_length);
-
-        if (info_log_length > 1) {
-            std::vector<char> vertex_shader_error(info_log_length);
-            glGetShaderInfoLog(vertex_shader_id, info_log_length, nullptr, &vertex_shader_error[0]);
-            if (result == GL_TRUE) {
-                LOG_DEBUG(Render_OpenGL, "%s", &vertex_shader_error[0]);
-            } else {
-                LOG_CRITICAL(Render_OpenGL, "Error compiling vertex shader:\n%s",
-                             &vertex_shader_error[0]);
-            }
-        }
-    }
-
-    if (geometry_shader) {
-        // Compile Geometry Shader
-        LOG_DEBUG(Render_OpenGL, "Compiling geometry shader...");
-
-        glShaderSource(geometry_shader_id, 1, &geometry_shader, nullptr);
-        glCompileShader(geometry_shader_id);
-
-        // Check Geometry Shader
-        glGetShaderiv(geometry_shader_id, GL_COMPILE_STATUS, &result);
-        glGetShaderiv(geometry_shader_id, GL_INFO_LOG_LENGTH, &info_log_length);
-
-        if (info_log_length > 1) {
-            std::vector<char> geometry_shader_error(info_log_length);
-            glGetShaderInfoLog(geometry_shader_id, info_log_length, nullptr,
-                               &geometry_shader_error[0]);
-            if (result == GL_TRUE) {
-                LOG_DEBUG(Render_OpenGL, "%s", &geometry_shader_error[0]);
-            } else {
-                LOG_CRITICAL(Render_OpenGL, "Error compiling geometry shader:\n%s",
-                             &geometry_shader_error[0]);
-            }
-        }
-    }
-
-    if (fragment_shader) {
-        // Compile Fragment Shader
-        LOG_DEBUG(Render_OpenGL, "Compiling fragment shader...");
-
-        glShaderSource(fragment_shader_id, 1, &fragment_shader, nullptr);
-        glCompileShader(fragment_shader_id);
-
-        // Check Fragment Shader
-        glGetShaderiv(fragment_shader_id, GL_COMPILE_STATUS, &result);
-        glGetShaderiv(fragment_shader_id, GL_INFO_LOG_LENGTH, &info_log_length);
-
-        if (info_log_length > 1) {
-            std::vector<char> fragment_shader_error(info_log_length);
-            glGetShaderInfoLog(fragment_shader_id, info_log_length, nullptr,
-                               &fragment_shader_error[0]);
-            if (result == GL_TRUE) {
-                LOG_DEBUG(Render_OpenGL, "%s", &fragment_shader_error[0]);
-            } else {
-                LOG_CRITICAL(Render_OpenGL, "Error compiling fragment shader:\n%s",
-                             &fragment_shader_error[0]);
-            }
-        }
-    }
-
-    // Link the program
-    LOG_DEBUG(Render_OpenGL, "Linking program...");
-
-    GLuint program_id = glCreateProgram();
-    if (vertex_shader) {
-        glAttachShader(program_id, vertex_shader_id);
-    }
-    if (geometry_shader) {
-        glAttachShader(program_id, geometry_shader_id);
-    }
-    if (fragment_shader) {
-        glAttachShader(program_id, fragment_shader_id);
-    }
-
-    if (!feedback_vars.empty()) {
-        auto varyings = feedback_vars;
-        glTransformFeedbackVaryings(program_id, static_cast<GLsizei>(feedback_vars.size()),
-                                    &varyings[0], GL_INTERLEAVED_ATTRIBS);
-    }
-
-    if (separable_program) {
-        glProgramParameteri(program_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
-    }
-
-    glLinkProgram(program_id);
-
-    // Check the program
-    glGetProgramiv(program_id, GL_LINK_STATUS, &result);
-    glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &info_log_length);
+    GLint info_log_length;
+    glGetShaderiv(shader_id, GL_COMPILE_STATUS, &result);
+    glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &info_log_length);
 
     if (info_log_length > 1) {
-        std::vector<char> program_error(info_log_length);
-        glGetProgramInfoLog(program_id, info_log_length, nullptr, &program_error[0]);
+        std::string shader_error(info_log_length, ' ');
+        glGetShaderInfoLog(shader_id, info_log_length, nullptr, &shader_error[0]);
         if (result == GL_TRUE) {
-            LOG_DEBUG(Render_OpenGL, "%s", &program_error[0]);
+            NGLOG_DEBUG(Render_OpenGL, "{}", shader_error);
         } else {
-            LOG_CRITICAL(Render_OpenGL, "Error linking shader:\n%s", &program_error[0]);
+            NGLOG_ERROR(Render_OpenGL, "Error compiling {} shader:\n{}", debug_type, shader_error);
         }
     }
-
-    // If the program linking failed at least one of the shaders was probably bad
-    if (result == GL_FALSE) {
-        if (vertex_shader) {
-            LOG_CRITICAL(Render_OpenGL, "Vertex shader:\n%s", vertex_shader);
-        }
-        if (geometry_shader) {
-            LOG_CRITICAL(Render_OpenGL, "Geometry shader:\n%s", geometry_shader);
-        }
-        if (fragment_shader) {
-            LOG_CRITICAL(Render_OpenGL, "Fragment shader:\n%s", fragment_shader);
-        }
-    }
-    ASSERT_MSG(result == GL_TRUE, "Shader not linked");
-
-    if (vertex_shader) {
-        glDetachShader(program_id, vertex_shader_id);
-        glDeleteShader(vertex_shader_id);
-    }
-    if (geometry_shader) {
-        glDetachShader(program_id, geometry_shader_id);
-        glDeleteShader(geometry_shader_id);
-    }
-    if (fragment_shader) {
-        glDetachShader(program_id, fragment_shader_id);
-        glDeleteShader(fragment_shader_id);
-    }
-
-    return program_id;
+    return shader_id;
 }
 
 } // namespace GLShader

+ 47 - 7
src/video_core/renderer_opengl/gl_shader_util.h

@@ -9,15 +9,55 @@
 
 namespace GLShader {
 
+/**
+ * Utility function to create and compile an OpenGL GLSL shader
+ * @param source String of the GLSL shader program
+ * @param type Type of the shader (GL_VERTEX_SHADER, GL_GEOMETRY_SHADER or GL_FRAGMENT_SHADER)
+ */
+GLuint LoadShader(const char* source, GLenum type);
+
 /**
  * Utility function to create and compile an OpenGL GLSL shader program (vertex + fragment shader)
- * @param vertex_shader String of the GLSL vertex shader program
- * @param geometry_shader String of the GLSL geometry shader program
- * @param fragment_shader String of the GLSL fragment shader program
- * @returns Handle of the newly created OpenGL shader object
+ * @param separable_program whether to create a separable program
+ * @param shaders ID of shaders to attach to the program
+ * @returns Handle of the newly created OpenGL program object
  */
-GLuint LoadProgram(const char* vertex_shader, const char* geometry_shader,
-                   const char* fragment_shader, const std::vector<const char*>& feedback_vars = {},
-                   bool separable_program = false);
+template <typename... T>
+GLuint LoadProgram(bool separable_program, T... shaders) {
+    // Link the program
+    NGLOG_DEBUG(Render_OpenGL, "Linking program...");
+
+    GLuint program_id = glCreateProgram();
+
+    ((shaders == 0 ? (void)0 : glAttachShader(program_id, shaders)), ...);
+
+    if (separable_program) {
+        glProgramParameteri(program_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
+    }
+
+    glLinkProgram(program_id);
+
+    // Check the program
+    GLint result = GL_FALSE;
+    GLint info_log_length;
+    glGetProgramiv(program_id, GL_LINK_STATUS, &result);
+    glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &info_log_length);
+
+    if (info_log_length > 1) {
+        std::string program_error(info_log_length, ' ');
+        glGetProgramInfoLog(program_id, info_log_length, nullptr, &program_error[0]);
+        if (result == GL_TRUE) {
+            NGLOG_DEBUG(Render_OpenGL, "{}", program_error);
+        } else {
+            NGLOG_ERROR(Render_OpenGL, "Error linking shader:\n{}", program_error);
+        }
+    }
+
+    ASSERT_MSG(result == GL_TRUE, "Shader not linked");
+
+    ((shaders == 0 ? (void)0 : glDetachShader(program_id, shaders)), ...);
+
+    return program_id;
+}
 
 } // namespace GLShader