ast_type_qualifier subroutine_only;
subroutine_only.flags.i = 0;
subroutine_only.flags.q.subroutine = 1;
- subroutine_only.flags.q.subroutine_def = 1;
if (state->has_explicit_uniform_location()) {
subroutine_only.flags.q.explicit_index = 1;
}
{
return this->flags.q.origin_upper_left
|| this->flags.q.pixel_center_integer
- || this->flags.q.depth_any
- || this->flags.q.depth_greater
- || this->flags.q.depth_less
- || this->flags.q.depth_unchanged
+ || this->flags.q.depth_type
|| this->flags.q.std140
|| this->flags.q.std430
|| this->flags.q.shared
|| this->flags.q.column_major
|| this->flags.q.row_major
|| this->flags.q.packed
+ || this->flags.q.bindless_sampler
+ || this->flags.q.bindless_image
+ || this->flags.q.bound_sampler
+ || this->flags.q.bound_image
|| this->flags.q.explicit_align
|| this->flags.q.explicit_component
|| this->flags.q.explicit_location
|| this->flags.q.write_only;
}
+bool ast_type_qualifier::is_subroutine_decl() const
+{
+ return this->flags.q.subroutine && !this->subroutine_list;
+}
+
static bool
validate_prim_type(YYLTYPE *loc,
_mesa_glsl_parse_state *state,
}
static bool
-validate_point_mode(YYLTYPE *loc,
- _mesa_glsl_parse_state *state,
- const ast_type_qualifier &qualifier,
- const ast_type_qualifier &new_qualifier)
+validate_point_mode(MAYBE_UNUSED const ast_type_qualifier &qualifier,
+ MAYBE_UNUSED const ast_type_qualifier &new_qualifier)
{
/* Point mode can only be true if the flag is set. */
assert (!qualifier.flags.q.point_mode || !new_qualifier.flags.q.point_mode
return true;
}
+static void
+merge_bindless_qualifier(_mesa_glsl_parse_state *state)
+{
+ if (state->default_uniform_qualifier->flags.q.bindless_sampler) {
+ state->bindless_sampler_specified = true;
+ state->default_uniform_qualifier->flags.q.bindless_sampler = false;
+ }
+
+ if (state->default_uniform_qualifier->flags.q.bindless_image) {
+ state->bindless_image_specified = true;
+ state->default_uniform_qualifier->flags.q.bindless_image = false;
+ }
+
+ if (state->default_uniform_qualifier->flags.q.bound_sampler) {
+ state->bound_sampler_specified = true;
+ state->default_uniform_qualifier->flags.q.bound_sampler = false;
+ }
+
+ if (state->default_uniform_qualifier->flags.q.bound_image) {
+ state->bound_image_specified = true;
+ state->default_uniform_qualifier->flags.q.bound_image = false;
+ }
+}
+
/**
* This function merges duplicate layout identifiers.
*
input_layout_mask.flags.q.precise = 1;
input_layout_mask.flags.q.sample = 1;
input_layout_mask.flags.q.smooth = 1;
+ input_layout_mask.flags.q.non_coherent = 1;
+
+ if (state->has_bindless()) {
+ /* Allow to use image qualifiers with shader inputs/outputs. */
+ input_layout_mask.flags.q.coherent = 1;
+ input_layout_mask.flags.q._volatile = 1;
+ input_layout_mask.flags.q.restrict_flag = 1;
+ input_layout_mask.flags.q.read_only = 1;
+ input_layout_mask.flags.q.write_only = 1;
+ input_layout_mask.flags.q.explicit_image_format = 1;
+ }
/* Uniform block layout qualifiers get to overwrite each
* other (rightmost having priority), while all other
}
}
- if (q.flags.q.subroutine_def) {
- if (this->flags.q.subroutine_def) {
+ if (q.subroutine_list) {
+ if (this->subroutine_list) {
_mesa_glsl_error(loc, state,
"conflicting subroutine qualifiers used");
} else {
}
if (q.flags.q.point_mode) {
- r &= validate_point_mode(loc, state, *this, q);
+ r &= validate_point_mode(*this, q);
this->flags.q.point_mode = 1;
this->point_mode = q.point_mode;
}
if (q.flags.q.local_size_variable)
this->flags.q.local_size_variable = true;
+ if (q.flags.q.bindless_sampler)
+ this->flags.q.bindless_sampler = true;
+
+ if (q.flags.q.bindless_image)
+ this->flags.q.bindless_image = true;
+
+ if (q.flags.q.bound_sampler)
+ this->flags.q.bound_sampler = true;
+
+ if (q.flags.q.bound_image)
+ this->flags.q.bound_image = true;
+
+ if (q.flags.q.derivative_group) {
+ this->flags.q.derivative_group = true;
+ this->derivative_group = q.derivative_group;
+ }
+
this->flags.i |= q.flags.i;
if (this->flags.q.in &&
this->image_base_type = q.image_base_type;
}
+ if (q.flags.q.bindless_sampler ||
+ q.flags.q.bindless_image ||
+ q.flags.q.bound_sampler ||
+ q.flags.q.bound_image)
+ merge_bindless_qualifier(state);
+
+ if (state->EXT_gpu_shader4_enable &&
+ state->stage == MESA_SHADER_FRAGMENT &&
+ this->flags.q.varying && q.flags.q.out) {
+ this->flags.q.varying = 0;
+ this->flags.q.out = 1;
+ }
+
return r;
}
break;
case MESA_SHADER_FRAGMENT:
valid_in_mask.flags.q.early_fragment_tests = 1;
+ valid_in_mask.flags.q.inner_coverage = 1;
+ valid_in_mask.flags.q.post_depth_coverage = 1;
+ valid_in_mask.flags.q.pixel_interlock_ordered = 1;
+ valid_in_mask.flags.q.pixel_interlock_unordered = 1;
+ valid_in_mask.flags.q.sample_interlock_ordered = 1;
+ valid_in_mask.flags.q.sample_interlock_unordered = 1;
break;
case MESA_SHADER_COMPUTE:
valid_in_mask.flags.q.local_size = 7;
valid_in_mask.flags.q.local_size_variable = 1;
+ valid_in_mask.flags.q.derivative_group = 1;
break;
default:
r = false;
r &= validate_prim_type(loc, state, *state->in_qualifier, *this);
r &= validate_vertex_spacing(loc, state, *state->in_qualifier, *this);
r &= validate_ordering(loc, state, *state->in_qualifier, *this);
- r &= validate_point_mode(loc, state, *state->in_qualifier, *this);
+ r &= validate_point_mode(*state->in_qualifier, *this);
return r;
}
state->in_qualifier->flags.q.early_fragment_tests = false;
}
+ if (state->in_qualifier->flags.q.inner_coverage) {
+ state->fs_inner_coverage = true;
+ state->in_qualifier->flags.q.inner_coverage = false;
+ }
+
+ if (state->in_qualifier->flags.q.post_depth_coverage) {
+ state->fs_post_depth_coverage = true;
+ state->in_qualifier->flags.q.post_depth_coverage = false;
+ }
+
+ if (state->fs_inner_coverage && state->fs_post_depth_coverage) {
+ _mesa_glsl_error(loc, state,
+ "inner_coverage & post_depth_coverage layout qualifiers "
+ "are mutally exclusives");
+ r = false;
+ }
+
+ if (state->in_qualifier->flags.q.pixel_interlock_ordered) {
+ state->fs_pixel_interlock_ordered = true;
+ state->in_qualifier->flags.q.pixel_interlock_ordered = false;
+ }
+
+ if (state->in_qualifier->flags.q.pixel_interlock_unordered) {
+ state->fs_pixel_interlock_unordered = true;
+ state->in_qualifier->flags.q.pixel_interlock_unordered = false;
+ }
+
+ if (state->in_qualifier->flags.q.sample_interlock_ordered) {
+ state->fs_sample_interlock_ordered = true;
+ state->in_qualifier->flags.q.sample_interlock_ordered = false;
+ }
+
+ if (state->in_qualifier->flags.q.sample_interlock_unordered) {
+ state->fs_sample_interlock_unordered = true;
+ state->in_qualifier->flags.q.sample_interlock_unordered = false;
+ }
+
+ if (state->fs_pixel_interlock_ordered +
+ state->fs_pixel_interlock_unordered +
+ state->fs_sample_interlock_ordered +
+ state->fs_sample_interlock_unordered > 1) {
+ _mesa_glsl_error(loc, state,
+ "only one interlock mode can be used at any time.");
+ r = false;
+ }
+
+ if (state->in_qualifier->flags.q.derivative_group) {
+ if (state->cs_derivative_group != DERIVATIVE_GROUP_NONE) {
+ if (state->in_qualifier->derivative_group != DERIVATIVE_GROUP_NONE &&
+ state->cs_derivative_group != state->in_qualifier->derivative_group) {
+ _mesa_glsl_error(loc, state,
+ "conflicting derivative groups.");
+ r = false;
+ }
+ } else {
+ state->cs_derivative_group = state->in_qualifier->derivative_group;
+ }
+ }
+
/* We allow the creation of multiple cs_input_layout nodes. Coherence among
* all existing nodes is checked later, when the AST node is transformed
* into HIR.
"%s '%s':"
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
message, name,
bad.flags.q.invariant ? " invariant" : "",
bad.flags.q.precise ? " precise" : "",
bad.flags.q.explicit_index ? " index" : "",
bad.flags.q.explicit_binding ? " binding" : "",
bad.flags.q.explicit_offset ? " offset" : "",
- bad.flags.q.depth_any ? " depth_any" : "",
- bad.flags.q.depth_greater ? " depth_greater" : "",
- bad.flags.q.depth_less ? " depth_less" : "",
- bad.flags.q.depth_unchanged ? " depth_unchanged" : "",
+ bad.flags.q.depth_type ? " depth_type" : "",
bad.flags.q.std140 ? " std140" : "",
bad.flags.q.std430 ? " std430" : "",
bad.flags.q.shared ? " shared" : "",
bad.flags.q.point_mode ? " point_mode" : "",
bad.flags.q.vertices ? " vertices" : "",
bad.flags.q.subroutine ? " subroutine" : "",
- bad.flags.q.subroutine_def ? " subroutine_def" : "");
+ bad.flags.q.blend_support ? " blend_support" : "",
+ bad.flags.q.inner_coverage ? " inner_coverage" : "",
+ bad.flags.q.bindless_sampler ? " bindless_sampler" : "",
+ bad.flags.q.bindless_image ? " bindless_image" : "",
+ bad.flags.q.bound_sampler ? " bound_sampler" : "",
+ bad.flags.q.bound_image ? " bound_image" : "",
+ bad.flags.q.post_depth_coverage ? " post_depth_coverage" : "",
+ bad.flags.q.pixel_interlock_ordered ? " pixel_interlock_ordered" : "",
+ bad.flags.q.pixel_interlock_unordered ? " pixel_interlock_unordered": "",
+ bad.flags.q.sample_interlock_ordered ? " sample_interlock_ordered": "",
+ bad.flags.q.sample_interlock_unordered ? " sample_interlock_unordered": "",
+ bad.flags.q.non_coherent ? " noncoherent" : "");
return false;
}
ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
- ir_constant *const const_int = ir->constant_expression_value();
- if (const_int == NULL || !const_int->type->is_integer()) {
+ ir_constant *const const_int =
+ ir->constant_expression_value(ralloc_parent(ir));
+
+ if (const_int == NULL || !const_int->type->is_integer_32()) {
YYLTYPE loc = const_expression->get_location();
_mesa_glsl_error(&loc, state, "%s must be an integral constant "
"expression", qual_indentifier);
return false;
}
- /* From section 4.4 "Layout Qualifiers" of the GLSL 4.50 spec:
- * "When the same layout-qualifier-name occurs multiple times,
- * in a single declaration, the last occurrence overrides the
- * former occurrence(s)."
- */
- if (!state->has_420pack() && !first_pass && *value != const_int->value.u[0]) {
+ if (!first_pass && *value != const_int->value.u[0]) {
YYLTYPE loc = const_expression->get_location();
_mesa_glsl_error(&loc, state, "%s layout qualifier does not "
"match previous declaration (%d vs %d)",
ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
- ir_constant *const const_int = ir->constant_expression_value();
- if (const_int == NULL || !const_int->type->is_integer()) {
+ ir_constant *const const_int =
+ ir->constant_expression_value(ralloc_parent(ir));
+ if (const_int == NULL || !const_int->type->is_integer_32()) {
_mesa_glsl_error(loc, state, "%s must be an integral constant "
"expression", qual_indentifier);
return false;