static const unsigned known_desktop_glsl_versions[] =
{ 110, 120, 130, 140, 150, 330, 400, 410, 420, 430, 440, 450 };
+static const unsigned known_desktop_gl_versions[] =
+ { 20, 21, 30, 31, 32, 33, 40, 41, 42, 43, 44, 45 };
_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->error = false;
this->loop_nesting_ast = NULL;
- this->struct_specifier_depth = 0;
-
this->uses_builtin_functions = false;
/* Set default language version and extensions */
this->language_version = 110;
this->forced_language_version = ctx->Const.ForceGLSLVersion;
+ this->zero_init = ctx->Const.GLSLZeroInit;
+ this->gl_version = 20;
this->es_shader = false;
this->ARB_texture_rectangle_enable = true;
this->extensions = &ctx->Extensions;
- this->ARB_compute_shader_enable = true;
-
this->Const.MaxLights = ctx->Const.MaxLights;
this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
this->Const.MaxTessEvaluationAtomicCounters = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicCounters;
this->Const.MaxGeometryAtomicCounters = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters;
this->Const.MaxFragmentAtomicCounters = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters;
+ this->Const.MaxComputeAtomicCounters = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters;
this->Const.MaxCombinedAtomicCounters = ctx->Const.MaxCombinedAtomicCounters;
this->Const.MaxAtomicBufferBindings = ctx->Const.MaxAtomicBufferBindings;
this->Const.MaxVertexAtomicCounterBuffers =
ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers;
this->Const.MaxFragmentAtomicCounterBuffers =
ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers;
+ this->Const.MaxComputeAtomicCounterBuffers =
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers;
this->Const.MaxCombinedAtomicCounterBuffers =
ctx->Const.MaxCombinedAtomicBuffers;
this->Const.MaxAtomicCounterBufferSize =
ctx->Const.MaxAtomicBufferSize;
+ /* ARB_enhanced_layouts constants */
+ this->Const.MaxTransformFeedbackBuffers = ctx->Const.MaxTransformFeedbackBuffers;
+ this->Const.MaxTransformFeedbackInterleavedComponents = ctx->Const.MaxTransformFeedbackInterleavedComponents;
+
/* Compute shader constants */
for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupCount); i++)
this->Const.MaxComputeWorkGroupCount[i] = ctx->Const.MaxComputeWorkGroupCount[i];
for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupSize); i++)
this->Const.MaxComputeWorkGroupSize[i] = ctx->Const.MaxComputeWorkGroupSize[i];
+ this->Const.MaxComputeTextureImageUnits = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
+ this->Const.MaxComputeUniformComponents = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents;
+
this->Const.MaxImageUnits = ctx->Const.MaxImageUnits;
this->Const.MaxCombinedShaderOutputResources = ctx->Const.MaxCombinedShaderOutputResources;
this->Const.MaxImageSamples = ctx->Const.MaxImageSamples;
this->Const.MaxTessEvaluationImageUniforms = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxImageUniforms;
this->Const.MaxGeometryImageUniforms = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms;
this->Const.MaxFragmentImageUniforms = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms;
+ this->Const.MaxComputeImageUniforms = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms;
this->Const.MaxCombinedImageUniforms = ctx->Const.MaxCombinedImageUniforms;
/* ARB_viewport_array */
this->Const.MaxTessControlUniformComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxUniformComponents;
this->Const.MaxTessEvaluationUniformComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxUniformComponents;
+ /* GL 4.5 / OES_sample_variables */
+ this->Const.MaxSamples = ctx->Const.MaxSamples;
+
this->current_function = NULL;
this->toplevel_ir = NULL;
this->found_return = false;
this->subroutine_types = NULL;
/* supported_versions should be large enough to support the known desktop
- * GLSL versions plus 3 GLES versions (ES 1.00, ES 3.00, and ES 3.10))
+ * GLSL versions plus 4 GLES versions (ES 1.00, ES 3.00, ES 3.10, ES 3.20)
*/
- STATIC_ASSERT((ARRAY_SIZE(known_desktop_glsl_versions) + 3) ==
+ STATIC_ASSERT((ARRAY_SIZE(known_desktop_glsl_versions) + 4) ==
ARRAY_SIZE(this->supported_versions));
/* Populate the list of supported GLSL versions */
if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) {
this->supported_versions[this->num_supported_versions].ver
= known_desktop_glsl_versions[i];
+ this->supported_versions[this->num_supported_versions].gl_ver
+ = known_desktop_gl_versions[i];
this->supported_versions[this->num_supported_versions].es = false;
this->num_supported_versions++;
}
}
if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) {
this->supported_versions[this->num_supported_versions].ver = 100;
+ this->supported_versions[this->num_supported_versions].gl_ver = 20;
this->supported_versions[this->num_supported_versions].es = true;
this->num_supported_versions++;
}
if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) {
this->supported_versions[this->num_supported_versions].ver = 300;
+ this->supported_versions[this->num_supported_versions].gl_ver = 30;
this->supported_versions[this->num_supported_versions].es = true;
this->num_supported_versions++;
}
- if (_mesa_is_gles31(ctx)) {
+ if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility) {
this->supported_versions[this->num_supported_versions].ver = 310;
+ this->supported_versions[this->num_supported_versions].gl_ver = 31;
+ this->supported_versions[this->num_supported_versions].es = true;
+ this->num_supported_versions++;
+ }
+ if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) ||
+ ctx->Extensions.ARB_ES3_2_compatibility) {
+ this->supported_versions[this->num_supported_versions].ver = 320;
+ this->supported_versions[this->num_supported_versions].gl_ver = 32;
this->supported_versions[this->num_supported_versions].es = true;
this->num_supported_versions++;
}
this->in_qualifier = new(this) ast_type_qualifier();
this->out_qualifier = new(this) ast_type_qualifier();
this->fs_early_fragment_tests = false;
+ this->fs_blend_support = 0;
memset(this->atomic_counter_offsets, 0,
sizeof(this->atomic_counter_offsets));
this->allow_extension_directive_midshader =
for (unsigned i = 0; i < this->num_supported_versions; i++) {
if (this->supported_versions[i].ver == this->language_version
&& this->supported_versions[i].es == this->es_shader) {
+ this->gl_version = this->supported_versions[i].gl_ver;
supported = true;
break;
}
*/
const char *name;
- /** True if this extension is available to desktop GL shaders */
- bool avail_in_GL;
-
- /** True if this extension is available to GLES shaders */
- bool avail_in_ES;
-
/**
- * Flag in the gl_extensions struct indicating whether this
- * extension is supported by the driver, or
- * &gl_extensions::dummy_true if supported by all drivers.
- *
- * Note: the type (GLboolean gl_extensions::*) is a "pointer to
- * member" type, the type-safe alternative to the "offsetof" macro.
- * In a nutshell:
- *
- * - foo bar::* p declares p to be an "offset" to a field of type
- * foo that exists within struct bar
- * - &bar::baz computes the "offset" of field baz within struct bar
- * - x.*p accesses the field of x that exists at "offset" p
- * - x->*p is equivalent to (*x).*p
+ * Predicate that checks whether the relevant extension is available for
+ * this context.
*/
- const GLboolean gl_extensions::* supported_flag;
+ bool (*available_pred)(const struct gl_context *,
+ gl_api api, uint8_t version);
/**
* Flag in the _mesa_glsl_parse_state struct that should be set
bool _mesa_glsl_parse_state::* warn_flag;
- bool compatible_with_state(const _mesa_glsl_parse_state *state) const;
+ bool compatible_with_state(const _mesa_glsl_parse_state *state,
+ gl_api api, uint8_t gl_version) const;
void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
};
-#define EXT(NAME, GL, ES, SUPPORTED_FLAG) \
- { "GL_" #NAME, GL, ES, &gl_extensions::SUPPORTED_FLAG, \
+/** Checks if the context supports a user-facing extension */
+#define EXT(name_str, driver_cap, ...) \
+static MAYBE_UNUSED bool \
+has_##name_str(const struct gl_context *ctx, gl_api api, uint8_t version) \
+{ \
+ return ctx->Extensions.driver_cap && (version >= \
+ _mesa_extension_table[MESA_EXTENSION_##name_str].version[api]); \
+}
+#include "main/extensions_table.h"
+#undef EXT
+
+#define EXT(NAME) \
+ { "GL_" #NAME, has_##NAME, \
&_mesa_glsl_parse_state::NAME##_enable, \
&_mesa_glsl_parse_state::NAME##_warn }
* and the conditions under which they are supported.
*/
static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
- /* API availability */
- /* name GL ES supported flag */
-
/* ARB extensions go here, sorted alphabetically.
*/
- EXT(ARB_arrays_of_arrays, true, false, ARB_arrays_of_arrays),
- EXT(ARB_compute_shader, true, false, ARB_compute_shader),
- EXT(ARB_conservative_depth, true, false, ARB_conservative_depth),
- EXT(ARB_derivative_control, true, false, ARB_derivative_control),
- EXT(ARB_draw_buffers, true, false, dummy_true),
- EXT(ARB_draw_instanced, true, false, ARB_draw_instanced),
- EXT(ARB_enhanced_layouts, true, false, ARB_enhanced_layouts),
- EXT(ARB_explicit_attrib_location, true, false, ARB_explicit_attrib_location),
- EXT(ARB_explicit_uniform_location, true, false, ARB_explicit_uniform_location),
- EXT(ARB_fragment_coord_conventions, true, false, ARB_fragment_coord_conventions),
- EXT(ARB_fragment_layer_viewport, true, false, ARB_fragment_layer_viewport),
- EXT(ARB_gpu_shader5, true, false, ARB_gpu_shader5),
- EXT(ARB_gpu_shader_fp64, true, false, ARB_gpu_shader_fp64),
- EXT(ARB_sample_shading, true, false, ARB_sample_shading),
- EXT(ARB_separate_shader_objects, true, false, dummy_true),
- EXT(ARB_shader_atomic_counters, true, false, ARB_shader_atomic_counters),
- EXT(ARB_shader_bit_encoding, true, false, ARB_shader_bit_encoding),
- EXT(ARB_shader_clock, true, false, ARB_shader_clock),
- EXT(ARB_shader_draw_parameters, true, false, ARB_shader_draw_parameters),
- EXT(ARB_shader_image_load_store, true, false, ARB_shader_image_load_store),
- EXT(ARB_shader_image_size, true, false, ARB_shader_image_size),
- EXT(ARB_shader_precision, true, false, ARB_shader_precision),
- EXT(ARB_shader_stencil_export, true, false, ARB_shader_stencil_export),
- EXT(ARB_shader_storage_buffer_object, true, true, ARB_shader_storage_buffer_object),
- EXT(ARB_shader_subroutine, true, false, ARB_shader_subroutine),
- EXT(ARB_shader_texture_image_samples, true, false, ARB_shader_texture_image_samples),
- EXT(ARB_shader_texture_lod, true, false, ARB_shader_texture_lod),
- EXT(ARB_shading_language_420pack, true, false, ARB_shading_language_420pack),
- EXT(ARB_shading_language_packing, true, false, ARB_shading_language_packing),
- EXT(ARB_tessellation_shader, true, false, ARB_tessellation_shader),
- EXT(ARB_texture_cube_map_array, true, false, ARB_texture_cube_map_array),
- EXT(ARB_texture_gather, true, false, ARB_texture_gather),
- EXT(ARB_texture_multisample, true, false, ARB_texture_multisample),
- EXT(ARB_texture_query_levels, true, false, ARB_texture_query_levels),
- EXT(ARB_texture_query_lod, true, false, ARB_texture_query_lod),
- EXT(ARB_texture_rectangle, true, false, dummy_true),
- EXT(ARB_uniform_buffer_object, true, false, ARB_uniform_buffer_object),
- EXT(ARB_vertex_attrib_64bit, true, false, ARB_vertex_attrib_64bit),
- EXT(ARB_viewport_array, true, false, ARB_viewport_array),
+ EXT(ARB_ES3_1_compatibility),
+ EXT(ARB_ES3_2_compatibility),
+ EXT(ARB_arrays_of_arrays),
+ EXT(ARB_compute_shader),
+ EXT(ARB_conservative_depth),
+ EXT(ARB_cull_distance),
+ EXT(ARB_derivative_control),
+ EXT(ARB_draw_buffers),
+ EXT(ARB_draw_instanced),
+ EXT(ARB_enhanced_layouts),
+ EXT(ARB_explicit_attrib_location),
+ EXT(ARB_explicit_uniform_location),
+ EXT(ARB_fragment_coord_conventions),
+ EXT(ARB_fragment_layer_viewport),
+ EXT(ARB_gpu_shader5),
+ EXT(ARB_gpu_shader_fp64),
+ EXT(ARB_sample_shading),
+ EXT(ARB_separate_shader_objects),
+ EXT(ARB_shader_atomic_counter_ops),
+ EXT(ARB_shader_atomic_counters),
+ EXT(ARB_shader_bit_encoding),
+ EXT(ARB_shader_clock),
+ EXT(ARB_shader_draw_parameters),
+ EXT(ARB_shader_group_vote),
+ EXT(ARB_shader_image_load_store),
+ EXT(ARB_shader_image_size),
+ EXT(ARB_shader_precision),
+ EXT(ARB_shader_stencil_export),
+ EXT(ARB_shader_storage_buffer_object),
+ EXT(ARB_shader_subroutine),
+ EXT(ARB_shader_texture_image_samples),
+ EXT(ARB_shader_texture_lod),
+ EXT(ARB_shading_language_420pack),
+ EXT(ARB_shading_language_packing),
+ EXT(ARB_tessellation_shader),
+ EXT(ARB_texture_cube_map_array),
+ EXT(ARB_texture_gather),
+ EXT(ARB_texture_multisample),
+ EXT(ARB_texture_query_levels),
+ EXT(ARB_texture_query_lod),
+ EXT(ARB_texture_rectangle),
+ EXT(ARB_uniform_buffer_object),
+ EXT(ARB_vertex_attrib_64bit),
+ EXT(ARB_viewport_array),
/* KHR extensions go here, sorted alphabetically.
*/
+ EXT(KHR_blend_equation_advanced),
/* OES extensions go here, sorted alphabetically.
*/
- EXT(OES_EGL_image_external, false, true, OES_EGL_image_external),
- EXT(OES_geometry_point_size, false, true, OES_geometry_shader),
- EXT(OES_geometry_shader, false, true, OES_geometry_shader),
- EXT(OES_standard_derivatives, false, true, OES_standard_derivatives),
- EXT(OES_texture_3D, false, true, dummy_true),
- EXT(OES_texture_storage_multisample_2d_array, false, true, ARB_texture_multisample),
+ EXT(OES_EGL_image_external),
+ EXT(OES_geometry_point_size),
+ EXT(OES_geometry_shader),
+ EXT(OES_gpu_shader5),
+ EXT(OES_sample_variables),
+ EXT(OES_shader_image_atomic),
+ EXT(OES_shader_io_blocks),
+ EXT(OES_shader_multisample_interpolation),
+ EXT(OES_standard_derivatives),
+ EXT(OES_tessellation_point_size),
+ EXT(OES_tessellation_shader),
+ EXT(OES_texture_3D),
+ EXT(OES_texture_buffer),
+ EXT(OES_texture_cube_map_array),
+ EXT(OES_texture_storage_multisample_2d_array),
/* All other extensions go here, sorted alphabetically.
*/
- EXT(AMD_conservative_depth, true, false, ARB_conservative_depth),
- EXT(AMD_shader_stencil_export, true, false, ARB_shader_stencil_export),
- EXT(AMD_shader_trinary_minmax, true, false, dummy_true),
- EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer),
- EXT(AMD_vertex_shader_viewport_index, true, false, AMD_vertex_shader_viewport_index),
- EXT(EXT_blend_func_extended, false, true, ARB_blend_func_extended),
- EXT(EXT_draw_buffers, false, true, dummy_true),
- EXT(EXT_separate_shader_objects, false, true, dummy_true),
- EXT(EXT_shader_integer_mix, true, true, EXT_shader_integer_mix),
- EXT(EXT_shader_samples_identical, true, true, EXT_shader_samples_identical),
- EXT(EXT_texture_array, true, false, EXT_texture_array),
+ EXT(AMD_conservative_depth),
+ EXT(AMD_shader_stencil_export),
+ EXT(AMD_shader_trinary_minmax),
+ EXT(AMD_vertex_shader_layer),
+ EXT(AMD_vertex_shader_viewport_index),
+ EXT(EXT_blend_func_extended),
+ EXT(EXT_draw_buffers),
+ EXT(EXT_clip_cull_distance),
+ EXT(EXT_geometry_point_size),
+ EXT(EXT_geometry_shader),
+ EXT(EXT_gpu_shader5),
+ EXT(EXT_separate_shader_objects),
+ EXT(EXT_shader_framebuffer_fetch),
+ EXT(EXT_shader_integer_mix),
+ EXT(EXT_shader_io_blocks),
+ EXT(EXT_shader_samples_identical),
+ EXT(EXT_tessellation_point_size),
+ EXT(EXT_tessellation_shader),
+ EXT(EXT_texture_array),
+ EXT(EXT_texture_buffer),
+ EXT(EXT_texture_cube_map_array),
+ EXT(MESA_shader_integer_functions),
};
#undef EXT
* Determine whether a given extension is compatible with the target,
* API, and extension information in the current parser state.
*/
-bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
- state) const
+bool _mesa_glsl_extension::compatible_with_state(
+ const _mesa_glsl_parse_state *state, gl_api api, uint8_t gl_version) const
{
- /* Check that this extension matches whether we are compiling
- * for desktop GL or GLES.
- */
- if (state->es_shader) {
- if (!this->avail_in_ES) return false;
- } else {
- if (!this->avail_in_GL) return false;
- }
-
- /* Check that this extension is supported by the OpenGL
- * implementation.
- *
- * Note: the ->* operator indexes into state->extensions by the
- * offset this->supported_flag. See
- * _mesa_glsl_extension::supported_flag for more info.
- */
- return state->extensions->*(this->supported_flag);
+ return this->available_pred(state->ctx, api, gl_version);
}
/**
const char *behavior_string, YYLTYPE *behavior_locp,
_mesa_glsl_parse_state *state)
{
+ uint8_t gl_version = state->ctx->Extensions.Version;
+ gl_api api = state->ctx->API;
ext_behavior behavior;
if (strcmp(behavior_string, "warn") == 0) {
behavior = extension_warn;
return false;
}
+ /* If we're in a desktop context but with an ES shader, use an ES API enum
+ * to verify extension availability.
+ */
+ if (state->es_shader && api != API_OPENGLES2)
+ api = API_OPENGLES2;
+ /* Use the language-version derived GL version to extension checks, unless
+ * we're using meta, which sets the version to the max.
+ */
+ if (gl_version != 0xff)
+ gl_version = state->gl_version;
+
if (strcmp(name, "all") == 0) {
if ((behavior == extension_enable) || (behavior == extension_require)) {
_mesa_glsl_error(name_locp, state, "cannot %s all extensions",
i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
const _mesa_glsl_extension *extension
= &_mesa_glsl_supported_extensions[i];
- if (extension->compatible_with_state(state)) {
+ if (extension->compatible_with_state(state, api, gl_version)) {
_mesa_glsl_supported_extensions[i].set_flags(state, behavior);
}
}
}
} else {
const _mesa_glsl_extension *extension = find_extension(name);
- if (extension && extension->compatible_with_state(state)) {
+ if (extension && extension->compatible_with_state(state, api, gl_version)) {
extension->set_flags(state, behavior);
} else {
static const char fmt[] = "extension `%s' unsupported in %s shader";
* E.g., if <type> if struct S[2] we want to set each element's type to
* struct S.
*/
- for (exec_node *expr_node = ai->expressions.head;
+ for (exec_node *expr_node = ai->expressions.get_head_raw();
!expr_node->is_tail_sentinel();
expr_node = expr_node->next) {
ast_expression *expr = exec_node_data(ast_expression, expr_node,
/* If the aggregate is a struct, recursively set its fields' types. */
} else if (type->is_record()) {
- exec_node *expr_node = ai->expressions.head;
+ exec_node *expr_node = ai->expressions.get_head_raw();
/* Iterate through the struct's fields. */
for (unsigned i = 0; !expr_node->is_tail_sentinel() && i < type->length;
}
/* If the aggregate is a matrix, set its columns' types. */
} else if (type->is_matrix()) {
- for (exec_node *expr_node = ai->expressions.head;
+ for (exec_node *expr_node = ai->expressions.get_head_raw();
!expr_node->is_tail_sentinel();
expr_node = expr_node->next) {
ast_expression *expr = exec_node_data(ast_expression, expr_node,
"required for defining uniform blocks");
}
} else {
- if (state->es_shader || state->language_version < 150) {
- _mesa_glsl_error(locp, state,
- "#version 150 required for using "
- "interface blocks");
+ if (!state->has_shader_io_blocks()) {
+ if (state->es_shader) {
+ _mesa_glsl_error(locp, state,
+ "GL_OES_shader_io_blocks or #version 320 "
+ "required for using interface blocks");
+ } else {
+ _mesa_glsl_error(locp, state,
+ "#version 150 required for using "
+ "interface blocks");
+ }
}
}
block->layout.flags.i |= block_interface_qualifier;
if (state->stage == MESA_SHADER_GEOMETRY &&
- state->has_explicit_attrib_stream()) {
+ state->has_explicit_attrib_stream() &&
+ block->layout.flags.q.out) {
/* Assign global layout's stream value. */
block->layout.flags.q.stream = 1;
block->layout.flags.q.explicit_stream = 0;
block->layout.stream = state->out_qualifier->stream;
}
+ if (state->has_enhanced_layouts() && block->layout.flags.q.out) {
+ /* Assign global layout's xfb_buffer value. */
+ block->layout.flags.q.xfb_buffer = 1;
+ block->layout.flags.q.explicit_xfb_buffer = 0;
+ block->layout.xfb_buffer = state->out_qualifier->xfb_buffer;
+ }
+
foreach_list_typed (ast_declarator_list, member, link, &block->declarations) {
ast_type_qualifier& qualifier = member->type->qualifier;
if ((qualifier.flags.i & interface_type_mask) == 0) {
"the interface block");
}
- /* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks":
- *
- * "GLSL ES 3.0 does not support interface blocks for shader inputs or
- * outputs."
- *
- * And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":.
- *
- * "Only variables output from a shader can be candidates for
- * invariance."
- *
- * From GLSL 4.40 and GLSL 1.50, section "Interface Blocks":
- *
- * "If optional qualifiers are used, they can include interpolation
- * qualifiers, auxiliary storage qualifiers, and storage qualifiers
- * and they must declare an input, output, or uniform member
- * consistent with the interface qualifier of the block"
- */
- if (qualifier.flags.q.invariant)
+ if (!(q.flags.q.in || q.flags.q.out) && qualifier.flags.q.invariant)
_mesa_glsl_error(locp, state,
- "invariant qualifiers cannot be used "
- "with interface blocks members");
+ "invariant qualifiers can be used only "
+ "in interface block members for shader "
+ "inputs or outputs");
}
}
this->subexpressions[1] = ex1;
this->subexpressions[2] = ex2;
this->non_lvalue_description = NULL;
+ this->is_lhs = false;
}
name = identifier;
this->declarations.push_degenerate_list_at_head(&declarator_list->link);
is_declaration = true;
+ layout = NULL;
}
void ast_subroutine_list::print(void) const
struct _mesa_glsl_parse_state *state)
{
/* Should have been prevented by the parser. */
- if (shader->Stage == MESA_SHADER_TESS_CTRL) {
+ if (shader->Stage == MESA_SHADER_TESS_CTRL ||
+ shader->Stage == MESA_SHADER_VERTEX) {
assert(!state->in_qualifier->flags.i);
- } else if (shader->Stage == MESA_SHADER_TESS_EVAL) {
- assert(!state->out_qualifier->flags.i);
- } else if (shader->Stage != MESA_SHADER_GEOMETRY) {
+ } else if (shader->Stage != MESA_SHADER_GEOMETRY &&
+ shader->Stage != MESA_SHADER_TESS_EVAL) {
assert(!state->in_qualifier->flags.i);
- assert(!state->out_qualifier->flags.i);
}
if (shader->Stage != MESA_SHADER_COMPUTE) {
assert(!state->fs_early_fragment_tests);
}
+ for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
+ if (state->out_qualifier->out_xfb_stride[i]) {
+ unsigned xfb_stride;
+ if (state->out_qualifier->out_xfb_stride[i]->
+ process_qualifier_constant(state, "xfb_stride", &xfb_stride,
+ true)) {
+ shader->info.TransformFeedback.BufferStride[i] = xfb_stride;
+ }
+ }
+ }
+
switch (shader->Stage) {
case MESA_SHADER_TESS_CTRL:
- shader->TessCtrl.VerticesOut = 0;
+ shader->info.TessCtrl.VerticesOut = 0;
if (state->tcs_output_vertices_specified) {
unsigned vertices;
if (state->out_qualifier->vertices->
_mesa_glsl_error(&loc, state, "vertices (%d) exceeds "
"GL_MAX_PATCH_VERTICES", vertices);
}
- shader->TessCtrl.VerticesOut = vertices;
+ shader->info.TessCtrl.VerticesOut = vertices;
}
}
break;
case MESA_SHADER_TESS_EVAL:
- shader->TessEval.PrimitiveMode = PRIM_UNKNOWN;
+ shader->info.TessEval.PrimitiveMode = PRIM_UNKNOWN;
if (state->in_qualifier->flags.q.prim_type)
- shader->TessEval.PrimitiveMode = state->in_qualifier->prim_type;
+ shader->info.TessEval.PrimitiveMode = state->in_qualifier->prim_type;
- shader->TessEval.Spacing = 0;
+ shader->info.TessEval.Spacing = 0;
if (state->in_qualifier->flags.q.vertex_spacing)
- shader->TessEval.Spacing = state->in_qualifier->vertex_spacing;
+ shader->info.TessEval.Spacing = state->in_qualifier->vertex_spacing;
- shader->TessEval.VertexOrder = 0;
+ shader->info.TessEval.VertexOrder = 0;
if (state->in_qualifier->flags.q.ordering)
- shader->TessEval.VertexOrder = state->in_qualifier->ordering;
+ shader->info.TessEval.VertexOrder = state->in_qualifier->ordering;
- shader->TessEval.PointMode = -1;
+ shader->info.TessEval.PointMode = -1;
if (state->in_qualifier->flags.q.point_mode)
- shader->TessEval.PointMode = state->in_qualifier->point_mode;
+ shader->info.TessEval.PointMode = state->in_qualifier->point_mode;
break;
case MESA_SHADER_GEOMETRY:
- shader->Geom.VerticesOut = 0;
+ shader->info.Geom.VerticesOut = -1;
if (state->out_qualifier->flags.q.max_vertices) {
unsigned qual_max_vertices;
if (state->out_qualifier->max_vertices->
process_qualifier_constant(state, "max_vertices",
- &qual_max_vertices, true)) {
- shader->Geom.VerticesOut = qual_max_vertices;
+ &qual_max_vertices, true, true)) {
+
+ if (qual_max_vertices > state->Const.MaxGeometryOutputVertices) {
+ YYLTYPE loc = state->out_qualifier->max_vertices->get_location();
+ _mesa_glsl_error(&loc, state,
+ "maximum output vertices (%d) exceeds "
+ "GL_MAX_GEOMETRY_OUTPUT_VERTICES",
+ qual_max_vertices);
+ }
+ shader->info.Geom.VerticesOut = qual_max_vertices;
}
}
if (state->gs_input_prim_type_specified) {
- shader->Geom.InputType = state->in_qualifier->prim_type;
+ shader->info.Geom.InputType = state->in_qualifier->prim_type;
} else {
- shader->Geom.InputType = PRIM_UNKNOWN;
+ shader->info.Geom.InputType = PRIM_UNKNOWN;
}
if (state->out_qualifier->flags.q.prim_type) {
- shader->Geom.OutputType = state->out_qualifier->prim_type;
+ shader->info.Geom.OutputType = state->out_qualifier->prim_type;
} else {
- shader->Geom.OutputType = PRIM_UNKNOWN;
+ shader->info.Geom.OutputType = PRIM_UNKNOWN;
}
- shader->Geom.Invocations = 0;
+ shader->info.Geom.Invocations = 0;
if (state->in_qualifier->flags.q.invocations) {
unsigned invocations;
if (state->in_qualifier->invocations->
"GL_MAX_GEOMETRY_SHADER_INVOCATIONS",
invocations);
}
- shader->Geom.Invocations = invocations;
+ shader->info.Geom.Invocations = invocations;
}
}
break;
case MESA_SHADER_COMPUTE:
if (state->cs_input_local_size_specified) {
for (int i = 0; i < 3; i++)
- shader->Comp.LocalSize[i] = state->cs_input_local_size[i];
+ shader->info.Comp.LocalSize[i] = state->cs_input_local_size[i];
} else {
for (int i = 0; i < 3; i++)
- shader->Comp.LocalSize[i] = 0;
+ shader->info.Comp.LocalSize[i] = 0;
}
break;
case MESA_SHADER_FRAGMENT:
- shader->redeclares_gl_fragcoord = state->fs_redeclares_gl_fragcoord;
- shader->uses_gl_fragcoord = state->fs_uses_gl_fragcoord;
- shader->pixel_center_integer = state->fs_pixel_center_integer;
- shader->origin_upper_left = state->fs_origin_upper_left;
- shader->ARB_fragment_coord_conventions_enable =
+ shader->info.redeclares_gl_fragcoord =
+ state->fs_redeclares_gl_fragcoord;
+ shader->info.uses_gl_fragcoord = state->fs_uses_gl_fragcoord;
+ shader->info.pixel_center_integer = state->fs_pixel_center_integer;
+ shader->info.origin_upper_left = state->fs_origin_upper_left;
+ shader->info.ARB_fragment_coord_conventions_enable =
state->ARB_fragment_coord_conventions_enable;
- shader->EarlyFragmentTests = state->fs_early_fragment_tests;
+ shader->info.EarlyFragmentTests = state->fs_early_fragment_tests;
+ shader->info.BlendSupport = state->fs_blend_support;
break;
default:
extern "C" {
+static void
+assign_subroutine_indexes(struct gl_shader *sh,
+ struct _mesa_glsl_parse_state *state)
+{
+ int j, k;
+ int index = 0;
+
+ for (j = 0; j < state->num_subroutines; j++) {
+ while (state->subroutines[j]->subroutine_index == -1) {
+ for (k = 0; k < state->num_subroutines; k++) {
+ if (state->subroutines[k]->subroutine_index == index)
+ break;
+ else if (k == state->num_subroutines - 1) {
+ state->subroutines[j]->subroutine_index = index;
+ }
+ }
+ index++;
+ }
+ }
+}
+
+static void
+add_builtin_defines(struct _mesa_glsl_parse_state *state,
+ void (*add_builtin_define)(struct glcpp_parser *, const char *, int),
+ struct glcpp_parser *data,
+ unsigned version,
+ bool es)
+{
+ unsigned gl_version = state->ctx->Extensions.Version;
+ gl_api api = state->ctx->API;
+
+ if (gl_version != 0xff) {
+ unsigned i;
+ for (i = 0; i < state->num_supported_versions; i++) {
+ if (state->supported_versions[i].ver == version &&
+ state->supported_versions[i].es == es) {
+ gl_version = state->supported_versions[i].gl_ver;
+ break;
+ }
+ }
+
+ if (i == state->num_supported_versions)
+ return;
+ }
+
+ if (es)
+ api = API_OPENGLES2;
+
+ for (unsigned i = 0;
+ i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
+ const _mesa_glsl_extension *extension
+ = &_mesa_glsl_supported_extensions[i];
+ if (extension->compatible_with_state(state, api, gl_version)) {
+ add_builtin_define(data, extension->name, 1);
+ }
+ }
+}
+
void
_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
bool dump_ast, bool dump_hir)
false, true);
state->error = glcpp_preprocess(state, &source, &state->info_log,
- &ctx->Extensions, ctx);
+ add_builtin_defines, state, ctx);
if (!state->error) {
_mesa_glsl_lexer_ctor(state, source);
struct gl_shader_compiler_options *options =
&ctx->Const.ShaderCompilerOptions[shader->Stage];
+ assign_subroutine_indexes(shader, state);
lower_subroutine(shader->ir, state);
/* Do some optimization at compile time to reduce shader IR size
* and reduce later work if the same shader is linked multiple times
shader->InfoLog = state->info_log;
shader->Version = state->language_version;
shader->IsES = state->es_shader;
- shader->uses_builtin_functions = state->uses_builtin_functions;
+ shader->info.uses_builtin_functions = state->uses_builtin_functions;
/* Retain any live IR, but trash the rest. */
reparent_ir(shader->ir, shader->ir);
}
}
- _mesa_glsl_initialize_derived_variables(shader);
+ _mesa_glsl_initialize_derived_variables(ctx, shader);
delete state->symbols;
ralloc_free(state);
OPT(do_dead_functions, ir);
OPT(do_structure_splitting, ir);
}
+ propagate_invariance(ir);
OPT(do_if_simplification, ir);
OPT(opt_flatten_nested_if_blocks, ir);
OPT(opt_conditional_discard, ir);