#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"
#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
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;
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;
}
/* 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?
*/
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 */
/* 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);
}
- 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);
+ }
}
}
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;
}
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;
}
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;
}
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;
}
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;
+ }
+}