<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Sun, Jul 15, 2018 at 3:11 AM Bas Nieuwenhuizen <<a href="mailto:bas@basnieuwenhuizen.nl">bas@basnieuwenhuizen.nl</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sun, Jul 15, 2018 at 3:56 AM, Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>> wrote:<br>
> For one thing, the NIR opcodes for image load/store always take and<br>
> return a vec4 value regardless of the image type. We need to fix up<br>
> both the source and destination to handle it. For another thing, we<br>
> weren't actually setting up a destination in the OpAtomicLoad case.<br>
<br>
Nominate for stable? I actually encountered this in an application.<br>
<br>
> ---<br>
> src/compiler/spirv/spirv_to_nir.c | 44 +++++++++++++++++++------------<br>
> 1 file changed, 27 insertions(+), 17 deletions(-)<br>
><br>
> diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c<br>
> index c31293a77be..a204bfa39ba 100644<br>
> --- a/src/compiler/spirv/spirv_to_nir.c<br>
> +++ b/src/compiler/spirv/spirv_to_nir.c<br>
> @@ -2309,6 +2309,15 @@ get_image_coord(struct vtn_builder *b, uint32_t value)<br>
> return nir_swizzle(&b->nb, coord->def, swizzle, 4, false);<br>
> }<br>
><br>
> +static nir_ssa_def *<br>
> +expand_to_vec4(nir_builder *b, nir_ssa_def *value)<br>
> +{<br>
> + unsigned swiz[4];<br>
> + for (unsigned i = 0; i < 4; i++)<br>
> + swiz[i] = i < value->num_components ? i : 0;<br>
> + return nir_swizzle(b, value, swiz, 4, false);<br>
<br>
Maybe skip if value already has 4 components?<br></blockquote><div><br></div><div>Done.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Either way,<br>
</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reviewed-by: Bas Nieuwenhuizen <<a href="mailto:bas@basnieuwenhuizen.nl" target="_blank">bas@basnieuwenhuizen.nl</a>><br></blockquote><div><br></div><div>Thanks! I'll push in the morning assuming my Jenkins run is happy.</div><div><br></div><div>--Uason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> +}<br>
> +<br>
> static void<br>
> vtn_handle_image(struct vtn_builder *b, SpvOp opcode,<br>
> const uint32_t *w, unsigned count)<br>
> @@ -2422,11 +2431,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,<br>
> /* The image coordinate is always 4 components but we may not have that<br>
> * many. Swizzle to compensate.<br>
> */<br>
> - unsigned swiz[4];<br>
> - for (unsigned i = 0; i < 4; i++)<br>
> - swiz[i] = i < image.coord->num_components ? i : 0;<br>
> - intrin->src[1] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,<br>
> - swiz, 4, false));<br>
> + intrin->src[1] = nir_src_for_ssa(expand_to_vec4(&b->nb, image.coord));<br>
> intrin->src[2] = nir_src_for_ssa(image.sample);<br>
> }<br>
><br>
> @@ -2436,11 +2441,13 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,<br>
> case SpvOpImageRead:<br>
> break;<br>
> case SpvOpAtomicStore:<br>
> - intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);<br>
> - break;<br>
> - case SpvOpImageWrite:<br>
> - intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);<br>
> + case SpvOpImageWrite: {<br>
> + const uint32_t value_id = opcode == SpvOpAtomicStore ? w[4] : w[3];<br>
> + nir_ssa_def *value = vtn_ssa_value(b, value_id)->def;<br>
> + /* nir_intrinsic_image_deref_store always takes a vec4 value */<br>
> + intrin->src[3] = nir_src_for_ssa(expand_to_vec4(&b->nb, value));<br>
> break;<br>
> + }<br>
><br>
> case SpvOpAtomicCompareExchange:<br>
> case SpvOpAtomicIIncrement:<br>
> @@ -2462,23 +2469,26 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,<br>
> vtn_fail("Invalid image opcode");<br>
> }<br>
><br>
> - if (opcode != SpvOpImageWrite) {<br>
> + if (opcode != SpvOpImageWrite && opcode != SpvOpAtomicStore) {<br>
> struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);<br>
> struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;<br>
><br>
> - unsigned dest_components = nir_intrinsic_dest_components(intrin);<br>
> - if (intrin->intrinsic == nir_intrinsic_image_deref_size) {<br>
> - dest_components = intrin->num_components =<br>
> - glsl_get_vector_elements(type->type);<br>
> - }<br>
> + unsigned dest_components = glsl_get_vector_elements(type->type);<br>
> + intrin->num_components = nir_intrinsic_infos[op].dest_components;<br>
> + if (intrin->num_components == 0)<br>
> + intrin->num_components = dest_components;<br>
><br>
> nir_ssa_dest_init(&intrin->instr, &intrin->dest,<br>
> - dest_components, 32, NULL);<br>
> + intrin->num_components, 32, NULL);<br>
><br>
> nir_builder_instr_insert(&b->nb, &intrin->instr);<br>
><br>
> + nir_ssa_def *result = &intrin->dest.ssa;<br>
> + if (intrin->num_components != dest_components)<br>
> + result = nir_channels(&b->nb, result, (1 << dest_components) - 1);<br>
> +<br>
> val->ssa = vtn_create_ssa_value(b, type->type);<br>
> - val->ssa->def = &intrin->dest.ssa;<br>
> + val->ssa->def = result;<br>
> } else {<br>
> nir_builder_instr_insert(&b->nb, &intrin->instr);<br>
> }<br>
> --<br>
> 2.17.1<br>
><br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div></div>