- any_identifier
- {
- memset(& $$, 0, sizeof($$));
-
- /* Layout qualifiers for ARB_fragment_coord_conventions. */
- if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) {
- if (strcmp($1, "origin_upper_left") == 0) {
- $$.flags.q.origin_upper_left = 1;
- } else if (strcmp($1, "pixel_center_integer") == 0) {
- $$.flags.q.pixel_center_integer = 1;
- }
-
- if ($$.flags.i && state->ARB_fragment_coord_conventions_warn) {
- _mesa_glsl_warning(& @1, state,
- "GL_ARB_fragment_coord_conventions layout "
- "identifier `%s' used\n", $1);
- }
- }
-
- /* Layout qualifiers for AMD/ARB_conservative_depth. */
- if (!$$.flags.i &&
- (state->AMD_conservative_depth_enable ||
- state->ARB_conservative_depth_enable)) {
- if (strcmp($1, "depth_any") == 0) {
- $$.flags.q.depth_any = 1;
- } else if (strcmp($1, "depth_greater") == 0) {
- $$.flags.q.depth_greater = 1;
- } else if (strcmp($1, "depth_less") == 0) {
- $$.flags.q.depth_less = 1;
- } else if (strcmp($1, "depth_unchanged") == 0) {
- $$.flags.q.depth_unchanged = 1;
- }
-
- if ($$.flags.i && state->AMD_conservative_depth_warn) {
- _mesa_glsl_warning(& @1, state,
- "GL_AMD_conservative_depth "
- "layout qualifier `%s' is used\n", $1);
- }
- if ($$.flags.i && state->ARB_conservative_depth_warn) {
- _mesa_glsl_warning(& @1, state,
- "GL_ARB_conservative_depth "
- "layout qualifier `%s' is used\n", $1);
- }
- }
-
- /* See also interface_block_layout_qualifier. */
- if (!$$.flags.i && state->ARB_uniform_buffer_object_enable) {
- if (strcmp($1, "std140") == 0) {
- $$.flags.q.std140 = 1;
- } else if (strcmp($1, "shared") == 0) {
- $$.flags.q.shared = 1;
- } else if (strcmp($1, "column_major") == 0) {
- $$.flags.q.column_major = 1;
- /* "row_major" is a reserved word in GLSL 1.30+. Its token is parsed
- * below in the interface_block_layout_qualifier rule.
- *
- * It is not a reserved word in GLSL ES 3.00, so it's handled here as
- * an identifier.
- */
- } else if (strcmp($1, "row_major") == 0) {
- $$.flags.q.row_major = 1;
- }
-
- if ($$.flags.i && state->ARB_uniform_buffer_object_warn) {
- _mesa_glsl_warning(& @1, state,
- "#version 140 / GL_ARB_uniform_buffer_object "
- "layout qualifier `%s' is used\n", $1);
- }
- }
-
- if (!$$.flags.i) {
- _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
- "`%s'\n", $1);
- YYERROR;
- }
- }
- | any_identifier '=' integer_constant
- {
- memset(& $$, 0, sizeof($$));
-
- if (state->ARB_explicit_attrib_location_enable) {
- if (strcmp("location", $1) == 0) {
- $$.flags.q.explicit_location = 1;
-
- if ($3 >= 0) {
- $$.location = $3;
- } else {
- _mesa_glsl_error(& @3, state,
- "invalid location %d specified\n", $3);
- YYERROR;
- }
- }
-
- if (strcmp("index", $1) == 0) {
- $$.flags.q.explicit_index = 1;
-
- if ($3 >= 0) {
- $$.index = $3;
- } else {
- _mesa_glsl_error(& @3, state,
- "invalid index %d specified\n", $3);
- YYERROR;
- }
- }
- }
-
- /* If the identifier didn't match any known layout identifiers,
- * emit an error.
- */
- if (!$$.flags.i) {
- _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
- "`%s'\n", $1);
- YYERROR;
- } else if (state->ARB_explicit_attrib_location_warn) {
- _mesa_glsl_warning(& @1, state,
- "GL_ARB_explicit_attrib_location layout "
- "identifier `%s' used\n", $1);
- }
- }
- | interface_block_layout_qualifier
- {
- $$ = $1;
- /* Layout qualifiers for ARB_uniform_buffer_object. */
- if ($$.flags.q.uniform && !state->ARB_uniform_buffer_object_enable) {
- _mesa_glsl_error(& @1, state,
- "#version 140 / GL_ARB_uniform_buffer_object "
- "layout qualifier `%s' is used\n", $1);
- } else if ($$.flags.q.uniform && state->ARB_uniform_buffer_object_warn) {
- _mesa_glsl_warning(& @1, state,
- "#version 140 / GL_ARB_uniform_buffer_object "
- "layout qualifier `%s' is used\n", $1);
- }
- }
- ;
+ any_identifier
+ {
+ memset(& $$, 0, sizeof($$));
+
+ /* Layout qualifiers for ARB_fragment_coord_conventions. */
+ if (!$$.flags.i && (state->ARB_fragment_coord_conventions_enable ||
+ state->is_version(150, 0))) {
+ if (match_layout_qualifier($1, "origin_upper_left", state) == 0) {
+ $$.flags.q.origin_upper_left = 1;
+ } else if (match_layout_qualifier($1, "pixel_center_integer",
+ state) == 0) {
+ $$.flags.q.pixel_center_integer = 1;
+ }
+
+ if ($$.flags.i && state->ARB_fragment_coord_conventions_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_ARB_fragment_coord_conventions layout "
+ "identifier `%s' used", $1);
+ }
+ }
+
+ /* Layout qualifiers for AMD/ARB_conservative_depth. */
+ if (!$$.flags.i &&
+ (state->AMD_conservative_depth_enable ||
+ state->ARB_conservative_depth_enable ||
+ state->is_version(420, 0))) {
+ if (match_layout_qualifier($1, "depth_any", state) == 0) {
+ $$.flags.q.depth_any = 1;
+ } else if (match_layout_qualifier($1, "depth_greater", state) == 0) {
+ $$.flags.q.depth_greater = 1;
+ } else if (match_layout_qualifier($1, "depth_less", state) == 0) {
+ $$.flags.q.depth_less = 1;
+ } else if (match_layout_qualifier($1, "depth_unchanged",
+ state) == 0) {
+ $$.flags.q.depth_unchanged = 1;
+ }
+
+ if ($$.flags.i && state->AMD_conservative_depth_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_AMD_conservative_depth "
+ "layout qualifier `%s' is used", $1);
+ }
+ if ($$.flags.i && state->ARB_conservative_depth_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_ARB_conservative_depth "
+ "layout qualifier `%s' is used", $1);
+ }
+ }
+
+ /* See also interface_block_layout_qualifier. */
+ if (!$$.flags.i && state->has_uniform_buffer_objects()) {
+ if (match_layout_qualifier($1, "std140", state) == 0) {
+ $$.flags.q.std140 = 1;
+ } else if (match_layout_qualifier($1, "shared", state) == 0) {
+ $$.flags.q.shared = 1;
+ } else if (match_layout_qualifier($1, "column_major", state) == 0) {
+ $$.flags.q.column_major = 1;
+ /* "row_major" is a reserved word in GLSL 1.30+. Its token is parsed
+ * below in the interface_block_layout_qualifier rule.
+ *
+ * It is not a reserved word in GLSL ES 3.00, so it's handled here as
+ * an identifier.
+ *
+ * Also, this takes care of alternate capitalizations of
+ * "row_major" (which is necessary because layout qualifiers
+ * are case-insensitive in desktop GLSL).
+ */
+ } else if (match_layout_qualifier($1, "row_major", state) == 0) {
+ $$.flags.q.row_major = 1;
+ /* "packed" is a reserved word in GLSL, and its token is
+ * parsed below in the interface_block_layout_qualifier rule.
+ * However, we must take care of alternate capitalizations of
+ * "packed", because layout qualifiers are case-insensitive
+ * in desktop GLSL.
+ */
+ } else if (match_layout_qualifier($1, "packed", state) == 0) {
+ $$.flags.q.packed = 1;
+ }
+
+ if ($$.flags.i && state->ARB_uniform_buffer_object_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "#version 140 / GL_ARB_uniform_buffer_object "
+ "layout qualifier `%s' is used", $1);
+ }
+ }
+
+ /* Layout qualifiers for GLSL 1.50 geometry shaders. */
+ if (!$$.flags.i) {
+ static const struct {
+ const char *s;
+ GLenum e;
+ } map[] = {
+ { "points", GL_POINTS },
+ { "lines", GL_LINES },
+ { "lines_adjacency", GL_LINES_ADJACENCY },
+ { "line_strip", GL_LINE_STRIP },
+ { "triangles", GL_TRIANGLES },
+ { "triangles_adjacency", GL_TRIANGLES_ADJACENCY },
+ { "triangle_strip", GL_TRIANGLE_STRIP },
+ };
+ for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
+ if (match_layout_qualifier($1, map[i].s, state) == 0) {
+ $$.flags.q.prim_type = 1;
+ $$.prim_type = map[i].e;
+ break;
+ }
+ }
+
+ if ($$.flags.i && !state->is_version(150, 0)) {
+ _mesa_glsl_error(& @1, state, "#version 150 layout "
+ "qualifier `%s' used", $1);
+ }
+ }
+
+ /* Layout qualifiers for ARB_shader_image_load_store. */
+ if (state->ARB_shader_image_load_store_enable ||
+ state->is_version(420, 0)) {
+ if (!$$.flags.i) {
+ static const struct {
+ const char *name;
+ GLenum format;
+ glsl_base_type base_type;
+ } map[] = {
+ { "rgba32f", GL_RGBA32F, GLSL_TYPE_FLOAT },
+ { "rgba16f", GL_RGBA16F, GLSL_TYPE_FLOAT },
+ { "rg32f", GL_RG32F, GLSL_TYPE_FLOAT },
+ { "rg16f", GL_RG16F, GLSL_TYPE_FLOAT },
+ { "r11f_g11f_b10f", GL_R11F_G11F_B10F, GLSL_TYPE_FLOAT },
+ { "r32f", GL_R32F, GLSL_TYPE_FLOAT },
+ { "r16f", GL_R16F, GLSL_TYPE_FLOAT },
+ { "rgba32ui", GL_RGBA32UI, GLSL_TYPE_UINT },
+ { "rgba16ui", GL_RGBA16UI, GLSL_TYPE_UINT },
+ { "rgb10_a2ui", GL_RGB10_A2UI, GLSL_TYPE_UINT },
+ { "rgba8ui", GL_RGBA8UI, GLSL_TYPE_UINT },
+ { "rg32ui", GL_RG32UI, GLSL_TYPE_UINT },
+ { "rg16ui", GL_RG16UI, GLSL_TYPE_UINT },
+ { "rg8ui", GL_RG8UI, GLSL_TYPE_UINT },
+ { "r32ui", GL_R32UI, GLSL_TYPE_UINT },
+ { "r16ui", GL_R16UI, GLSL_TYPE_UINT },
+ { "r8ui", GL_R8UI, GLSL_TYPE_UINT },
+ { "rgba32i", GL_RGBA32I, GLSL_TYPE_INT },
+ { "rgba16i", GL_RGBA16I, GLSL_TYPE_INT },
+ { "rgba8i", GL_RGBA8I, GLSL_TYPE_INT },
+ { "rg32i", GL_RG32I, GLSL_TYPE_INT },
+ { "rg16i", GL_RG16I, GLSL_TYPE_INT },
+ { "rg8i", GL_RG8I, GLSL_TYPE_INT },
+ { "r32i", GL_R32I, GLSL_TYPE_INT },
+ { "r16i", GL_R16I, GLSL_TYPE_INT },
+ { "r8i", GL_R8I, GLSL_TYPE_INT },
+ { "rgba16", GL_RGBA16, GLSL_TYPE_FLOAT },
+ { "rgb10_a2", GL_RGB10_A2, GLSL_TYPE_FLOAT },
+ { "rgba8", GL_RGBA8, GLSL_TYPE_FLOAT },
+ { "rg16", GL_RG16, GLSL_TYPE_FLOAT },
+ { "rg8", GL_RG8, GLSL_TYPE_FLOAT },
+ { "r16", GL_R16, GLSL_TYPE_FLOAT },
+ { "r8", GL_R8, GLSL_TYPE_FLOAT },
+ { "rgba16_snorm", GL_RGBA16_SNORM, GLSL_TYPE_FLOAT },
+ { "rgba8_snorm", GL_RGBA8_SNORM, GLSL_TYPE_FLOAT },
+ { "rg16_snorm", GL_RG16_SNORM, GLSL_TYPE_FLOAT },
+ { "rg8_snorm", GL_RG8_SNORM, GLSL_TYPE_FLOAT },
+ { "r16_snorm", GL_R16_SNORM, GLSL_TYPE_FLOAT },
+ { "r8_snorm", GL_R8_SNORM, GLSL_TYPE_FLOAT }
+ };
+
+ for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
+ if (match_layout_qualifier($1, map[i].name, state) == 0) {
+ $$.flags.q.explicit_image_format = 1;
+ $$.image_format = map[i].format;
+ $$.image_base_type = map[i].base_type;
+ break;
+ }
+ }
+ }
+
+ if (!$$.flags.i &&
+ match_layout_qualifier($1, "early_fragment_tests", state) == 0) {
+ /* From section 4.4.1.3 of the GLSL 4.50 specification
+ * (Fragment Shader Inputs):
+ *
+ * "Fragment shaders also allow the following layout
+ * qualifier on in only (not with variable declarations)
+ * layout-qualifier-id
+ * early_fragment_tests
+ * [...]"
+ */
+ if (state->stage != MESA_SHADER_FRAGMENT) {
+ _mesa_glsl_error(& @1, state,
+ "early_fragment_tests layout qualifier only "
+ "valid in fragment shaders");
+ }
+
+ $$.flags.q.early_fragment_tests = 1;
+ }
+ }
+
+ /* Layout qualifiers for tessellation evaluation shaders. */
+ if (!$$.flags.i) {
+ struct {
+ const char *s;
+ GLenum e;
+ } map[] = {
+ /* triangles already parsed by gs-specific code */
+ { "quads", GL_QUADS },
+ { "isolines", GL_ISOLINES },
+ };
+ for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
+ if (match_layout_qualifier($1, map[i].s, state) == 0) {
+ $$.flags.q.prim_type = 1;
+ $$.prim_type = map[i].e;
+ break;
+ }
+ }
+
+ if ($$.flags.i &&
+ !state->ARB_tessellation_shader_enable &&
+ !state->is_version(400, 0)) {
+ _mesa_glsl_error(& @1, state,
+ "primitive mode qualifier `%s' requires "
+ "GLSL 4.00 or ARB_tessellation_shader", $1);
+ }
+ }
+ if (!$$.flags.i) {
+ struct {
+ const char *s;
+ GLenum e;
+ } map[] = {
+ { "equal_spacing", GL_EQUAL },
+ { "fractional_odd_spacing", GL_FRACTIONAL_ODD },
+ { "fractional_even_spacing", GL_FRACTIONAL_EVEN },
+ };
+ for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
+ if (match_layout_qualifier($1, map[i].s, state) == 0) {
+ $$.flags.q.vertex_spacing = 1;
+ $$.vertex_spacing = map[i].e;
+ break;
+ }
+ }
+
+ if ($$.flags.i &&
+ !state->ARB_tessellation_shader_enable &&
+ !state->is_version(400, 0)) {
+ _mesa_glsl_error(& @1, state,
+ "vertex spacing qualifier `%s' requires "
+ "GLSL 4.00 or ARB_tessellation_shader", $1);
+ }
+ }
+ if (!$$.flags.i) {
+ if (match_layout_qualifier($1, "cw", state) == 0) {
+ $$.flags.q.ordering = 1;
+ $$.ordering = GL_CW;
+ } else if (match_layout_qualifier($1, "ccw", state) == 0) {
+ $$.flags.q.ordering = 1;
+ $$.ordering = GL_CCW;
+ }
+
+ if ($$.flags.i &&
+ !state->ARB_tessellation_shader_enable &&
+ !state->is_version(400, 0)) {
+ _mesa_glsl_error(& @1, state,
+ "ordering qualifier `%s' requires "
+ "GLSL 4.00 or ARB_tessellation_shader", $1);
+ }
+ }
+ if (!$$.flags.i) {
+ if (match_layout_qualifier($1, "point_mode", state) == 0) {
+ $$.flags.q.point_mode = 1;
+ $$.point_mode = true;
+ }
+
+ if ($$.flags.i &&
+ !state->ARB_tessellation_shader_enable &&
+ !state->is_version(400, 0)) {
+ _mesa_glsl_error(& @1, state,
+ "qualifier `point_mode' requires "
+ "GLSL 4.00 or ARB_tessellation_shader");
+ }
+ }
+
+ if (!$$.flags.i) {
+ _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+ "`%s'", $1);
+ YYERROR;
+ }
+ }
+ | any_identifier '=' integer_constant
+ {
+ memset(& $$, 0, sizeof($$));
+
+ if (match_layout_qualifier("location", $1, state) == 0) {
+ $$.flags.q.explicit_location = 1;
+
+ if ($$.flags.q.attribute == 1 &&
+ state->ARB_explicit_attrib_location_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "GL_ARB_explicit_attrib_location layout "
+ "identifier `%s' used", $1);
+ }
+
+ if ($3 >= 0) {
+ $$.location = $3;
+ } else {
+ _mesa_glsl_error(& @3, state, "invalid location %d specified", $3);
+ YYERROR;
+ }
+ }
+
+ if (match_layout_qualifier("index", $1, state) == 0) {
+ $$.flags.q.explicit_index = 1;
+
+ if ($3 >= 0) {
+ $$.index = $3;
+ } else {
+ _mesa_glsl_error(& @3, state, "invalid index %d specified", $3);
+ YYERROR;
+ }
+ }
+
+ if (match_layout_qualifier("binding", $1, state) == 0) {
+ $$.flags.q.explicit_binding = 1;
+ $$.binding = $3;
+ }
+
+ if (match_layout_qualifier("set", $1, state) == 0) {
+ $$.flags.q.vk_set = 1;
+ $$.set = $3;
+ }
+
+ if (state->has_atomic_counters() &&
+ match_layout_qualifier("offset", $1, state) == 0) {
+ $$.flags.q.explicit_offset = 1;
+ $$.offset = $3;
+ }
+
+ if (match_layout_qualifier("max_vertices", $1, state) == 0) {
+ $$.flags.q.max_vertices = 1;
+
+ if ($3 < 0) {
+ _mesa_glsl_error(& @3, state,
+ "invalid max_vertices %d specified", $3);
+ YYERROR;
+ } else {
+ $$.max_vertices = $3;
+ if (!state->is_version(150, 0)) {
+ _mesa_glsl_error(& @3, state,
+ "#version 150 max_vertices qualifier "
+ "specified", $3);
+ }
+ }
+ }
+
+ if (state->stage == MESA_SHADER_GEOMETRY) {
+ if (match_layout_qualifier("stream", $1, state) == 0 &&
+ state->check_explicit_attrib_stream_allowed(& @3)) {
+ $$.flags.q.stream = 1;
+
+ if ($3 < 0) {
+ _mesa_glsl_error(& @3, state,
+ "invalid stream %d specified", $3);
+ YYERROR;
+ } else {
+ $$.flags.q.explicit_stream = 1;
+ $$.stream = $3;
+ }
+ }
+ }
+
+ static const char * const local_size_qualifiers[3] = {
+ "local_size_x",
+ "local_size_y",
+ "local_size_z",
+ };
+ for (int i = 0; i < 3; i++) {
+ if (match_layout_qualifier(local_size_qualifiers[i], $1,
+ state) == 0) {
+ if ($3 <= 0) {
+ _mesa_glsl_error(& @3, state,
+ "invalid %s of %d specified",
+ local_size_qualifiers[i], $3);
+ YYERROR;
+ } else if (!state->is_version(430, 0) &&
+ !state->ARB_compute_shader_enable) {
+ _mesa_glsl_error(& @3, state,
+ "%s qualifier requires GLSL 4.30 or "
+ "ARB_compute_shader",
+ local_size_qualifiers[i]);
+ YYERROR;
+ } else {
+ $$.flags.q.local_size |= (1 << i);
+ $$.local_size[i] = $3;
+ }
+ break;
+ }
+ }
+
+ if (match_layout_qualifier("invocations", $1, state) == 0) {
+ $$.flags.q.invocations = 1;
+
+ if ($3 <= 0) {
+ _mesa_glsl_error(& @3, state,
+ "invalid invocations %d specified", $3);
+ YYERROR;
+ } else if ($3 > MAX_GEOMETRY_SHADER_INVOCATIONS) {
+ _mesa_glsl_error(& @3, state,
+ "invocations (%d) exceeds "
+ "GL_MAX_GEOMETRY_SHADER_INVOCATIONS", $3);
+ YYERROR;
+ } else {
+ $$.invocations = $3;
+ if (!state->is_version(400, 0) &&
+ !state->ARB_gpu_shader5_enable) {
+ _mesa_glsl_error(& @3, state,
+ "GL_ARB_gpu_shader5 invocations "
+ "qualifier specified", $3);
+ }
+ }
+ }
+
+ /* Layout qualifiers for tessellation control shaders. */
+ if (match_layout_qualifier("vertices", $1, state) == 0) {
+ $$.flags.q.vertices = 1;
+
+ if ($3 <= 0) {
+ _mesa_glsl_error(& @3, state,
+ "invalid vertices (%d) specified", $3);
+ YYERROR;
+ } else if ($3 > (int)state->Const.MaxPatchVertices) {
+ _mesa_glsl_error(& @3, state,
+ "vertices (%d) exceeds "
+ "GL_MAX_PATCH_VERTICES", $3);
+ YYERROR;
+ } else {
+ $$.vertices = $3;
+ if (!state->ARB_tessellation_shader_enable &&
+ !state->is_version(400, 0)) {
+ _mesa_glsl_error(& @1, state,
+ "vertices qualifier requires GLSL 4.00 or "
+ "ARB_tessellation_shader");
+ }
+ }
+ }
+
+ /* If the identifier didn't match any known layout identifiers,
+ * emit an error.
+ */
+ if (!$$.flags.i) {
+ _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+ "`%s'", $1);
+ YYERROR;
+ }
+ }
+ | interface_block_layout_qualifier
+ {
+ $$ = $1;
+ /* Layout qualifiers for ARB_uniform_buffer_object. */
+ if ($$.flags.q.uniform && !state->has_uniform_buffer_objects()) {
+ _mesa_glsl_error(& @1, state,
+ "#version 140 / GL_ARB_uniform_buffer_object "
+ "layout qualifier `%s' is used", $1);
+ } else if ($$.flags.q.uniform && state->ARB_uniform_buffer_object_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "#version 140 / GL_ARB_uniform_buffer_object "
+ "layout qualifier `%s' is used", $1);
+ }
+ }
+ ;