Demos (master): Don't use OpenGL 2.0 GLSL functions if OpenGL 2. 0 is not supported

Ian Romanick idr at kemper.freedesktop.org
Fri Oct 29 13:45:43 PDT 2010


Module: Demos
Branch: master
Commit: 10674b59ef4aa9e8fb0d8f150f5ad20c49c9d5a7
URL:    http://cgit.freedesktop.org/mesa/demos/commit/?id=10674b59ef4aa9e8fb0d8f150f5ad20c49c9d5a7

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Oct 29 13:40:20 2010 -0700

Don't use OpenGL 2.0 GLSL functions if OpenGL 2.0 is not supported

GLEW doesn't initialize function pointers for core versions or
extensions that are not supported.  If OpenGL 2.0 was not supported
but all of the GLSL extensions were, the OpenGL 2.0 function pointers
from GLEW would still be NULL.  As a result, programs would always
segfault.

This patch fixes shaderutil to do the right thing, and fixes brick.c
to do the right thing.  Other demos will still explode, but they can
be fixed in a manner similar to brick.c.

This is related to bugzilla #31118.

---

 src/glsl/brick.c      |   16 ++++---
 src/glsl/multitex.c   |    6 +-
 src/glsl/samplers.c   |    4 +-
 src/glsl/texdemo1.c   |    6 +-
 src/tests/floattex.c  |    4 +-
 src/util/shaderutil.c |  127 ++++++++++++++++++++++++++++++++++++-------------
 src/util/shaderutil.h |   23 +++++++++
 7 files changed, 136 insertions(+), 50 deletions(-)

diff --git a/src/glsl/brick.c b/src/glsl/brick.c
index 20417aa..6f15304 100644
--- a/src/glsl/brick.c
+++ b/src/glsl/brick.c
@@ -80,9 +80,9 @@ Reshape(int width, int height)
 static void
 CleanUp(void)
 {
-   glDeleteShader(fragShader);
-   glDeleteShader(vertShader);
-   glDeleteProgram(program);
+   DeleteShader(fragShader);
+   DeleteShader(vertShader);
+   DeleteProgram(program);
    glutDestroyWindow(win);
 }
 
@@ -146,7 +146,7 @@ Init(void)
    fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
    program = LinkShaders(vertShader, fragShader);
 
-   glUseProgram(program);
+   UseProgram(program);
 
    SetUniformValues(program, Uniforms);
    PrintUniforms(Uniforms);
@@ -157,9 +157,11 @@ Init(void)
 
    printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
 
-   assert(glIsProgram(program));
-   assert(glIsShader(fragShader));
-   assert(glIsShader(vertShader));
+   if (GLEW_VERSION_2_0) {
+      assert(glIsProgram(program));
+      assert(glIsShader(fragShader));
+      assert(glIsShader(vertShader));
+   }
 
    glColor3f(1, 0, 0);
 }
diff --git a/src/glsl/multitex.c b/src/glsl/multitex.c
index 49b3225..b1d278a 100644
--- a/src/glsl/multitex.c
+++ b/src/glsl/multitex.c
@@ -316,8 +316,8 @@ InitTextures(void)
 
 
 static GLuint
