aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/glsl_to_nir.cpp64
-rw-r--r--src/compiler/nir/nir.c1
2 files changed, 59 insertions, 6 deletions
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index 2e0075c2d5e..656566e4c61 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -34,6 +34,7 @@
#include "program.h"
#include "compiler/nir/nir_control_flow.h"
#include "compiler/nir/nir_builder.h"
+#include "compiler/nir/nir_deref.h"
#include "main/errors.h"
#include "main/imports.h"
#include "main/mtypes.h"
@@ -812,6 +813,45 @@ intrinsic_set_std430_align(nir_intrinsic_instr *intrin, const glsl_type *type)
nir_intrinsic_set_align(intrin, (bit_size / 8) * pow2_components, 0);
}
+/* Accumulate any qualifiers along the deref chain to get the actual
+ * load/store qualifier.
+ */
+
+static enum gl_access_qualifier
+deref_get_qualifier(nir_deref_instr *deref)
+{
+ nir_deref_path path;
+ nir_deref_path_init(&path, deref, NULL);
+
+ unsigned qualifiers = path.path[0]->var->data.image.access;
+
+ const glsl_type *parent_type = path.path[0]->type;
+ for (nir_deref_instr **cur_ptr = &path.path[1]; *cur_ptr; cur_ptr++) {
+ nir_deref_instr *cur = *cur_ptr;
+
+ if (parent_type->is_interface()) {
+ const struct glsl_struct_field *field =
+ &parent_type->fields.structure[cur->strct.index];
+ if (field->memory_read_only)
+ qualifiers |= ACCESS_NON_WRITEABLE;
+ if (field->memory_write_only)
+ qualifiers |= ACCESS_NON_READABLE;
+ if (field->memory_coherent)
+ qualifiers |= ACCESS_COHERENT;
+ if (field->memory_volatile)
+ qualifiers |= ACCESS_VOLATILE;
+ if (field->memory_restrict)
+ qualifiers |= ACCESS_RESTRICT;
+ }
+
+ parent_type = cur->type;
+ }
+
+ nir_deref_path_finish(&path);
+
+ return (gl_access_qualifier) qualifiers;
+}
+
void
nir_visitor::visit(ir_call *ir)
{
@@ -1121,6 +1161,8 @@ nir_visitor::visit(ir_call *ir)
}
instr->src[0] = nir_src_for_ssa(&nir_deref->dest.ssa);
+ nir_intrinsic_set_access(instr, deref_get_qualifier(nir_deref));
+
/* data1 parameter (this is always present) */
param = param->get_next();
ir_instruction *inst = (ir_instruction *) param;
@@ -1204,6 +1246,8 @@ nir_visitor::visit(ir_call *ir)
nir_deref_instr *deref = evaluate_deref(image);
const glsl_type *type = deref->type;
+ nir_intrinsic_set_access(instr, deref_get_qualifier(deref));
+
instr->src[0] = nir_src_for_ssa(&deref->dest.ssa);
param = param->get_next();
@@ -1607,12 +1651,18 @@ nir_visitor::visit(ir_assignment *ir)
if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) &&
(ir->write_mask == (1 << num_components) - 1 || ir->write_mask == 0)) {
+ nir_deref_instr *lhs = evaluate_deref(ir->lhs);
+ nir_deref_instr *rhs = evaluate_deref(ir->rhs);
+ enum gl_access_qualifier lhs_qualifiers = deref_get_qualifier(lhs);
+ enum gl_access_qualifier rhs_qualifiers = deref_get_qualifier(rhs);
if (ir->condition) {
nir_push_if(&b, evaluate_rvalue(ir->condition));
- nir_copy_deref(&b, evaluate_deref(ir->lhs), evaluate_deref(ir->rhs));
+ nir_copy_deref_with_access(&b, lhs, rhs, lhs_qualifiers,
+ rhs_qualifiers);
nir_pop_if(&b, NULL);
} else {
- nir_copy_deref(&b, evaluate_deref(ir->lhs), evaluate_deref(ir->rhs));
+ nir_copy_deref_with_access(&b, lhs, rhs, lhs_qualifiers,
+ rhs_qualifiers);
}
return;
}
@@ -1637,12 +1687,15 @@ nir_visitor::visit(ir_assignment *ir)
src = nir_swizzle(&b, src, swiz, num_components);
}
+ enum gl_access_qualifier qualifiers = deref_get_qualifier(lhs_deref);
if (ir->condition) {
nir_push_if(&b, evaluate_rvalue(ir->condition));
- nir_store_deref(&b, lhs_deref, src, ir->write_mask);
+ nir_store_deref_with_access(&b, lhs_deref, src, ir->write_mask,
+ qualifiers);
nir_pop_if(&b, NULL);
} else {
- nir_store_deref(&b, lhs_deref, src, ir->write_mask);
+ nir_store_deref_with_access(&b, lhs_deref, src, ir->write_mask,
+ qualifiers);
}
}
@@ -1709,7 +1762,8 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir)
* must emit a variable load.
*/
- this->result = nir_load_deref(&b, this->deref);
+ enum gl_access_qualifier access = deref_get_qualifier(this->deref);
+ this->result = nir_load_deref_with_access(&b, this->deref, access);
}
return this->result;
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 524b9445b11..81f569b4c2b 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -2041,7 +2041,6 @@ nir_rewrite_image_intrinsic(nir_intrinsic_instr *intrin, nir_ssa_def *src,
nir_intrinsic_set_image_dim(intrin, glsl_get_sampler_dim(deref->type));
nir_intrinsic_set_image_array(intrin, glsl_sampler_type_is_array(deref->type));
- nir_intrinsic_set_access(intrin, var->data.image.access);
nir_intrinsic_set_format(intrin, var->data.image.format);
nir_instr_rewrite_src(&intrin->instr, &intrin->src[0],