From 86b53770e1ea6e79452ccc97bab829ad58ffc5fd Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 1 Jul 2019 14:57:54 +0300 Subject: [PATCH] spirv: wrap push ssa/pointer values This refactor allows for common code to apply decoration on all ssa/pointer values. In particular this will allow to propagage access qualifiers. Signed-off-by: Lionel Landwerlin Suggested-by: Caio Marcelo de Oliveira Filho Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/spirv/spirv_to_nir.c | 82 +++++++++++++++--------------- src/compiler/spirv/vtn_cfg.c | 9 +--- src/compiler/spirv/vtn_private.h | 27 +++++----- src/compiler/spirv/vtn_variables.c | 40 ++++++++++++--- 4 files changed, 89 insertions(+), 69 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 76ccbfad514..c2528cef35a 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2060,19 +2060,17 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, vtn_value(b, w[4], vtn_value_type_pointer)->pointer; return; } else if (opcode == SpvOpImage) { - struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer); struct vtn_value *src_val = vtn_untyped_value(b, w[3]); if (src_val->value_type == vtn_value_type_sampled_image) { - val->pointer = src_val->sampled_image->image; + vtn_push_value_pointer(b, w[2], src_val->sampled_image->image); } else { vtn_assert(src_val->value_type == vtn_value_type_pointer); - val->pointer = src_val->pointer; + vtn_push_value_pointer(b, w[2], src_val->pointer); } return; } struct vtn_type *ret_type = vtn_value(b, w[1], vtn_value_type_type)->type; - struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); struct vtn_sampled_image sampled; struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]); @@ -2385,8 +2383,9 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, } } - val->ssa = vtn_create_ssa_value(b, ret_type->type); - val->ssa->def = &instr->dest.ssa; + struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, ret_type->type); + ssa->def = &instr->dest.ssa; + vtn_push_ssa(b, w[2], ret_type, ssa); nir_builder_instr_insert(&b->nb, &instr->instr); } @@ -2614,7 +2613,6 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode, } if (opcode != SpvOpImageWrite && opcode != SpvOpAtomicStore) { - struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type; unsigned dest_components = glsl_get_vector_elements(type->type); @@ -2631,7 +2629,8 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode, if (intrin->num_components != dest_components) result = nir_channels(&b->nb, result, (1 << dest_components) - 1); - val->ssa = vtn_create_ssa_value(b, type->type); + struct vtn_value *val = + vtn_push_ssa(b, w[2], type, vtn_create_ssa_value(b, type->type)); val->ssa->def = result; } else { nir_builder_instr_insert(&b->nb, &intrin->instr); @@ -2942,10 +2941,10 @@ vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode, glsl_get_vector_elements(type->type), glsl_get_bit_size(type->type), NULL); - struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); - val->ssa = rzalloc(b, struct vtn_ssa_value); - val->ssa->def = &atomic->dest.ssa; - val->ssa->type = type->type; + struct vtn_ssa_value *ssa = rzalloc(b, struct vtn_ssa_value); + ssa->def = &atomic->dest.ssa; + ssa->type = type->type; + vtn_push_ssa(b, w[2], type, ssa); } nir_builder_instr_insert(&b->nb, &atomic->instr); @@ -3185,66 +3184,66 @@ static void vtn_handle_composite(struct vtn_builder *b, SpvOp opcode, const uint32_t *w, unsigned count) { - struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); - const struct glsl_type *type = - vtn_value(b, w[1], vtn_value_type_type)->type->type; - val->ssa = vtn_create_ssa_value(b, type); + struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type; + struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, type->type); switch (opcode) { case SpvOpVectorExtractDynamic: - val->ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def, - vtn_ssa_value(b, w[4])->def); + ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def, + vtn_ssa_value(b, w[4])->def); break; case SpvOpVectorInsertDynamic: - val->ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def, - vtn_ssa_value(b, w[4])->def, - vtn_ssa_value(b, w[5])->def); + ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def, + vtn_ssa_value(b, w[4])->def, + vtn_ssa_value(b, w[5])->def); break; case SpvOpVectorShuffle: - val->ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type), - vtn_ssa_value(b, w[3])->def, - vtn_ssa_value(b, w[4])->def, - w + 5); + ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type->type), + vtn_ssa_value(b, w[3])->def, + vtn_ssa_value(b, w[4])->def, + w + 5); break; case SpvOpCompositeConstruct: { unsigned elems = count - 3; assume(elems >= 1); - if (glsl_type_is_vector_or_scalar(type)) { + if (glsl_type_is_vector_or_scalar(type->type)) { nir_ssa_def *srcs[NIR_MAX_VEC_COMPONENTS]; for (unsigned i = 0; i < elems; i++) srcs[i] = vtn_ssa_value(b, w[3 + i])->def; - val->ssa->def = - vtn_vector_construct(b, glsl_get_vector_elements(type), + ssa->def = + vtn_vector_construct(b, glsl_get_vector_elements(type->type), elems, srcs); } else { - val->ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems); + ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems); for (unsigned i = 0; i < elems; i++) - val->ssa->elems[i] = vtn_ssa_value(b, w[3 + i]); + ssa->elems[i] = vtn_ssa_value(b, w[3 + i]); } break; } case SpvOpCompositeExtract: - val->ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]), - w + 4, count - 4); + ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]), + w + 4, count - 4); break; case SpvOpCompositeInsert: - val->ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]), - vtn_ssa_value(b, w[3]), - w + 5, count - 5); + ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]), + vtn_ssa_value(b, w[3]), + w + 5, count - 5); break; case SpvOpCopyLogical: case SpvOpCopyObject: - val->ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3])); + ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3])); break; default: vtn_fail_with_opcode("unknown composite operation", opcode); } + + vtn_push_ssa(b, w[2], type, ssa); } static void @@ -4194,8 +4193,9 @@ vtn_handle_ptr(struct vtn_builder *b, SpvOp opcode, "%s operands must have the same storage class", spirv_op_to_string(opcode)); - const struct glsl_type *type = - vtn_value(b, w[1], vtn_value_type_type)->type->type; + struct vtn_type *vtn_type = + vtn_value(b, w[1], vtn_value_type_type)->type; + const struct glsl_type *type = vtn_type->type; nir_address_format addr_format = vtn_mode_to_address_format( b, vtn_storage_class_to_mode(b, type1->storage_class, NULL, NULL)); @@ -4233,9 +4233,9 @@ vtn_handle_ptr(struct vtn_builder *b, SpvOp opcode, unreachable("Invalid ptr operation"); } - struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); - val->ssa = vtn_create_ssa_value(b, type); - val->ssa->def = def; + struct vtn_ssa_value *ssa_value = vtn_create_ssa_value(b, type); + ssa_value->def = def; + vtn_push_ssa(b, w[2], vtn_type, ssa_value); } static bool diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index 87c3fde3f31..db3c46a0de6 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -328,17 +328,12 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode, } else if (type->base_type == vtn_base_type_pointer && type->type != NULL) { /* This is a pointer with an actual storage type */ - struct vtn_value *val = - vtn_push_value(b, w[2], vtn_value_type_pointer); nir_ssa_def *ssa_ptr = nir_load_param(&b->nb, b->func_param_idx++); - val->pointer = vtn_pointer_from_ssa(b, ssa_ptr, type); + vtn_push_value_pointer(b, w[2], vtn_pointer_from_ssa(b, ssa_ptr, type)); } else if (type->base_type == vtn_base_type_pointer || type->base_type == vtn_base_type_image || type->base_type == vtn_base_type_sampler) { - struct vtn_value *val = - vtn_push_value(b, w[2], vtn_value_type_pointer); - val->pointer = - vtn_load_param_pointer(b, type, b->func_param_idx++); + vtn_push_value_pointer(b, w[2], vtn_load_param_pointer(b, type, b->func_param_idx++)); } else { /* We're a regular SSA value. */ struct vtn_ssa_value *value = vtn_create_ssa_value(b, type->type); diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index cd534e6829c..5998196a838 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -655,6 +655,10 @@ vtn_untyped_value(struct vtn_builder *b, uint32_t value_id) return &b->values[value_id]; } +/* Consider not using this function directly and instead use + * vtn_push_ssa/vtn_push_value_pointer so that appropriate applying of + * decorations is handled by common code. + */ static inline struct vtn_value * vtn_push_value(struct vtn_builder *b, uint32_t value_id, enum vtn_value_type value_type) @@ -666,22 +670,8 @@ vtn_push_value(struct vtn_builder *b, uint32_t value_id, value_id); val->value_type = value_type; - return &b->values[value_id]; -} -static inline struct vtn_value * -vtn_push_ssa(struct vtn_builder *b, uint32_t value_id, - struct vtn_type *type, struct vtn_ssa_value *ssa) -{ - struct vtn_value *val; - if (type->base_type == vtn_base_type_pointer) { - val = vtn_push_value(b, value_id, vtn_value_type_pointer); - val->pointer = vtn_pointer_from_ssa(b, ssa->def, type); - } else { - val = vtn_push_value(b, value_id, vtn_value_type_ssa); - val->ssa = ssa; - } - return val; + return &b->values[value_id]; } static inline struct vtn_value * @@ -736,6 +726,13 @@ vtn_constant_int(struct vtn_builder *b, uint32_t value_id) struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id); +struct vtn_value *vtn_push_value_pointer(struct vtn_builder *b, + uint32_t value_id, + struct vtn_pointer *ptr); + +struct vtn_value *vtn_push_ssa(struct vtn_builder *b, uint32_t value_id, + struct vtn_type *type, struct vtn_ssa_value *ssa); + struct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type); diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 5bdfd758040..0b03c224af7 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -30,6 +30,35 @@ #include "nir_deref.h" #include +static void ptr_decoration_cb(struct vtn_builder *b, + struct vtn_value *val, int member, + const struct vtn_decoration *dec, + void *void_ptr); + +struct vtn_value * +vtn_push_value_pointer(struct vtn_builder *b, uint32_t value_id, + struct vtn_pointer *ptr) +{ + struct vtn_value *val = vtn_push_value(b, value_id, vtn_value_type_pointer); + val->pointer = ptr; + vtn_foreach_decoration(b, val, ptr_decoration_cb, ptr); + return val; +} + +struct vtn_value * +vtn_push_ssa(struct vtn_builder *b, uint32_t value_id, + struct vtn_type *type, struct vtn_ssa_value *ssa) +{ + struct vtn_value *val; + if (type->base_type == vtn_base_type_pointer) { + val = vtn_push_value_pointer(b, value_id, vtn_pointer_from_ssa(b, ssa->def, type)); + } else { + val = vtn_push_value(b, value_id, vtn_value_type_ssa); + val->ssa = ssa; + } + return val; +} + static struct vtn_access_chain * vtn_access_chain_create(struct vtn_builder *b, unsigned length) { @@ -2460,11 +2489,10 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, val->sampled_image->sampler); } else { vtn_assert(base_val->value_type == vtn_value_type_pointer); - struct vtn_value *val = - vtn_push_value(b, w[2], vtn_value_type_pointer); - val->pointer = vtn_pointer_dereference(b, base_val->pointer, chain); - val->pointer->ptr_type = ptr_type; - vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer); + struct vtn_pointer *ptr = + vtn_pointer_dereference(b, base_val->pointer, chain); + ptr->ptr_type = ptr_type; + vtn_push_value_pointer(b, w[2], ptr); } break; } @@ -2489,7 +2517,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, if (glsl_type_is_image(res_type->type) || glsl_type_is_sampler(res_type->type)) { - vtn_push_value(b, w[2], vtn_value_type_pointer)->pointer = src; + vtn_push_value_pointer(b, w[2], src); return; } -- 2.30.2