mesa: Remove some remaining FEATURE_* detritus.
[mesa.git] / src / mesa / main / shaderapi.c
index d214204a60a3e21e22ffae701699e78c7b303079..4c0484aaf0c9253eb13de5624a50d7425e633b75 100644 (file)
@@ -42,6 +42,7 @@
 #include "main/dispatch.h"
 #include "main/enums.h"
 #include "main/hash.h"
+#include "main/hash_table.h"
 #include "main/mtypes.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
@@ -55,6 +56,7 @@
 #include "../glsl/glsl_parser_extras.h"
 #include "../glsl/ir.h"
 #include "../glsl/ir_uniform.h"
+#include "../glsl/program.h"
 
 /** Define this to enable shader substitution (see below) */
 #define SHADER_SUBST 0
@@ -70,7 +72,9 @@ get_shader_flags(void)
    const char *env = _mesa_getenv("MESA_GLSL");
 
    if (env) {
-      if (strstr(env, "dump"))
+      if (strstr(env, "dump_on_error"))
+         flags |= GLSL_DUMP_ON_ERROR;
+      else if (strstr(env, "dump"))
          flags |= GLSL_DUMP;
       if (strstr(env, "log"))
          flags |= GLSL_LOG;
@@ -176,7 +180,7 @@ validate_shader_target(const struct gl_context *ctx, GLenum type)
    case GL_VERTEX_SHADER:
       return ctx->Extensions.ARB_vertex_shader;
    case GL_GEOMETRY_SHADER_ARB:
-      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+      return _mesa_has_geometry_shaders(ctx);
    default:
       return false;
    }
@@ -475,8 +479,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
 
    /* Are geometry shaders available in this context?
     */
-   const bool has_gs =
-      _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+   const bool has_gs = _mesa_has_geometry_shaders(ctx);
 
    /* Are uniform buffer objects available in this context?
     */
@@ -740,6 +743,12 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
    if (!sh)
       return;
 
+   /* Geometry shaders are not yet fully supported, so issue a warning message
+    * if we're compiling one.
+    */
+   if (sh->Type == GL_GEOMETRY_SHADER)
+      printf("WARNING: Geometry shader support is currently experimental.\n");
+
    options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
 
    /* set default pragma state for shader */
@@ -760,7 +769,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
       /* this call will set the shader->CompileStatus field to indicate if
        * compilation was successful.
        */
-      _mesa_glsl_compile_shader(ctx, sh);
+      _mesa_glsl_compile_shader(ctx, sh, false, false);
 
       if (ctx->Shader.Flags & GLSL_LOG) {
          _mesa_write_shader_to_file(sh);
@@ -782,10 +791,17 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
 
    }
 
-   if (sh->CompileStatus == GL_FALSE && 
-       (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
-      _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
-                  sh->Name, sh->InfoLog);
+   if (!sh->CompileStatus) {
+      if (ctx->Shader.Flags & GLSL_DUMP_ON_ERROR) {
+         fprintf(stderr, "GLSL source for %s shader %d:\n",
+                 _mesa_glsl_shader_target_name(sh->Type), sh->Name);
+         fprintf(stderr, "%s\n", sh->Source);
+      }
+
+      if (ctx->Shader.Flags & GLSL_REPORT_ERRORS) {
+         _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
+                     sh->Name, sh->InfoLog);
+      }
    }
 }
 
@@ -797,19 +813,19 @@ static void
 link_program(struct gl_context *ctx, GLuint program)
 {
    struct gl_shader_program *shProg;
-   struct gl_transform_feedback_object *obj =
-      ctx->TransformFeedback.CurrentObject;
 
    shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
    if (!shProg)
       return;
 
-   if (obj->Active
-       && (shProg == ctx->Shader.CurrentVertexProgram
-          || shProg == ctx->Shader.CurrentGeometryProgram
-          || shProg == ctx->Shader.CurrentFragmentProgram)) {
+   /* From the ARB_transform_feedback2 specification:
+    * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
+    *  the name of a program being used by one or more transform feedback
+    *  objects, even if the objects are not currently bound or are paused."
+    */
+   if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLinkProgram(transform feedback active)");
+                  "glLinkProgram(transform feedback is using the program)");
       return;
    }
 
@@ -1625,10 +1641,10 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
       if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
          break;
 
-      if (value < 1 ||
+      if (value < 0 ||
           (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
          _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
+                     "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d)",
                      value);
          return;
       }
@@ -1648,7 +1664,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
          break;
       default:
          _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glProgramParameteri(geometry input type = %s",
+                     "glProgramParameteri(geometry input type = %s)",
                      _mesa_lookup_enum_by_nr(value));
          return;
       }
@@ -1665,7 +1681,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
          break;
       default:
          _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glProgramParameteri(geometry output type = %s",
+                     "glProgramParameteri(geometry output type = %s)",
                      _mesa_lookup_enum_by_nr(value));
          return;
       }
@@ -1833,3 +1849,34 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
 
    return program;
 }
+
+
+/**
+ * Copy program-specific data generated by linking from the gl_shader_program
+ * object to a specific gl_program object.
+ */
+void
+_mesa_copy_linked_program_data(gl_shader_type type,
+                               const struct gl_shader_program *src,
+                               struct gl_program *dst)
+{
+   switch (type) {
+   case MESA_SHADER_VERTEX: {
+      struct gl_vertex_program *dst_vp = (struct gl_vertex_program *) dst;
+      dst_vp->UsesClipDistance = src->Vert.UsesClipDistance;
+   }
+      break;
+   case MESA_SHADER_GEOMETRY: {
+      struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
+      dst_gp->VerticesIn = src->Geom.VerticesIn;
+      dst_gp->VerticesOut = src->Geom.VerticesOut;
+      dst_gp->InputType = src->Geom.InputType;
+      dst_gp->OutputType = src->Geom.OutputType;
+      dst_gp->UsesClipDistance = src->Geom.UsesClipDistance;
+      dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
+   }
+      break;
+   default:
+      break;
+   }
+}