mesa: combined PBO validate/map helpers
[mesa.git] / src / mesa / main / shaders.c
index 5bd4a3f5ff55fe726b9b7e6a26c2820e0ac0e7ad..bc76b912913a08083294f7b3917c5112eec70a83 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.3
  *
- * Copyright (C) 2004-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -83,7 +83,7 @@ _mesa_CreateShader(GLenum type)
 }
 
 
-GLhandleARB APIENTRY
+GLhandleARB GLAPIENTRY
 _mesa_CreateShaderObjectARB(GLenum type)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -99,7 +99,7 @@ _mesa_CreateProgram(void)
 }
 
 
-GLhandleARB APIENTRY
+GLhandleARB GLAPIENTRY
 _mesa_CreateProgramObjectARB(void)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -110,15 +110,17 @@ _mesa_CreateProgramObjectARB(void)
 void GLAPIENTRY
 _mesa_DeleteObjectARB(GLhandleARB obj)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   if (ctx->Driver.IsProgram(ctx, obj)) {
-      ctx->Driver.DeleteProgram2(ctx, obj);
-   }
-   else if (ctx->Driver.IsShader(ctx, obj)) {
-      ctx->Driver.DeleteShader(ctx, obj);
-   }
-   else {
-      /* error? */
+   if (obj) {
+      GET_CURRENT_CONTEXT(ctx);
+      if (ctx->Driver.IsProgram(ctx, obj)) {
+         ctx->Driver.DeleteProgram2(ctx, obj);
+      }
+      else if (ctx->Driver.IsShader(ctx, obj)) {
+         ctx->Driver.DeleteShader(ctx, obj);
+      }
+      else {
+         /* error? */
+      }
    }
 }
 
@@ -126,16 +128,20 @@ _mesa_DeleteObjectARB(GLhandleARB obj)
 void GLAPIENTRY
 _mesa_DeleteProgram(GLuint name)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.DeleteProgram2(ctx, name);
+   if (name) {
+      GET_CURRENT_CONTEXT(ctx);
+      ctx->Driver.DeleteProgram2(ctx, name);
+   }
 }
 
 
 void GLAPIENTRY
 _mesa_DeleteShader(GLuint name)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.DeleteShader(ctx, name);
+   if (name) {
+      GET_CURRENT_CONTEXT(ctx);
+      ctx->Driver.DeleteShader(ctx, name);
+   }
 }
 
 
@@ -227,13 +233,23 @@ _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
    GET_CURRENT_CONTEXT(ctx);
    /* Implement in terms of GetProgramiv, GetShaderiv */
    if (ctx->Driver.IsProgram(ctx, object)) {
-      ctx->Driver.GetProgramiv(ctx, object, pname, params);
+      if (pname == GL_OBJECT_TYPE_ARB) {
+        *params = GL_PROGRAM_OBJECT_ARB;
+      }
+      else {
+        ctx->Driver.GetProgramiv(ctx, object, pname, params);
+      }
    }
    else if (ctx->Driver.IsShader(ctx, object)) {
-      ctx->Driver.GetShaderiv(ctx, object, pname, params);
+      if (pname == GL_OBJECT_TYPE_ARB) {
+        *params = GL_SHADER_OBJECT_ARB;
+      }
+      else {
+        ctx->Driver.GetShaderiv(ctx, object, pname, params);
+      }
    }
    else {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
    }
 }
 
@@ -303,17 +319,13 @@ void GLAPIENTRY
 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLfloat fparams[16]; /* XXX is 16 enough? */
-   GLuint i;
-   ctx->Driver.GetUniformfv(ctx, program, location, fparams);
-   for (i = 0; i < 16; i++)
-      params[i] = (GLint) fparams[i];  /* XXX correct? */
+   ctx->Driver.GetUniformiv(ctx, program, location, params);
 }
 
 
 
 #if 0
-GLint APIENTRY
+GLint GLAPIENTRY
 _mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -330,7 +342,7 @@ _mesa_GetHandleARB(GLenum pname)
 }
 
 
