From bb8cadd169782f463f79c70f5478ccd8f13826da Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 18 Jan 2016 15:00:01 -0800 Subject: [PATCH] nir/spirv: Insert movs around image intrinsics Image intrinsics always take a vec4 coordinate and always return a vec4. This simplifies the intrinsics a but but also means that they don't actually match the incomming SPIR-V. In order to compensate for this, we add swizzling movs for both source and destination to get the right number of components. --- src/glsl/nir/spirv/spirv_to_nir.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/glsl/nir/spirv/spirv_to_nir.c b/src/glsl/nir/spirv/spirv_to_nir.c index dc95b40f9c3..ef24156a48e 100644 --- a/src/glsl/nir/spirv/spirv_to_nir.c +++ b/src/glsl/nir/spirv/spirv_to_nir.c @@ -2650,7 +2650,15 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode, nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op); intrin->variables[0] = nir_deref_as_var(nir_copy_deref(&intrin->instr, &image.deref->deref)); - intrin->src[0] = nir_src_for_ssa(image.coord); + + /* The image coordinate is always 4 components but we may not have that + * many. Swizzle to compensate. + */ + unsigned swiz[4]; + for (unsigned i = 0; i < 4; i++) + swiz[i] = i < image.coord->num_components ? i : 0; + intrin->src[0] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord, + swiz, 4, false)); intrin->src[1] = nir_src_for_ssa(image.sample); switch (opcode) { @@ -2694,13 +2702,20 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode, if (opcode != SpvOpImageWrite) { 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; - nir_ssa_dest_init(&intrin->instr, &intrin->dest, - glsl_get_vector_elements(type->type), NULL); + nir_ssa_dest_init(&intrin->instr, &intrin->dest, 4, NULL); + + nir_builder_instr_insert(&b->nb, &intrin->instr); + + /* The image intrinsics always return 4 channels but we may not want + * that many. Emit a mov to trim it down. + */ + unsigned swiz[4] = {0, 1, 2, 3}; val->ssa = vtn_create_ssa_value(b, type->type); - val->ssa->def = &intrin->dest.ssa; + val->ssa->def = nir_swizzle(&b->nb, &intrin->dest.ssa, swiz, + glsl_get_vector_elements(type->type), false); + } else { + nir_builder_instr_insert(&b->nb, &intrin->instr); } - - nir_builder_instr_insert(&b->nb, &intrin->instr); } static void -- 2.30.2