Merge branch 'mesa_7_6_branch' into mesa_7_7_branch
[mesa.git] / progs / util / shaderutil.c
index 489e71cc30cb4ee9eddee4b4baa5b297f56ba69d..2f44c388d8a3b7769851de09d6be8bd546ca32e3 100644 (file)
 #include <GL/glut.h>
 #include "shaderutil.h"
 
+/** time to compile previous shader */
+static GLdouble CompileTime = 0.0;
+
+/** time to linke previous program */
+static GLdouble LinkTime = 0.0;
+
 
 GLboolean
 ShadersSupported(void)
 {
    const char *version = (const char *) glGetString(GL_VERSION);
-   if (version[0] == '2' && version[1] == '.') {
+
+   /* NVIDIA binary drivers will return "3.0.0", and they clearly support
+    * shaders.
+    */
+   if (version[0] >= '2' && version[1] == '.') {
       return GL_TRUE;
    }
    else if (glutExtensionSupported("GL_ARB_vertex_shader")
@@ -28,7 +38,8 @@ ShadersSupported(void)
       fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x.  This may not work.\n");
       return GL_TRUE;
    }
-   return GL_TRUE;
+   fprintf(stderr, "Sorry, GLSL not supported with this OpenGL.\n");
+   return GL_FALSE;
 }
 
 
@@ -37,10 +48,17 @@ CompileShaderText(GLenum shaderType, const char *text)
 {
    GLuint shader;
    GLint stat;
+   GLdouble t0, t1;
 
    shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, (const GLchar **) &text, NULL);
+
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
    glCompileShader(shader);
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+   CompileTime = t1 - t0;
+
    glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
    if (!stat) {
       GLchar log[1000];
@@ -71,6 +89,7 @@ CompileShaderFile(GLenum shaderType, const char *filename)
    f = fopen(filename, "r");
    if (!f) {
       fprintf(stderr, "Unable to open shader file %s\n", filename);
+      free(buffer);
       return 0;
    }
 
@@ -81,6 +100,8 @@ CompileShaderFile(GLenum shaderType, const char *filename)
       shader = CompileShaderText(shaderType, buffer);
    }
    else {
+      fclose(f);
+      free(buffer);
       return 0;
    }
 
@@ -95,6 +116,7 @@ GLuint
 LinkShaders(GLuint vertShader, GLuint fragShader)
 {
    GLuint program = glCreateProgram();
+   GLdouble t0, t1;
 
    assert(vertShader || fragShader);
 
@@ -102,7 +124,12 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
       glAttachShader(program, fragShader);
    if (vertShader)
       glAttachShader(program, vertShader);
+
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
    glLinkProgram(program);
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+   LinkTime = t1 - t0;
 
    /* check link */
    {
@@ -121,6 +148,39 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
 }
 
 
+GLboolean
+ValidateShaderProgram(GLuint program)
+{
+   GLint stat;
+   glValidateProgramARB(program);
+   glGetProgramiv(program, GL_VALIDATE_STATUS, &stat);
+
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetProgramInfoLog(program, 1000, &len, log);
+      fprintf(stderr, "Program validation error:\n%s\n", log);
+      return 0;
+   }
+
+   return (GLboolean) stat;
+}
+
+
+GLdouble
+GetShaderCompileTime(void)
+{
+   return CompileTime;
+}
+
+
+GLdouble
+GetShaderLinkTime(void)
+{
+   return LinkTime;
+}
+
+
 void
 SetUniformValues(GLuint program, struct uniform_info uniforms[])
 {
@@ -137,6 +197,7 @@ SetUniformValues(GLuint program, struct uniform_info uniforms[])
       case GL_SAMPLER_3D:
       case GL_SAMPLER_CUBE:
       case GL_SAMPLER_2D_RECT_ARB:
+         assert(uniforms[i].value[0] >= 0.0F);
          glUniform1i(uniforms[i].location,
                      (GLint) uniforms[i].value[0]);
          break;