diff options
author | Connor Abbott <[email protected]> | 2019-06-04 11:41:25 +0200 |
---|---|---|
committer | Connor Abbott <[email protected]> | 2019-06-19 14:08:27 +0200 |
commit | 364996d70dec716707493d667e17d2c1efcb7259 (patch) | |
tree | f3ba6565e88e415aaca84e5646d76dfe2262db45 /src | |
parent | 6f20643b471a851c936fc8b569cf05dcd6e6e7fe (diff) |
glsl/nir: Propagate access qualifiers
We were completely ignoring these before, except for putting them on
variables. While we're here, don't set access qualifiers when converting
to bindless since glsl_to_nir will already have set a more accurate
qualifier that includes any qualifiers on struct members that are
dereferenced.
Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/glsl/glsl_to_nir.cpp | 64 | ||||
-rw-r--r-- | src/compiler/nir/nir.c | 1 |
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], |