-CreateProgram(const char *vertProgFile, const char *fragProgFile,
-              struct uniform_info *uniforms)
+CreateAProgram(const char *vertProgFile, const char *fragProgFile,
+	       struct uniform_info *uniforms)
 {
    GLuint fragShader, vertShader, program;
 
@@ -362,7 +362,7 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile,
 static void
 InitPrograms(void)
 {
-   Program = CreateProgram(VertFile, FragFile, Uniforms);
+   Program = CreateAProgram(VertFile, FragFile, Uniforms);
 }
 
 
diff --git a/src/glsl/samplers.c b/src/glsl/samplers.c
index 8f26a5e..eff01e5 100644
--- a/src/glsl/samplers.c
+++ b/src/glsl/samplers.c
@@ -279,7 +279,7 @@ GenFragmentShader(GLint numSamplers)
 
 /** Create & bind shader program */
 static GLuint
-CreateProgram(void)
+CreateAProgram(void)
 {
    GLuint fragShader, vertShader, program;
    const char *vertShaderText = 
@@ -310,7 +310,7 @@ InitProgram(void)
 {
    GLint s;
 
-   Program = CreateProgram();
+   Program = CreateAProgram();
 
    /* init sampler uniforms */
    for (s = 0; s < NumSamplers; s++) {
diff --git a/src/glsl/texdemo1.c b/src/glsl/texdemo1.c
index 2076e6a..5220b5e 100644
--- a/src/glsl/texdemo1.c
+++ b/src/glsl/texdemo1.c
@@ -371,7 +371,7 @@ InitTextures(GLboolean useImageFiles)
 
 
 static GLuint
-CreateProgram(const char *vertProgFile, const char *fragProgFile,
+CreateAProgram(const char *vertProgFile, const char *fragProgFile,
               struct uniform_info *uniforms)
 {
    GLuint fragShader, vertShader, program;
@@ -392,8 +392,8 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile,
 static void
 InitPrograms(void)
 {
-   Program1 = CreateProgram(ReflectVertFile, CubeFragFile, ReflectUniforms);
-   Program2 = CreateProgram(SimpleVertFile, SimpleTexFragFile, SimpleUniforms);
+   Program1 = CreateAProgram(ReflectVertFile, CubeFragFile, ReflectUniforms);
+   Program2 = CreateAProgram(SimpleVertFile, SimpleTexFragFile, SimpleUniforms);
 }
 
 
diff --git a/src/tests/floattex.c b/src/tests/floattex.c
index 7b6e807..46ceddb 100644
--- a/src/tests/floattex.c
+++ b/src/tests/floattex.c
@@ -175,7 +175,7 @@ InitTexture(void)
 
 
 static GLuint
-CreateProgram(void)
+CreateAProgram(void)
 {
    GLuint fragShader, vertShader, program;
 
@@ -212,7 +212,7 @@ Init(void)
 
    InitTexture();
 
-   Program = CreateProgram();
+   Program = CreateAProgram();
    glUseProgram(Program);
 }
 
diff --git a/src/util/shaderutil.c b/src/util/shaderutil.c
index 2f44c38..87d7e87 100644
--- a/src/util/shaderutil.c
+++ b/src/util/shaderutil.c
@@ -20,22 +20,83 @@ static GLdouble CompileTime = 0.0;
 /** time to linke previous program */
 static GLdouble LinkTime = 0.0;
 
+PFNGLCREATESHADERPROC CreateShader = NULL;
+PFNGLDELETESHADERPROC DeleteShader = NULL;
+PFNGLSHADERSOURCEPROC ShaderSource = NULL;
+PFNGLGETSHADERIVPROC GetShaderiv = NULL;
+PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog = NULL;
+PFNGLCREATEPROGRAMPROC CreateProgram = NULL;
+PFNGLDELETEPROGRAMPROC DeleteProgram = NULL;
+PFNGLATTACHSHADERPROC AttachShader = NULL;
+PFNGLLINKPROGRAMPROC LinkProgram = NULL;
+PFNGLUSEPROGRAMPROC UseProgram = NULL;
+PFNGLGETPROGRAMIVPROC GetProgramiv = NULL;
+PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog = NULL;
+PFNGLVALIDATEPROGRAMARBPROC ValidateProgramARB = NULL;
+PFNGLUNIFORM1IPROC Uniform1i = NULL;
+PFNGLUNIFORM1FVPROC Uniform1fv = NULL;
+PFNGLUNIFORM2FVPROC Uniform2fv = NULL;
+PFNGLUNIFORM3FVPROC Uniform3fv = NULL;
+PFNGLUNIFORM4FVPROC Uniform4fv = NULL;
+PFNGLGETACTIVEATTRIBPROC GetActiveAttrib = NULL;
+PFNGLGETATTRIBLOCATIONPROC GetAttribLocation = NULL;
+
+static void
+fake_ValidateProgram(GLuint prog)
+{
+   (void) prog;
+}
 
 GLboolean
 ShadersSupported(void)
 {
-   const char *version = (const char *) glGetString(GL_VERSION);
-
-   /* NVIDIA binary drivers will return "3.0.0", and they clearly support
-    * shaders.
-    */
-   if (version[0] >= '2' && version[1] == '.') {
+   if (GLEW_VERSION_2_0) {
+      CreateShader = glCreateShader;
+      DeleteShader = glDeleteShader;
+      ShaderSource = glShaderSource;
+      GetShaderiv = glGetShaderiv;
+      GetShaderInfoLog = glGetShaderInfoLog;
+      CreateProgram = glCreateProgram;
+      DeleteProgram = glDeleteProgram;
+      AttachShader = glAttachShader;
+      LinkProgram = glLinkProgram;
+      UseProgram = glUseProgram;
+      GetProgramiv = glGetProgramiv;
+      GetProgramInfoLog = glGetProgramInfoLog;
+      ValidateProgramARB = (GLEW_ARB_shader_objects)
+	 ? glValidateProgramARB : fake_ValidateProgram;
+      Uniform1i = glUniform1i;
+      Uniform1fv = glUniform1fv;
+      Uniform2fv = glUniform2fv;
+      Uniform3fv = glUniform3fv;
+      Uniform4fv = glUniform4fv;
+      GetActiveAttrib = glGetActiveAttrib;
+      GetAttribLocation = glGetAttribLocation;
       return GL_TRUE;
    }
-   else if (glutExtensionSupported("GL_ARB_vertex_shader")
-            && glutExtensionSupported("GL_ARB_fragment_shader")
-            && glutExtensionSupported("GL_ARB_shader_objects")) {
+   else if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader
+	    && GLEW_ARB_shader_objects) {
       fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x.  This may not work.\n");
+      CreateShader = glCreateShaderObjectARB;
+      DeleteShader = glDeleteObjectARB;
+      ShaderSource = glShaderSourceARB;
+      GetShaderiv = glGetObjectParameterivARB;
+      GetShaderInfoLog = glGetInfoLogARB;
+      CreateProgram = glCreateProgramObjectARB;
+      DeleteProgram = glDeleteObjectARB;
+      AttachShader = glAttachObjectARB;
+      LinkProgram = glLinkProgramARB;
+      UseProgram = glUseProgramObjectARB;
+      GetProgramiv = glGetObjectParameterivARB;
+      GetProgramInfoLog = glGetInfoLogARB;
+      ValidateProgramARB = glValidateProgramARB;
+      Uniform1i = glUniform1iARB;
+      Uniform1fv = glUniform1fvARB;
+      Uniform2fv = glUniform2fvARB;
+      Uniform3fv = glUniform3fvARB;
+      Uniform4fv = glUniform4fvARB;
+      GetActiveAttrib = glGetActiveAttribARB;
+      GetAttribLocation = glGetAttribLocationARB;
       return GL_TRUE;
    }
    fprintf(stderr, "Sorry, GLSL not supported with this OpenGL.\n");
@@ -50,8 +111,8 @@ CompileShaderText(GLenum shaderType, const char *text)
    GLint stat;
    GLdouble t0, t1;
 
-   shader = glCreateShader(shaderType);
-   glShaderSource(shader, 1, (const GLchar **) &text, NULL);
+   shader = CreateShader(shaderType);
+   ShaderSource(shader, 1, (const GLchar **) &text, NULL);
 
    t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
    glCompileShader(shader);
@@ -59,11 +120,11 @@ CompileShaderText(GLenum shaderType, const char *text)
 
    CompileTime = t1 - t0;
 
-   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+   GetShaderiv(shader, GL_COMPILE_STATUS, &stat);
    if (!stat) {
       GLchar log[1000];
       GLsizei len;
-      glGetShaderInfoLog(shader, 1000, &len, log);
+      GetShaderInfoLog(shader, 1000, &len, log);
       fprintf(stderr, "Error: problem compiling shader: %s\n", log);
       exit(1);
    }
@@ -115,18 +176,18 @@ CompileShaderFile(GLenum shaderType, const char *filename)
 GLuint
 LinkShaders(GLuint vertShader, GLuint fragShader)
 {
-   GLuint program = glCreateProgram();
+   GLuint program = CreateProgram();
    GLdouble t0, t1;
 
    assert(vertShader || fragShader);
 
    if (fragShader)
-      glAttachShader(program, fragShader);
+      AttachShader(program, fragShader);
    if (vertShader)
-      glAttachShader(program, vertShader);
+      AttachShader(program, vertShader);
 
    t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
-   glLinkProgram(program);
+   LinkProgram(program);
    t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
 
    LinkTime = t1 - t0;
@@ -134,11 +195,11 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
    /* check link */
    {
       GLint stat;
-      glGetProgramiv(program, GL_LINK_STATUS, &stat);
+      GetProgramiv(program, GL_LINK_STATUS, &stat);
       if (!stat) {
          GLchar log[1000];
          GLsizei len;
-         glGetProgramInfoLog(program, 1000, &len, log);
+         GetProgramInfoLog(program, 1000, &len, log);
          fprintf(stderr, "Shader link error:\n%s\n", log);
          return 0;
       }
@@ -152,13 +213,13 @@ GLboolean
 ValidateShaderProgram(GLuint program)
 {
    GLint stat;
-   glValidateProgramARB(program);
-   glGetProgramiv(program, GL_VALIDATE_STATUS, &stat);
+   ValidateProgramARB(program);
+   GetProgramiv(program, GL_VALIDATE_STATUS, &stat);
 
    if (!stat) {
       GLchar log[1000];
       GLsizei len;
-      glGetProgramInfoLog(program, 1000, &len, log);
+      GetProgramInfoLog(program, 1000, &len, log);
       fprintf(stderr, "Program validation error:\n%s\n", log);
       return 0;
    }
@@ -198,20 +259,20 @@ SetUniformValues(GLuint program, struct uniform_info uniforms[])
       case GL_SAMPLER_CUBE:
       case GL_SAMPLER_2D_RECT_ARB:
          assert(uniforms[i].value[0] >= 0.0F);
-         glUniform1i(uniforms[i].location,
+         Uniform1i(uniforms[i].location,
                      (GLint) uniforms[i].value[0]);
          break;
       case GL_FLOAT:
-         glUniform1fv(uniforms[i].location, 1, uniforms[i].value);
+         Uniform1fv(uniforms[i].location, 1, uniforms[i].value);
          break;
       case GL_FLOAT_VEC2:
-         glUniform2fv(uniforms[i].location, 1, uniforms[i].value);
+         Uniform2fv(uniforms[i].location, 1, uniforms[i].value);
          break;
       case GL_FLOAT_VEC3:
-         glUniform3fv(uniforms[i].location, 1, uniforms[i].value);
+         Uniform3fv(uniforms[i].location, 1, uniforms[i].value);
          break;
       case GL_FLOAT_VEC4:
-         glUniform4fv(uniforms[i].location, 1, uniforms[i].value);
+         Uniform4fv(uniforms[i].location, 1, uniforms[i].value);
          break;
       default:
          if (strncmp(uniforms[i].name, "gl_", 3) == 0) {
@@ -233,8 +294,8 @@ GetUniforms(GLuint program, struct uniform_info uniforms[])
 {
    GLint n, max, i;
 
-   glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
-   glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max);
+   GetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
+   GetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max);
 
    for (i = 0; i < n; i++) {
       GLint size, len;
@@ -283,20 +344,20 @@ GetAttribs(GLuint program, struct attrib_info attribs[])
 {
    GLint n, max, i;
 
-   glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
-   glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max);
+   GetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
+   GetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max);
 
    for (i = 0; i < n; i++) {
       GLint size, len;
       GLenum type;
       char name[100];
 
-      glGetActiveAttrib(program, i, 100, &len, &size, &type, name);
+      GetActiveAttrib(program, i, 100, &len, &size, &type, name);
 
       attribs[i].name = strdup(name);
       attribs[i].size = size;
       attribs[i].type = type;
-      attribs[i].location = glGetAttribLocation(program, name);
+      attribs[i].location = GetAttribLocation(program, name);
    }
 
    attribs[i].name = NULL; /* end of list */
diff --git a/src/util/shaderutil.h b/src/util/shaderutil.h
index 98c7181..9aad294 100644
--- a/src/util/shaderutil.h
+++ b/src/util/shaderutil.h
@@ -60,4 +60,27 @@ GetAttribs(GLuint program, struct attrib_info attribs[]);
 extern void
 PrintAttribs(const struct attrib_info attribs[]);
 
+/* These pointers are only valid after calling ShadersSupported.
+ */
+extern PFNGLCREATESHADERPROC CreateShader;
+extern PFNGLDELETESHADERPROC DeleteShader;
+extern PFNGLSHADERSOURCEPROC ShaderSource;
+extern PFNGLGETSHADERIVPROC GetShaderiv;
+extern PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+extern PFNGLCREATEPROGRAMPROC CreateProgram;
+extern PFNGLDELETEPROGRAMPROC DeleteProgram;
+extern PFNGLATTACHSHADERPROC AttachShader;
+extern PFNGLLINKPROGRAMPROC LinkProgram;
+extern PFNGLUSEPROGRAMPROC UseProgram;
+extern PFNGLGETPROGRAMIVPROC GetProgramiv;
+extern PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
+extern PFNGLVALIDATEPROGRAMARBPROC ValidateProgramARB;
+extern PFNGLUNIFORM1IPROC Uniform1i;
+extern PFNGLUNIFORM1FVPROC Uniform1fv;
+extern PFNGLUNIFORM2FVPROC Uniform2fv;
+extern PFNGLUNIFORM3FVPROC Uniform3fv;
+extern PFNGLUNIFORM4FVPROC Uniform4fv;
+extern PFNGLGETACTIVEATTRIBPROC GetActiveAttrib;
+extern PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
+
 #endif /* SHADER_UTIL_H */



More information about the mesa-commit mailing list