+struct vtn_value *
+vtn_push_ssa_value(struct vtn_builder *b, uint32_t value_id,
+ struct vtn_ssa_value *ssa)
+{
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+
+ /* See vtn_create_ssa_value */
+ vtn_fail_if(ssa->type != glsl_get_bare_type(type->type),
+ "Type mismatch for SPIR-V SSA value");
+
+ struct vtn_value *val;
+ if (type->base_type == vtn_base_type_pointer) {
+ val = vtn_push_pointer(b, value_id, vtn_pointer_from_ssa(b, ssa->def, type));
+ } else {
+ /* Don't trip the value_type_ssa check in vtn_push_value */
+ val = vtn_push_value(b, value_id, vtn_value_type_invalid);
+ val->value_type = vtn_value_type_ssa;
+ val->ssa = ssa;
+ }
+
+ return val;
+}
+
+nir_ssa_def *
+vtn_get_nir_ssa(struct vtn_builder *b, uint32_t value_id)
+{
+ struct vtn_ssa_value *ssa = vtn_ssa_value(b, value_id);
+ vtn_fail_if(!glsl_type_is_vector_or_scalar(ssa->type),
+ "Expected a vector or scalar type");
+ return ssa->def;
+}
+
+struct vtn_value *
+vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id, nir_ssa_def *def)
+{
+ /* Types for all SPIR-V SSA values are set as part of a pre-pass so the
+ * type will be valid by the time we get here.
+ */
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+ vtn_fail_if(def->num_components != glsl_get_vector_elements(type->type) ||
+ def->bit_size != glsl_get_bit_size(type->type),
+ "Mismatch between NIR and SPIR-V type.");
+ struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, type->type);
+ ssa->def = def;
+ return vtn_push_ssa_value(b, value_id, ssa);
+}
+
+static nir_deref_instr *
+vtn_get_image(struct vtn_builder *b, uint32_t value_id)
+{
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+ vtn_assert(type->base_type == vtn_base_type_image);
+ return nir_build_deref_cast(&b->nb, vtn_get_nir_ssa(b, value_id),
+ nir_var_uniform, type->glsl_image, 0);
+}
+
+static void
+vtn_push_image(struct vtn_builder *b, uint32_t value_id,
+ nir_deref_instr *deref, bool propagate_non_uniform)
+{
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+ vtn_assert(type->base_type == vtn_base_type_image);
+ struct vtn_value *value = vtn_push_nir_ssa(b, value_id, &deref->dest.ssa);
+ value->propagated_non_uniform = propagate_non_uniform;
+}
+
+static nir_deref_instr *
+vtn_get_sampler(struct vtn_builder *b, uint32_t value_id)
+{
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+ vtn_assert(type->base_type == vtn_base_type_sampler);
+ return nir_build_deref_cast(&b->nb, vtn_get_nir_ssa(b, value_id),
+ nir_var_uniform, glsl_bare_sampler_type(), 0);
+}
+
+nir_ssa_def *
+vtn_sampled_image_to_nir_ssa(struct vtn_builder *b,
+ struct vtn_sampled_image si)
+{
+ return nir_vec2(&b->nb, &si.image->dest.ssa, &si.sampler->dest.ssa);
+}
+
+static void
+vtn_push_sampled_image(struct vtn_builder *b, uint32_t value_id,
+ struct vtn_sampled_image si, bool propagate_non_uniform)
+{
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+ vtn_assert(type->base_type == vtn_base_type_sampled_image);
+ struct vtn_value *value = vtn_push_nir_ssa(b, value_id,
+ vtn_sampled_image_to_nir_ssa(b, si));
+ value->propagated_non_uniform = propagate_non_uniform;
+}
+
+static struct vtn_sampled_image
+vtn_get_sampled_image(struct vtn_builder *b, uint32_t value_id)
+{
+ struct vtn_type *type = vtn_get_value_type(b, value_id);
+ vtn_assert(type->base_type == vtn_base_type_sampled_image);
+ nir_ssa_def *si_vec2 = vtn_get_nir_ssa(b, value_id);
+
+ struct vtn_sampled_image si = { NULL, };
+ si.image = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 0),
+ nir_var_uniform,
+ type->image->glsl_image, 0);
+ si.sampler = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 1),
+ nir_var_uniform,
+ glsl_bare_sampler_type(), 0);
+ return si;
+}
+
+static const char *