#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"
#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
* 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;
/* 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();
}
/**
* 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,
}
if (*target != shProg) {
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
_mesa_reference_shader_program(ctx, target, shProg);
return true;
}
* 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);
_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);
}
void GLAPIENTRY
_mesa_ReleaseShaderCompiler(void)
{
- GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+ _mesa_destroy_shader_compiler_caches();
}
#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)");
}
}
- 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
? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
: NULL;
- active_program(ctx, shProg, "glActiveProgramEXT");
+ _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
return;
}
SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
+ /* GL_ARB_ES2_compatibility */
+ SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
+
#endif /* FEATURE_GL */
}