*/
struct gl_shader_compiler_options options;
gl_shader_stage sh;
+ int i;
memset(&options, 0, sizeof(options));
options.MaxUnrollIterations = 32;
options.MaxIfDepth = UINT_MAX;
- /* Default pragma settings */
- options.DefaultPragmas.Optimize = GL_TRUE;
-
for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options));
/* Extended for ARB_separate_shader_objects */
ctx->Shader.RefCount = 1;
mtx_init(&ctx->Shader.Mutex, mtx_plain);
+
+ ctx->TessCtrlProgram.patch_vertices = 3;
+ for (i = 0; i < 4; ++i)
+ ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
+ for (i = 0; i < 2; ++i)
+ ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0;
}
return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
case GL_GEOMETRY_SHADER_ARB:
return ctx == NULL || _mesa_has_geometry_shaders(ctx);
+ case GL_TESS_CONTROL_SHADER:
+ case GL_TESS_EVALUATION_SHADER:
+ return ctx == NULL || _mesa_has_tessellation(ctx);
case GL_COMPUTE_SHADER:
return ctx == NULL || ctx->Extensions.ARB_compute_shader;
default:
/* sanity check - make sure the new list's entries are sensible */
for (j = 0; j < shProg->NumShaders; j++) {
assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
+ shProg->Shaders[j]->Type == GL_TESS_CONTROL_SHADER ||
+ shProg->Shaders[j]->Type == GL_TESS_EVALUATION_SHADER ||
shProg->Shaders[j]->Type == GL_GEOMETRY_SHADER ||
shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
assert(shProg->Shaders[j]->RefCount > 0);
}
+/**
+ * Check if a tessellation control shader query is valid at this time.
+ * If not, report an error and return false.
+ *
+ * From GL 4.0 section 6.1.12 (Shader and Program Queries):
+ *
+ * "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
+ * not been linked successfully, or which does not contain objects to
+ * form a tessellation control shader, then an INVALID_OPERATION error is
+ * generated."
+ */
+static bool
+check_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
+{
+ if (shProg->LinkStatus &&
+ shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) {
+ return true;
+ }
+
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramv(linked tessellation control shader required)");
+ return false;
+}
+
+
+/**
+ * Check if a tessellation evaluation shader query is valid at this time.
+ * If not, report an error and return false.
+ *
+ * From GL 4.0 section 6.1.12 (Shader and Program Queries):
+ *
+ * "If any of the pname values in this paragraph are queried for a program
+ * which has not been linked successfully, or which does not contain
+ * objects to form a tessellation evaluation shader, then an
+ * INVALID_OPERATION error is generated."
+ *
+ */
+static bool
+check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
+{
+ if (shProg->LinkStatus &&
+ shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) {
+ return true;
+ }
+
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation "
+ "evaluation shader required)");
+ return false;
+}
+
+
/**
* glGetProgramiv() - get shader program state.
* Note that this is for GLSL shader programs, not ARB vertex/fragment
/* True if geometry shaders (of the form that was adopted into GLSL 1.50
* and GL 3.2) are available in this context
*/
- const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;
+ const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
+ const bool has_tess = _mesa_has_tessellation(ctx);
/* Are uniform buffer objects available in this context?
*/
*params = _mesa_longest_attribute_name_length(shProg);
return;
case GL_ACTIVE_UNIFORMS:
- *params = shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
+ *params = shProg->NumUniformStorage - shProg->NumHiddenUniforms;
return;
case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
unsigned i;
GLint max_len = 0;
const unsigned num_uniforms =
- shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
+ shProg->NumUniformStorage - shProg->NumHiddenUniforms;
for (i = 0; i < num_uniforms; i++) {
/* Add one for the terminating NUL character for a non-array, and
case GL_PROGRAM_SEPARABLE:
*params = shProg->SeparateShader;
return;
+
+ /* ARB_tessellation_shader */
+ case GL_TESS_CONTROL_OUTPUT_VERTICES:
+ if (!has_tess)
+ break;
+ if (check_tcs_query(ctx, shProg))
+ *params = shProg->TessCtrl.VerticesOut;
+ return;
+ case GL_TESS_GEN_MODE:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.PrimitiveMode;
+ return;
+ case GL_TESS_GEN_SPACING:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.Spacing;
+ return;
+ case GL_TESS_GEN_VERTEX_ORDER:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.VertexOrder;
+ return;
+ case GL_TESS_GEN_POINT_MODE:
+ if (!has_tess)
+ break;
+ if (check_tes_query(ctx, shProg))
+ *params = shProg->TessEval.PointMode;
+ return;
default:
break;
}
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
}
compile_shader(struct gl_context *ctx, GLuint shaderObj)
{
struct gl_shader *sh;
- struct gl_shader_compiler_options *options;
sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
if (!sh)
return;
- options = &ctx->Const.ShaderCompilerOptions[sh->Stage];
-
- /* set default pragma state for shader */
- sh->Pragmas = options->DefaultPragmas;
-
if (!sh->Source) {
/* If the user called glCompileShader without first calling
* glShaderSource, we should fail to compile, but not raise a GL_ERROR.
if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
printf(" geom prog %u\n",
shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
+ if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL])
+ printf(" tesc prog %u\n",
+ shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id);
+ if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL])
+ printf(" tese prog %u\n",
+ shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id);
}
{
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
+ _mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type));
return create_shader(ctx, type);
}
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
- _mesa_lookup_enum_by_nr(pname));
+ _mesa_enum_to_string(pname));
return;
}
_mesa_error(ctx, GL_INVALID_VALUE,
"glProgramParameteri(pname=%s, value=%d): "
"value must be 0 or 1.",
- _mesa_lookup_enum_by_nr(pname),
+ _mesa_enum_to_string(pname),
value);
}
case MESA_SHADER_VERTEX:
dst->UsesClipDistanceOut = src->Vert.UsesClipDistance;
break;
+ case MESA_SHADER_TESS_CTRL: {
+ struct gl_tess_ctrl_program *dst_tcp =
+ (struct gl_tess_ctrl_program *) dst;
+ dst_tcp->VerticesOut = src->TessCtrl.VerticesOut;
+ break;
+ }
+ case MESA_SHADER_TESS_EVAL: {
+ struct gl_tess_eval_program *dst_tep =
+ (struct gl_tess_eval_program *) dst;
+ dst_tep->PrimitiveMode = src->TessEval.PrimitiveMode;
+ dst_tep->Spacing = src->TessEval.Spacing;
+ dst_tep->VertexOrder = src->TessEval.VertexOrder;
+ dst_tep->PointMode = src->TessEval.PointMode;
+ break;
+ }
case MESA_SHADER_GEOMETRY: {
struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
dst_gp->VerticesIn = src->Geom.VerticesIn;
return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
}
+
+
+/**
+ * For GL_ARB_tessellation_shader
+ */
+extern void GLAPIENTRY
+_mesa_PatchParameteri(GLenum pname, GLint value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_has_tessellation(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameteri");
+ return;
+ }
+
+ if (pname != GL_PATCH_VERTICES) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameteri");
+ return;
+ }
+
+ if (value <= 0 || value > ctx->Const.MaxPatchVertices) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glPatchParameteri");
+ return;
+ }
+
+ ctx->TessCtrlProgram.patch_vertices = value;
+}
+
+
+extern void GLAPIENTRY
+_mesa_PatchParameterfv(GLenum pname, const GLfloat *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_has_tessellation(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameterfv");
+ return;
+ }
+
+ switch(pname) {
+ case GL_PATCH_DEFAULT_OUTER_LEVEL:
+ FLUSH_VERTICES(ctx, 0);
+ memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values,
+ 4 * sizeof(GLfloat));
+ ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
+ return;
+ case GL_PATCH_DEFAULT_INNER_LEVEL:
+ FLUSH_VERTICES(ctx, 0);
+ memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values,
+ 2 * sizeof(GLfloat));
+ ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
+ return;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv");
+ return;
+ }
+}
+