diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/nir/nir.c | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir.h | 7 | ||||
-rw-r--r-- | src/compiler/nir/nir_builder.h | 29 | ||||
-rw-r--r-- | src/compiler/nir/nir_clone.c | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir_deref.c | 20 | ||||
-rw-r--r-- | src/compiler/nir/nir_instr_set.c | 13 | ||||
-rw-r--r-- | src/compiler/nir/nir_opt_copy_propagate.c | 3 | ||||
-rw-r--r-- | src/compiler/nir/nir_print.c | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir_serialize.c | 12 | ||||
-rw-r--r-- | src/compiler/nir/nir_validate.c | 13 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_cfg.c | 2 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_variables.c | 2 |
12 files changed, 106 insertions, 13 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index b0b031cde61..07bb96dc3b0 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -460,7 +460,8 @@ nir_deref_instr_create(nir_shader *shader, nir_deref_type deref_type) if (deref_type != nir_deref_type_var) src_init(&instr->parent); - if (deref_type == nir_deref_type_array) + if (deref_type == nir_deref_type_array || + deref_type == nir_deref_type_ptr_as_array) src_init(&instr->arr.index); dest_init(&instr->dest); @@ -1067,7 +1068,8 @@ visit_deref_instr_src(nir_deref_instr *instr, return false; } - if (instr->deref_type == nir_deref_type_array) { + if (instr->deref_type == nir_deref_type_array || + instr->deref_type == nir_deref_type_ptr_as_array) { if (!visit_src(&instr->arr.index, cb, state)) return false; } diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index e991c625536..971d8c4979f 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -998,6 +998,7 @@ typedef enum { nir_deref_type_var, nir_deref_type_array, nir_deref_type_array_wildcard, + nir_deref_type_ptr_as_array, nir_deref_type_struct, nir_deref_type_cast, } nir_deref_type; @@ -1031,6 +1032,10 @@ typedef struct { struct { unsigned index; } strct; + + struct { + unsigned ptr_stride; + } cast; }; /** Destination to store the resulting "pointer" */ @@ -1078,6 +1083,8 @@ bool nir_deref_instr_has_indirect(nir_deref_instr *instr); bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr); +unsigned nir_deref_instr_ptr_as_array_stride(nir_deref_instr *instr); + typedef struct { nir_instr instr; diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h index 2076f419ae2..7dbdd5724c2 100644 --- a/src/compiler/nir/nir_builder.h +++ b/src/compiler/nir/nir_builder.h @@ -812,6 +812,31 @@ nir_build_deref_array(nir_builder *build, nir_deref_instr *parent, } static inline nir_deref_instr * +nir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent, + nir_ssa_def *index) +{ + assert(parent->deref_type == nir_deref_type_array || + parent->deref_type == nir_deref_type_ptr_as_array || + parent->deref_type == nir_deref_type_cast); + + nir_deref_instr *deref = + nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array); + + deref->mode = parent->mode; + deref->type = parent->type; + deref->parent = nir_src_for_ssa(&parent->dest.ssa); + deref->arr.index = nir_src_for_ssa(index); + + nir_ssa_dest_init(&deref->instr, &deref->dest, + parent->dest.ssa.num_components, + parent->dest.ssa.bit_size, NULL); + + nir_builder_instr_insert(build, &deref->instr); + + return deref; +} + +static inline nir_deref_instr * nir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent) { assert(glsl_type_is_array(parent->type) || @@ -858,7 +883,8 @@ nir_build_deref_struct(nir_builder *build, nir_deref_instr *parent, static inline nir_deref_instr * nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, - nir_variable_mode mode, const struct glsl_type *type) + nir_variable_mode mode, const struct glsl_type *type, + unsigned ptr_stride) { nir_deref_instr *deref = nir_deref_instr_create(build->shader, nir_deref_type_cast); @@ -866,6 +892,7 @@ nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, deref->mode = mode; deref->type = type; deref->parent = nir_src_for_ssa(parent); + deref->cast.ptr_stride = ptr_stride; nir_ssa_dest_init(&deref->instr, &deref->dest, parent->num_components, parent->bit_size, NULL); diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index 989c5051a54..e690b9165c9 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -311,15 +311,19 @@ clone_deref_instr(clone_state *state, const nir_deref_instr *deref) break; case nir_deref_type_array: + case nir_deref_type_ptr_as_array: __clone_src(state, &nderef->instr, &nderef->arr.index, &deref->arr.index); break; case nir_deref_type_array_wildcard: - case nir_deref_type_cast: /* Nothing to do */ break; + case nir_deref_type_cast: + nderef->cast.ptr_stride = deref->cast.ptr_stride; + break; + default: unreachable("Invalid instruction deref type"); } diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index 1dffa285037..76bad2dd9db 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -111,7 +111,8 @@ nir_deref_instr_has_indirect(nir_deref_instr *instr) if (instr->deref_type == nir_deref_type_cast) return true; - if (instr->deref_type == nir_deref_type_array && + if ((instr->deref_type == nir_deref_type_array || + instr->deref_type == nir_deref_type_ptr_as_array) && !nir_src_is_const(instr->arr.index)) return true; @@ -121,6 +122,23 @@ nir_deref_instr_has_indirect(nir_deref_instr *instr) return false; } +unsigned +nir_deref_instr_ptr_as_array_stride(nir_deref_instr *deref) +{ + assert(deref->deref_type == nir_deref_type_ptr_as_array); + nir_deref_instr *parent = nir_deref_instr_parent(deref); + switch (parent->deref_type) { + case nir_deref_type_array: + return glsl_get_explicit_stride(nir_deref_instr_parent(parent)->type); + case nir_deref_type_ptr_as_array: + return nir_deref_instr_ptr_as_array_stride(parent); + case nir_deref_type_cast: + return parent->cast.ptr_stride; + default: + unreachable("Invalid parent for ptr_as_array deref"); + } +} + static unsigned type_get_array_stride(const struct glsl_type *elem_type, glsl_type_size_align_func size_align) diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c index 2a9e3396985..060bd9eee0b 100644 --- a/src/compiler/nir/nir_instr_set.c +++ b/src/compiler/nir/nir_instr_set.c @@ -96,12 +96,16 @@ hash_deref(uint32_t hash, const nir_deref_instr *instr) break; case nir_deref_type_array: + case nir_deref_type_ptr_as_array: hash = hash_src(hash, &instr->arr.index); break; + case nir_deref_type_cast: + hash = HASH(hash, instr->cast.ptr_stride); + break; + case nir_deref_type_var: case nir_deref_type_array_wildcard: - case nir_deref_type_cast: /* Nothing to do */ break; @@ -351,13 +355,18 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2) break; case nir_deref_type_array: + case nir_deref_type_ptr_as_array: if (!nir_srcs_equal(deref1->arr.index, deref2->arr.index)) return false; break; + case nir_deref_type_cast: + if (deref1->cast.ptr_stride != deref2->cast.ptr_stride) + return false; + break; + case nir_deref_type_var: case nir_deref_type_array_wildcard: - case nir_deref_type_cast: /* Nothing to do */ break; diff --git a/src/compiler/nir/nir_opt_copy_propagate.c b/src/compiler/nir/nir_opt_copy_propagate.c index 7673e9b62dd..fcb85d15535 100644 --- a/src/compiler/nir/nir_opt_copy_propagate.c +++ b/src/compiler/nir/nir_opt_copy_propagate.c @@ -224,7 +224,8 @@ copy_prop_instr(nir_instr *instr) progress = true; } - if (deref->deref_type == nir_deref_type_array) { + if (deref->deref_type == nir_deref_type_array || + deref->deref_type == nir_deref_type_ptr_as_array) { while (copy_prop_src(&deref->arr.index, instr, NULL, 1)) progress = true; } diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 95d9bc85656..a73b9d37ae5 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -636,7 +636,8 @@ print_deref_link(const nir_deref_instr *instr, bool whole_chain, print_state *st glsl_get_struct_elem_name(parent->type, instr->strct.index)); break; - case nir_deref_type_array: { + case nir_deref_type_array: + case nir_deref_type_ptr_as_array: { nir_const_value *const_index = nir_src_as_const_value(instr->arr.index); if (const_index) { fprintf(fp, "[%u]", const_index->u32[0]); @@ -678,6 +679,9 @@ print_deref_instr(nir_deref_instr *instr, print_state *state) case nir_deref_type_cast: fprintf(fp, " = deref_cast "); break; + case nir_deref_type_ptr_as_array: + fprintf(fp, " = deref_ptr_as_array "); + break; default: unreachable("Invalid deref instruction type"); } diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index 43016310048..b4187213716 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -438,11 +438,15 @@ write_deref(write_ctx *ctx, const nir_deref_instr *deref) break; case nir_deref_type_array: + case nir_deref_type_ptr_as_array: write_src(ctx, &deref->arr.index); break; - case nir_deref_type_array_wildcard: case nir_deref_type_cast: + blob_write_uint32(ctx->blob, deref->cast.ptr_stride); + break; + + case nir_deref_type_array_wildcard: /* Nothing to do */ break; @@ -475,11 +479,15 @@ read_deref(read_ctx *ctx) break; case nir_deref_type_array: + case nir_deref_type_ptr_as_array: read_src(ctx, &deref->arr.index, &deref->instr); break; - case nir_deref_type_array_wildcard: case nir_deref_type_cast: + deref->cast.ptr_stride = blob_read_uint32(ctx->blob); + break; + + case nir_deref_type_array_wildcard: /* Nothing to do */ break; diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index ccd0cf782fe..9f8455d21cc 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -470,6 +470,19 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state) } break; + case nir_deref_type_ptr_as_array: + /* ptr_as_array derefs must have a parent that is either an array, + * ptr_as_array, or cast. If the parent is a cast, we get the stride + * information (if any) from the cast deref. + */ + validate_assert(state, + parent->deref_type == nir_deref_type_array || + parent->deref_type == nir_deref_type_ptr_as_array || + parent->deref_type == nir_deref_type_cast); + validate_src(&instr->arr.index, state, + nir_dest_bit_size(instr->dest), 1); + break; + default: unreachable("Invalid deref instruction type"); } diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index ab0d42942f2..9cec036d462 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -884,7 +884,7 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list, glsl_get_bare_type(b->func->type->return_type->type); nir_deref_instr *ret_deref = nir_build_deref_cast(&b->nb, nir_load_param(&b->nb, 0), - nir_var_local, ret_type); + nir_var_local, ret_type, 0); vtn_local_store(b, src, ret_deref); } diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 6e96cb606b4..3041fa47ec1 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1627,7 +1627,7 @@ vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa, assert(!vtn_pointer_is_external_block(b, ptr)); const struct glsl_type *deref_type = ptr_type->deref->type; ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode, - glsl_get_bare_type(deref_type)); + glsl_get_bare_type(deref_type), 0); } return ptr; |