summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2018-07-06 14:41:12 -0700
committerDylan Baker <dylan@pnwbakers.com>2018-07-26 10:42:06 -0700
commit2cb3b5b319162126ef0f40c81416a0e530a1da7a (patch)
tree00f93b14a1b656f77dba89f6c4015387e7b64475
parent7c6ff66eba5fdd9646e92b5e7c3cf5256fdaf093 (diff)
spirv: Fix a couple of image atomic load/store bugs
For one thing, the NIR opcodes for image load/store always take and return a vec4 value regardless of the image type. We need to fix up both the source and destination to handle it. For another thing, we weren't actually setting up a destination in the OpAtomicLoad case. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Cc: mesa-stable@lists.freedesktop.org (cherry picked from commit 5e030deaf226a355f49647daeb60af33783fc0b7) Conflicts resolved by Dylan Conflicts: src/compiler/spirv/spirv_to_nir.c
-rw-r--r--src/compiler/spirv/spirv_to_nir.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 2a835f047e4..f62b0255c37 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -2278,6 +2278,18 @@ get_image_coord(struct vtn_builder *b, uint32_t value)
return nir_swizzle(&b->nb, coord->def, swizzle, 4, false);
}
+static nir_ssa_def *
+expand_to_vec4(nir_builder *b, nir_ssa_def *value)
+{
+ if (value->num_components == 4)
+ return value;
+
+ unsigned swiz[4];
+ for (unsigned i = 0; i < 4; i++)
+ swiz[i] = i < value->num_components ? i : 0;
+ return nir_swizzle(b, value, swiz, 4, false);
+}
+
static void
vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count)
@@ -2391,11 +2403,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
/* 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[0] = nir_src_for_ssa(expand_to_vec4(&b->nb, image.coord));
intrin->src[1] = nir_src_for_ssa(image.sample);
}
@@ -2405,11 +2413,13 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
case SpvOpImageRead:
break;
case SpvOpAtomicStore:
- intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
- break;
- case SpvOpImageWrite:
- intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
+ case SpvOpImageWrite: {
+ const uint32_t value_id = opcode == SpvOpAtomicStore ? w[4] : w[3];
+ nir_ssa_def *value = vtn_ssa_value(b, value_id)->def;
+ /* nir_intrinsic_image_deref_store always takes a vec4 value */
+ intrin->src[2] = nir_src_for_ssa(expand_to_vec4(&b->nb, value));
break;
+ }
case SpvOpAtomicCompareExchange:
case SpvOpAtomicIIncrement:
@@ -2431,23 +2441,26 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
vtn_fail("Invalid image opcode");
}
- if (opcode != SpvOpImageWrite) {
+ 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 = nir_intrinsic_dest_components(intrin);
- if (intrin->intrinsic == nir_intrinsic_image_var_size) {
- dest_components = intrin->num_components =
- glsl_get_vector_elements(type->type);
- }
+ unsigned dest_components = glsl_get_vector_elements(type->type);
+ intrin->num_components = nir_intrinsic_infos[op].dest_components;
+ if (intrin->num_components == 0)
+ intrin->num_components = dest_components;
nir_ssa_dest_init(&intrin->instr, &intrin->dest,
- dest_components, 32, NULL);
+ intrin->num_components, 32, NULL);
nir_builder_instr_insert(&b->nb, &intrin->instr);
+ nir_ssa_def *result = &intrin->dest.ssa;
+ 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);
- val->ssa->def = &intrin->dest.ssa;
+ val->ssa->def = result;
} else {
nir_builder_instr_insert(&b->nb, &intrin->instr);
}