-GLint APIENTRY
+GLint GLAPIENTRY
 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -362,6 +374,43 @@ _mesa_LinkProgramARB(GLhandleARB programObj)
 }
 
 
+
+/**
+ * Read shader source code from a file.
+ * Useful for debugging to override an app's shader.
+ */
+static GLcharARB *
+_mesa_read_shader(const char *fname)
+{
+   const int max = 50*1000;
+   FILE *f = fopen(fname, "r");
+   GLcharARB *buffer, *shader;
+   int len;
+
+   if (!f) {
+      _mesa_fprintf(stderr, "Unable to open shader file %s\n", fname);
+      return NULL;
+   }
+
+   buffer = (char *) malloc(max);
+   len = fread(buffer, 1, max, f);
+   buffer[len] = 0;
+
+   fclose(f);
+
+   shader = _mesa_strdup(buffer);
+   free(buffer);
+
+   if (0) {
+      _mesa_fprintf(stderr, "Read shader %s:\n", fname);
+      _mesa_fprintf(stderr, "%s\n", shader);
+   }
+
+   return shader;
+}
+
+
+
 /**
  * Called via glShaderSource() and glShaderSourceARB() API functions.
  * Basically, concatenate the source code strings into one long string
@@ -373,10 +422,10 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
 {
    GET_CURRENT_CONTEXT(ctx);
    GLint *offsets;
-   GLsizei i;
+   GLsizei i, totalLength;
    GLcharARB *source;
 
-   if (string == NULL) {
+   if (!shaderObj || string == NULL) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
       return;
    }
@@ -394,7 +443,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
    for (i = 0; i < count; i++) {
       if (string[i] == NULL) {
          _mesa_free((GLvoid *) offsets);
-         _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)");
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
          return;
       }
       if (length == NULL || length[i] < 0)
@@ -406,8 +455,12 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
          offsets[i] += offsets[i - 1];
    }
 
-   source = (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) *
-                                       sizeof(GLcharARB));
+   /* Total length of source string is sum off all strings plus two.
+    * One extra byte for terminating zero, another extra byte to silence
+    * valgrind warnings in the parser/grammer code.
+    */
+   totalLength = offsets[count - 1] + 2;
+   source = (GLcharARB *) _mesa_malloc(totalLength * sizeof(GLcharARB));
    if (source == NULL) {
       _mesa_free((GLvoid *) offsets);
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
@@ -419,7 +472,22 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
       _mesa_memcpy(source + start, string[i],
                    (offsets[i] - start) * sizeof(GLcharARB));
    }
-   source[offsets[count - 1]] = '\0';
+   source[totalLength - 1] = '\0';
+   source[totalLength - 2] = '\0';
+
+#if 0
+   if (0) {
+      GLcharARB *newSource;
+
+      newSource = _mesa_read_shader("newshader.frag");
+      if (newSource) {
+         _mesa_free(source);
+         source = newSource;
+      }
+   }
+#else
+   (void) _mesa_read_shader;
+#endif
 
    ctx->Driver.ShaderSource(ctx, shaderObj, source);
 
@@ -570,8 +638,7 @@ _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 2, GL_FLOAT_MAT2,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -579,8 +646,7 @@ _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 3, GL_FLOAT_MAT3,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -588,8 +654,7 @@ _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
                           const GLfloat * value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 4, GL_FLOAT_MAT4,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 4, 4, location, count, transpose, value);
 }
 
 
@@ -601,8 +666,7 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 3, GL_FLOAT_MAT2x3,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -610,8 +674,7 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 2, GL_FLOAT_MAT3x2,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -619,8 +682,7 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 4, GL_FLOAT_MAT2x4,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -628,8 +690,7 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 2, GL_FLOAT_MAT4x2,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -637,8 +698,7 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 4, GL_FLOAT_MAT3x4,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
 }
 
 void GLAPIENTRY
@@ -646,8 +706,7 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
                          const GLfloat *value)
 {
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 3, GL_FLOAT_MAT4x3,
-                             location, count, transpose, value);
+   ctx->Driver.UniformMatrix(ctx, 4, 3, location, count, transpose, value);
 }