Mesa (master): spirv: Sort out the mess that is sampled image
Module: Mesa Branch: master Commit: 9e440b8d0b982933650c7b600de1e4b6e33f9c7d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=9e440b8d0b982933650c7b600de1e4b6e33f9c7d Author: Jason Ekstrand Date: Thu Sep 26 11:56:48 2019 -0500 spirv: Sort out the mess that is sampled image This commit makes two major changes. First, we add a second case to OpLoad for sampled images which constructs a vtn_sampled_image and stashes that rather than stashing a pointer to the combined image sampler like we do for bare samplers and images. This should be more in line with how SPIR-V is intended to work and hopefully doesn't cause any weird problems. The second is a rework of vtn_handle_texture to assume that everything has an image but not everything has a sampler. We also add a vtn_fail_if for the case where a texture instructions require a sampler but none is provided. Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/spirv/spirv_to_nir.c | 28 +++- src/compiler/spirv/vtn_variables.c | 11 +-- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 013805b842a..d0dc40aff92 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2264,16 +2264,20 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, struct vtn_type *ret_type = vtn_value(b, w[1], vtn_value_type_type)->type; - struct vtn_sampled_image sampled; + struct vtn_pointer *image = NULL, *sampler = NULL; struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]); if (sampled_val->value_type == vtn_value_type_sampled_image) { - sampled = *sampled_val->sampled_image; + image = sampled_val->sampled_image->image; + sampler = sampled_val->sampled_image->sampler; } else { vtn_assert(sampled_val->value_type == vtn_value_type_pointer); - sampled.image = NULL; - sampled.sampler = sampled_val->pointer; + image = sampled_val->pointer; } + nir_deref_instr *image_deref = vtn_pointer_to_deref(b, image); + nir_deref_instr *sampler_deref = + sampler ? vtn_pointer_to_deref(b, sampler) : NULL; + const struct glsl_type *image_type = sampled_val->type->type; const enum glsl_sampler_dim sampler_dim = glsl_get_sampler_dim(image_type); const bool is_array = glsl_sampler_type_is_array(image_type); @@ -2337,11 +2341,7 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, nir_tex_src srcs[10]; /* 10 should be enough */ nir_tex_src *p = srcs; - nir_deref_instr *sampler = vtn_pointer_to_deref(b, sampled.sampler); - nir_deref_instr *texture = - sampled.image ? vtn_pointer_to_deref(b, sampled.image) : sampler; - - p->src = nir_src_for_ssa(>dest.ssa); + p->src = nir_src_for_ssa(_deref->dest.ssa); p->src_type = nir_tex_src_texture_deref; p++; @@ -2352,8 +2352,10 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, case nir_texop_txd: case nir_texop_tg4: case nir_texop_lod: - /* These operations require a sampler */ - p->src = nir_src_for_ssa(>dest.ssa); + vtn_fail_if(sampler == NULL, + "%s requires an image of type OpTypeSampledImage", + spirv_op_to_string(opcode)); + p->src = nir_src_for_ssa(_deref->dest.ssa); p->src_type = nir_tex_src_sampler_deref; p++; break; @@ -2554,10 +2556,10 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, is_shadow && glsl_get_components(ret_type->type) == 1; instr->component = gather_component; - if (sampled.image && (sampled.image->access & ACCESS_NON_UNIFORM)) + if (image && (image->access & ACCESS_NON_UNIFORM)) instr->texture_non_uniform = true; - if (sampled.sampler && (sampled.sampler->access & ACCESS_NON_UNIFORM)) + if (sampler && (sampler->access & ACCESS_NON_UNIFORM)) instr->sampler_non_uniform = true; /* for non-query ops, get dest_type from sampler type */ diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 0603e9d0c84..944d1f006d6 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -2541,10 +2541,17 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, vtn_assert_types_equal(b, opcode, res_type, src_val->type->deref); - if (glsl_type_is_image(res_type->type) || - glsl_type_is_sampler(res_type->type)) { + if (res_type->base_type == vtn_base_type_image || + res_type->base_type == vtn_base_type_sampler) { vtn_push_value_pointer(b, w[2], src); return; + } else if (res_type->base_type == vtn_base_type_sampled_image) { + struct vtn_value *val = +vtn_push_value(b, w[2], vtn_value_type_sampled_image); + val->sampled_image = ralloc(b, struct vtn_sampled_image); + val->sampled_image->image = val->sampled_image->sampler = +
Mesa (master): spirv: Add a vtn_decorate_pointer helper
Module: Mesa Branch: master Commit: 9cc4c2c91649be6eb0b0a3f56eeb4ce3696a79a3 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=9cc4c2c91649be6eb0b0a3f56eeb4ce3696a79a3 Author: Jason Ekstrand Date: Mon Nov 4 16:44:30 2019 -0600 spirv: Add a vtn_decorate_pointer helper This helper makes a duplicate copy of the pointer if any new access flags are set at this stage. This way we don't end up propagating access flags further than they actual SPIR-V decorations. In several instances where we create new pointers, we still call the decoration helper directly because no copy is needed. Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/spirv/vtn_variables.c | 67 +++--- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 1028199d310..0603e9d0c84 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -30,18 +30,49 @@ #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); +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_pointer *ptr = void_ptr; + + switch (dec->decoration) { + case SpvDecorationNonUniformEXT: + ptr->access |= ACCESS_NON_UNIFORM; + break; + + default: + break; + } +} + +static struct vtn_pointer* +vtn_decorate_pointer(struct vtn_builder *b, struct vtn_value *val, + struct vtn_pointer *ptr) +{ + struct vtn_pointer dummy = { }; + vtn_foreach_decoration(b, val, ptr_decoration_cb, ); + + /* If we're adding access flags, make a copy of the pointer. We could +* probably just OR them in without doing so but this prevents us from +* leaking them any further than actually specified in the SPIR-V. +*/ + if (dummy.access & ~ptr->access) { + struct vtn_pointer *copy = ralloc(b, struct vtn_pointer); + *copy = *ptr; + copy->access |= dummy.access; + return copy; + } + + return 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); + val->pointer = vtn_decorate_pointer(b, val, ptr); return val; } @@ -1753,22 +1784,6 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, } } -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_pointer *ptr = void_ptr; - - switch (dec->decoration) { - case SpvDecorationNonUniformEXT: - ptr->access |= ACCESS_NON_UNIFORM; - break; - - default: - break; - } -} - enum vtn_variable_mode vtn_storage_class_to_mode(struct vtn_builder *b, SpvStorageClass class, @@ -2493,10 +2508,10 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, val->sampled_image->image = vtn_pointer_dereference(b, base_val->sampled_image->image, chain); val->sampled_image->sampler = base_val->sampled_image->sampler; - vtn_foreach_decoration(b, val, ptr_decoration_cb, -val->sampled_image->image); - vtn_foreach_decoration(b, val, ptr_decoration_cb, -val->sampled_image->sampler); + val->sampled_image->image = +vtn_decorate_pointer(b, val, val->sampled_image->image); + val->sampled_image->sampler = +vtn_decorate_pointer(b, val, val->sampled_image->sampler); } else { vtn_assert(base_val->value_type == vtn_value_type_pointer); struct vtn_pointer *ptr = ___ mesa-commit mailing list mesa-commit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-commit
Mesa (master): spirv: Remove the type from sampled_image
Module: Mesa Branch: master Commit: 4f9688e5719bfa49b36ed38dc14e57af8aa41050 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4f9688e5719bfa49b36ed38dc14e57af8aa41050 Author: Jason Ekstrand Date: Thu Sep 26 11:48:44 2019 -0500 spirv: Remove the type from sampled_image We have types on all vtn_values at this point so there's no reason to carry the redundant type information. Reviewed-by: Caio Marcelo de Oliveira Filho --- src/compiler/spirv/spirv_to_nir.c | 7 ++- src/compiler/spirv/vtn_cfg.c | 1 - src/compiler/spirv/vtn_private.h | 1 - src/compiler/spirv/vtn_variables.c | 1 - 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index eeca640ba49..013805b842a 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2246,8 +2246,6 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_sampled_image); val->sampled_image = ralloc(b, struct vtn_sampled_image); - val->sampled_image->type = - vtn_value(b, w[1], vtn_value_type_type)->type; val->sampled_image->image = vtn_value(b, w[3], vtn_value_type_pointer)->pointer; val->sampled_image->sampler = @@ -2272,12 +2270,11 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, sampled = *sampled_val->sampled_image; } else { vtn_assert(sampled_val->value_type == vtn_value_type_pointer); - sampled.type = sampled_val->pointer->type; sampled.image = NULL; sampled.sampler = sampled_val->pointer; } - const struct glsl_type *image_type = sampled.type->type; + const struct glsl_type *image_type = sampled_val->type->type; const enum glsl_sampler_dim sampler_dim = glsl_get_sampler_dim(image_type); const bool is_array = glsl_sampler_type_is_array(image_type); nir_alu_type dest_type = nir_type_invalid; @@ -2300,7 +2297,7 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, break; case SpvOpImageFetch: - if (glsl_get_sampler_dim(image_type) == GLSL_SAMPLER_DIM_MS) { + if (sampler_dim == GLSL_SAMPLER_DIM_MS) { texop = nir_texop_txf_ms; } else { texop = nir_texop_txf; diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index a6451490081..cf67893c6c8 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -315,7 +315,6 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode, vtn_push_value(b, w[2], vtn_value_type_sampled_image); val->sampled_image = ralloc(b, struct vtn_sampled_image); - val->sampled_image->type = type; struct vtn_type *sampler_type = rzalloc(b, struct vtn_type); sampler_type->base_type = vtn_base_type_sampler; diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index db6242fa85a..7c7527582b4 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -537,7 +537,6 @@ struct vtn_image_pointer { }; struct vtn_sampled_image { - struct vtn_type *type; struct vtn_pointer *image; /* Image or array of images */ struct vtn_pointer *sampler; /* Sampler */ }; diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index af611b68b13..1028199d310 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -2490,7 +2490,6 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_sampled_image); val->sampled_image = ralloc(b, struct vtn_sampled_image); - val->sampled_image->type = base_val->sampled_image->type; val->sampled_image->image = vtn_pointer_dereference(b, base_val->sampled_image->image, chain); val->sampled_image->sampler = base_val->sampled_image->sampler; ___ mesa-commit mailing list mesa-commit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-commit