mesa: plug in GL_ARB_draw_buffers_blend functions
[mesa.git] / src / mesa / main / shaderapi.c
index 622285debb3edc982cb49348b0baf1a21c30ca72..2ffd8be0eb40aad83240989d83dc9d4c28022211 100644 (file)
@@ -41,6 +41,8 @@
 #include "main/dispatch.h"
 #include "main/enums.h"
 #include "main/hash.h"
+#include "main/mfeatures.h"
+#include "main/mtypes.h"
 #include "main/shaderapi.h"
 #include "main/shaderobj.h"
 #include "program/program.h"
@@ -48,6 +50,7 @@
 #include "program/prog_uniform.h"
 #include "talloc.h"
 #include <stdbool.h>
+#include "../glsl/glsl_parser_extras.h"
 
 /** Define this to enable shader substitution (see below) */
 #define SHADER_SUBST 0
@@ -95,7 +98,7 @@ _mesa_init_shader_state(struct gl_context *ctx)
     * are generated by the GLSL compiler.
     */
    struct gl_shader_compiler_options options;
-   GLuint i;
+   gl_shader_type sh;
 
    memset(&options, 0, sizeof(options));
    options.MaxUnrollIterations = 32;
@@ -103,8 +106,8 @@ _mesa_init_shader_state(struct gl_context *ctx)
    /* Default pragma settings */
    options.DefaultPragmas.Optimize = GL_TRUE;
 
-   for(i = 0; i < MESA_SHADER_TYPES; ++i)
-      memcpy(&ctx->ShaderCompilerOptions[i], &options, sizeof(options));
+   for (sh = 0; sh < MESA_SHADER_TYPES; ++sh)
+      memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
 
    ctx->Shader.Flags = get_shader_flags();
 }
@@ -936,9 +939,9 @@ print_shader_info(const struct gl_shader_program *shProg)
 /**
  * Use the named shader program for subsequent glUniform calls
  */
-static void
-active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
-              const char *caller)
+void
+_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
+                    const char *caller)
 {
    if ((shProg != NULL) && !shProg->LinkStatus) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -992,6 +995,7 @@ use_shader_program(struct gl_context *ctx, GLenum type,
    }
 
    if (*target != shProg) {
+      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
       _mesa_reference_shader_program(ctx, target, shProg);
       return true;
    }
@@ -1003,49 +1007,12 @@ use_shader_program(struct gl_context *ctx, GLenum type,
  * Use the named shader program for subsequent rendering.
  */
 void
-_mesa_use_program(struct gl_context *ctx, GLuint program)
+_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
 {
-   struct gl_shader_program *shProg;
-   struct gl_transform_feedback_object *obj =
-      ctx->TransformFeedback.CurrentObject;
-   bool changed = false;
-
-   if (obj->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glUseProgram(transform feedback active)");
-      return;
-   }
-
-   if (program) {
-      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
-      if (!shProg) {
-         return;
-      }
-      if (!shProg->LinkStatus) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glUseProgram(program %u not linked)", program);
-         return;
-      }
-
-      /* debug code */
-      if (ctx->Shader.Flags & GLSL_USE_PROG) {
-         print_shader_info(shProg);
-      }
-   }
-   else {
-      shProg = NULL;
-   }
-
-   changed = use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
-   changed = use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg)
-      || changed;
-   changed = use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg)
-      || changed;
-   active_program(ctx, shProg, "glUseProgram");
-
-   if (changed) {
-      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
-   }
+   use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
+   use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg);
+   use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg);
+   _mesa_active_program(ctx, shProg, "glUseProgram");
 
    if (ctx->Driver.UseProgram)
       ctx->Driver.UseProgram(ctx, shProg);
@@ -1614,8 +1581,37 @@ void GLAPIENTRY
 _mesa_UseProgramObjectARB(GLhandleARB program)
 {
    GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-   _mesa_use_program(ctx, program);
+   struct gl_shader_program *shProg;
+   struct gl_transform_feedback_object *obj =
+      ctx->TransformFeedback.CurrentObject;
+
+   if (obj->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glUseProgram(transform feedback active)");
+      return;
+   }
+
+   if (program) {
+      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
+      if (!shProg) {
+         return;
+      }
+      if (!shProg->LinkStatus) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glUseProgram(program %u not linked)", program);
+         return;
+      }
+
+      /* debug code */
+      if (ctx->Shader.Flags & GLSL_USE_PROG) {
+         print_shader_info(shProg);
+      }
+   }
+   else {
+      shProg = NULL;
+   }
+
+   _mesa_use_program(ctx, shProg);
 }
 
 
@@ -1644,8 +1640,7 @@ _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
 void GLAPIENTRY
 _mesa_ReleaseShaderCompiler(void)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+   _mesa_destroy_shader_compiler_caches();
 }
 
 
@@ -1731,12 +1726,21 @@ _mesa_ProgramParameteriARB(GLuint program, GLenum pname,
 
 #endif
 
+void
+_mesa_use_shader_program(struct gl_context *ctx, GLenum type,
+                        struct gl_shader_program *shProg)
+{
+   use_shader_program(ctx, type, shProg);
+
+   if (ctx->Driver.UseProgram)
+      ctx->Driver.UseProgram(ctx, shProg);
+}
+
 void GLAPIENTRY
 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg = NULL;
-   bool changed = false;
 
    if (!validate_shader_target(ctx, type)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
@@ -1762,13 +1766,7 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
       }
    }
 
-   changed = use_shader_program(ctx, type, shProg);
-   if (changed)
-      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
-
-   if (ctx->Driver.UseProgram)
-      ctx->Driver.UseProgram(ctx, shProg);
-   return;
+   _mesa_use_shader_program(ctx, type, shProg);
 }
 
 void GLAPIENTRY
@@ -1779,7 +1777,7 @@ _mesa_ActiveProgramEXT(GLuint program)
       ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
       : NULL;
 
-   active_program(ctx, shProg, "glActiveProgramEXT");
+   _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
    return;
 }
 
@@ -1885,6 +1883,9 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
    SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
    SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
 
+   /* GL_ARB_ES2_compatibility */
+   SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
+
 #endif /* FEATURE_GL */
 }