summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/ast.h8
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp66
-rw-r--r--src/compiler/glsl/ast_type.cpp53
-rw-r--r--src/compiler/glsl/glsl_parser.yy21
-rw-r--r--src/compiler/glsl/glsl_parser_extras.cpp11
-rw-r--r--src/compiler/glsl/glsl_parser_extras.h10
-rw-r--r--src/compiler/glsl/ir.cpp2
-rw-r--r--src/compiler/glsl/ir.h12
-rw-r--r--src/compiler/glsl/ir_print_visitor.cpp8
-rw-r--r--src/mesa/main/mtypes.h10
10 files changed, 198 insertions, 3 deletions
diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
index 455cb8113cd..9327e039793 100644
--- a/src/compiler/glsl/ast.h
+++ b/src/compiler/glsl/ast.h
@@ -622,6 +622,14 @@ struct ast_type_qualifier {
* is used.
*/
unsigned inner_coverage:1;
+
+ /** \name Layout qualifiers for GL_ARB_bindless_texture */
+ /** \{ */
+ unsigned bindless_sampler:1;
+ unsigned bindless_image:1;
+ unsigned bound_sampler:1;
+ unsigned bound_image:1;
+ /** \} */
}
/** \brief Set of flags, accessed by name. */
q;
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index f301b39f896..53dd08fe84f 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -3457,6 +3457,69 @@ validate_array_dimensions(const glsl_type *t,
}
static void
+apply_bindless_qualifier_to_variable(const struct ast_type_qualifier *qual,
+ ir_variable *var,
+ struct _mesa_glsl_parse_state *state,
+ YYLTYPE *loc)
+{
+ bool has_local_qualifiers = qual->flags.q.bindless_sampler ||
+ qual->flags.q.bindless_image ||
+ qual->flags.q.bound_sampler ||
+ qual->flags.q.bound_image;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "Modify Section 4.4.6 Opaque-Uniform Layout Qualifiers of the GLSL 4.30
+ * spec"
+ *
+ * "If these layout qualifiers are applied to other types of default block
+ * uniforms, or variables with non-uniform storage, a compile-time error
+ * will be generated."
+ */
+ if (has_local_qualifiers && !qual->flags.q.uniform) {
+ _mesa_glsl_error(loc, state, "ARB_bindless_texture layout qualifiers "
+ "can only be applied to default block uniforms or "
+ "variables with uniform storage");
+ return;
+ }
+
+ /* The ARB_bindless_texture spec doesn't state anything in this situation,
+ * but it makes sense to only allow bindless_sampler/bound_sampler for
+ * sampler types, and respectively bindless_image/bound_image for image
+ * types.
+ */
+ if ((qual->flags.q.bindless_sampler || qual->flags.q.bound_sampler) &&
+ !var->type->contains_sampler()) {
+ _mesa_glsl_error(loc, state, "bindless_sampler or bound_sampler can only "
+ "be applied to sampler types");
+ return;
+ }
+
+ if ((qual->flags.q.bindless_image || qual->flags.q.bound_image) &&
+ !var->type->contains_image()) {
+ _mesa_glsl_error(loc, state, "bindless_image or bound_image can only be "
+ "applied to image types");
+ return;
+ }
+
+ /* The bindless_sampler/bindless_image (and respectively
+ * bound_sampler/bound_image) layout qualifiers can be set at global and at
+ * local scope.
+ */
+ if (var->type->contains_sampler() || var->type->contains_image()) {
+ var->data.bindless = qual->flags.q.bindless_sampler ||
+ qual->flags.q.bindless_image ||
+ state->bindless_sampler_specified ||
+ state->bindless_image_specified;
+
+ var->data.bound = qual->flags.q.bound_sampler ||
+ qual->flags.q.bound_image ||
+ state->bound_sampler_specified ||
+ state->bound_image_specified;
+ }
+}
+
+static void
apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
ir_variable *var,
struct _mesa_glsl_parse_state *state,
@@ -3753,6 +3816,9 @@ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
_mesa_glsl_error(loc, state, "post_depth_coverage layout qualifier only "
"valid in fragment shader input layout declaration.");
}
+
+ if (state->has_bindless())
+ apply_bindless_qualifier_to_variable(qual, var, state, loc);
}
static void
diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
index d302fc45fd7..9e3e10f33c0 100644
--- a/src/compiler/glsl/ast_type.cpp
+++ b/src/compiler/glsl/ast_type.cpp
@@ -69,6 +69,10 @@ ast_type_qualifier::has_layout() const
|| 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
@@ -181,6 +185,33 @@ validate_point_mode(MAYBE_UNUSED const ast_type_qualifier &qualifier,
return true;
}
+static void
+merge_bindless_qualifier(YYLTYPE *loc,
+ _mesa_glsl_parse_state *state,
+ const ast_type_qualifier &qualifier,
+ const ast_type_qualifier &new_qualifier)
+{
+ 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.
*
@@ -393,6 +424,18 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
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;
+
this->flags.i |= q.flags.i;
if (this->flags.q.in &&
@@ -427,6 +470,12 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
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(loc, state, *this, q);
+
return r;
}
@@ -778,6 +827,10 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
bad.flags.q.subroutine ? " subroutine" : "",
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" : "");
return false;
}
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy
index e703073c9ca..9cdc37eb9a3 100644
--- a/src/compiler/glsl/glsl_parser.yy
+++ b/src/compiler/glsl/glsl_parser.yy
@@ -1589,6 +1589,27 @@ layout_qualifier_id:
}
}
+ /* Layout qualifiers for ARB_bindless_texture. */
+ if (!$$.flags.i) {
+ if (match_layout_qualifier($1, "bindless_sampler", state) == 0)
+ $$.flags.q.bindless_sampler = 1;
+ if (match_layout_qualifier($1, "bound_sampler", state) == 0)
+ $$.flags.q.bound_sampler = 1;
+
+ if (state->has_shader_image_load_store()) {
+ if (match_layout_qualifier($1, "bindless_image", state) == 0)
+ $$.flags.q.bindless_image = 1;
+ if (match_layout_qualifier($1, "bound_image", state) == 0)
+ $$.flags.q.bound_image = 1;
+ }
+
+ if ($$.flags.i && !state->has_bindless()) {
+ _mesa_glsl_error(& @1, state,
+ "qualifier `%s` requires "
+ "ARB_bindless_texture", $1);
+ }
+ }
+
if (!$$.flags.i) {
_mesa_glsl_error(& @1, state, "unrecognized layout identifier "
"`%s'", $1);
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
index b7303aba421..d731e35e212 100644
--- a/src/compiler/glsl/glsl_parser_extras.cpp
+++ b/src/compiler/glsl/glsl_parser_extras.cpp
@@ -307,6 +307,12 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
ctx->Const.AllowGLSLExtensionDirectiveMidShader;
this->cs_input_local_size_variable_specified = false;
+
+ /* ARB_bindless_texture */
+ this->bindless_sampler_specified = false;
+ this->bindless_image_specified = false;
+ this->bound_sampler_specified = false;
+ this->bound_image_specified = false;
}
/**
@@ -1849,6 +1855,11 @@ set_shader_inout_layout(struct gl_shader *shader,
/* Nothing to do. */
break;
}
+
+ shader->bindless_sampler = state->bindless_sampler_specified;
+ shader->bindless_image = state->bindless_image_specified;
+ shader->bound_sampler = state->bound_sampler_specified;
+ shader->bound_image = state->bound_image_specified;
}
extern "C" {
diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h
index 6045a6128e6..3a84d655b14 100644
--- a/src/compiler/glsl/glsl_parser_extras.h
+++ b/src/compiler/glsl/glsl_parser_extras.h
@@ -428,6 +428,16 @@ struct _mesa_glsl_parse_state {
bool cs_input_local_size_variable_specified;
/**
+ * True if a shader declare bindless_sampler/bindless_image, and
+ * respectively bound_sampler/bound_image at global scope as specified by
+ * ARB_bindless_texture.
+ */
+ bool bindless_sampler_specified;
+ bool bindless_image_specified;
+ bool bound_sampler_specified;
+ bool bound_image_specified;
+
+ /**
* Output layout qualifiers from GLSL 1.50 (geometry shader controls),
* and GLSL 4.00 (tessellation control shader).
*/
diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
index 5b38a711494..590d2ad1c4b 100644
--- a/src/compiler/glsl/ir.cpp
+++ b/src/compiler/glsl/ir.cpp
@@ -1729,6 +1729,8 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
this->data.memory_restrict = false;
this->data.from_ssbo_unsized_array = false;
this->data.fb_fetch_output = false;
+ this->data.bindless = false;
+ this->data.bound = false;
if (type != NULL) {
if (type->is_interface())
diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
index 5a5729cdbe3..7e125e60d42 100644
--- a/src/compiler/glsl/ir.h
+++ b/src/compiler/glsl/ir.h
@@ -850,6 +850,18 @@ public:
unsigned fb_fetch_output:1;
/**
+ * Non-zero if this variable is considered bindless as defined by
+ * ARB_bindless_texture.
+ */
+ unsigned bindless:1;
+
+ /**
+ * Non-zero if this variable is considered bound as defined by
+ * ARB_bindless_texture.
+ */
+ unsigned bound:1;
+
+ /**
* Emit a warning if this variable is accessed.
*/
private:
diff --git a/src/compiler/glsl/ir_print_visitor.cpp b/src/compiler/glsl/ir_print_visitor.cpp
index 6c1c86a5828..f8d0dc4dec2 100644
--- a/src/compiler/glsl/ir_print_visitor.cpp
+++ b/src/compiler/glsl/ir_print_visitor.cpp
@@ -193,6 +193,8 @@ void ir_print_visitor::visit(ir_variable *ir)
const char *const patc = (ir->data.patch) ? "patch " : "";
const char *const inv = (ir->data.invariant) ? "invariant " : "";
const char *const prec = (ir->data.precise) ? "precise " : "";
+ const char *const bindless = (ir->data.bindless) ? "bindless " : "";
+ const char *const bound = (ir->data.bound) ? "bound " : "";
const char *const mode[] = { "", "uniform ", "shader_storage ",
"shader_shared ", "shader_in ", "shader_out ",
"in ", "out ", "inout ",
@@ -201,9 +203,9 @@ void ir_print_visitor::visit(ir_variable *ir)
const char *const interp[] = { "", "smooth", "flat", "noperspective" };
STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_MODE_COUNT);
- fprintf(f, "(%s%s%s%s%s%s%s%s%s%s%s) ",
- binding, loc, component, cent, samp, patc, inv, prec, mode[ir->data.mode],
- stream,
+ fprintf(f, "(%s%s%s%s%s%s%s%s%s%s%s%s%s) ",
+ binding, loc, component, cent, bindless, bound, samp, patc, inv,
+ prec, mode[ir->data.mode], stream,
interp[ir->data.interpolation]);
print_type(f, ir->type);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 79c7e50a1bf..0d594bf436f 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2547,6 +2547,16 @@ struct gl_shader
bool origin_upper_left;
bool pixel_center_integer;
+ /**
+ * Whether bindless_sampler/bindless_image, and respectively
+ * bound_sampler/bound_image are declared at global scope as defined by
+ * ARB_bindless_texture.
+ */
+ bool bindless_sampler;
+ bool bindless_image;
+ bool bound_sampler;
+ bool bound_image;
+
/** Global xfb_stride out qualifier if any */
GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS];