summaryrefslogtreecommitdiffstats
path: root/src/compiler/spirv
diff options
context:
space:
mode:
authorSamuel Iglesias Gonsálvez <[email protected]>2016-11-21 16:13:46 +0100
committerSamuel Iglesias Gonsálvez <[email protected]>2017-01-09 09:10:13 +0100
commita9663878835b14051fbd79f644bae3f23daf1787 (patch)
tree72f99b8739bc02e3db8d397ebc5f9cb425f2f619 /src/compiler/spirv
parentec686ff62c840e8a5766f1c9dc80f09cba8af73a (diff)
spirv: fix SpvOpSpecConstantOp with SpvOpVectorShuffle working with double-based vecs
We need to pick two 32-bit values per component to perform the right shuffle operation. v2 (Jason): - Add assert to check matching bit sizes (Jason) - Simplify the code to pick components (Jason) v3: - Switch on bit_size once (Jason) - Add comment to explain the constant value for unused components (Erik) Signed-off-by: Samuel Iglesias Gonsálvez <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/compiler/spirv')
-rw-r--r--src/compiler/spirv/spirv_to_nir.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index b44b8e823d2..82d67fa8886 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1076,18 +1076,46 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
unsigned len0 = glsl_get_vector_elements(v0->const_type);
unsigned len1 = glsl_get_vector_elements(v1->const_type);
- uint32_t u[8];
- for (unsigned i = 0; i < len0; i++)
- u[i] = v0->constant->values[0].u32[i];
- for (unsigned i = 0; i < len1; i++)
- u[len0 + i] = v1->constant->values[0].u32[i];
-
- for (unsigned i = 0; i < count - 6; i++) {
- uint32_t comp = w[i + 6];
- if (comp == (uint32_t)-1) {
- val->constant->values[0].u32[i] = 0xdeadbeef;
- } else {
- val->constant->values[0].u32[i] = u[comp];
+ assert(len0 + len1 < 16);
+
+ unsigned bit_size = glsl_get_bit_size(val->const_type);
+ assert(bit_size == glsl_get_bit_size(v0->const_type) &&
+ bit_size == glsl_get_bit_size(v1->const_type));
+
+ if (bit_size == 64) {
+ uint64_t u64[8];
+ for (unsigned i = 0; i < len0; i++)
+ u64[i] = v0->constant->values[0].u64[i];
+ for (unsigned i = 0; i < len1; i++)
+ u64[len0 + i] = v1->constant->values[0].u64[i];
+
+ for (unsigned i = 0, j = 0; i < count - 6; i++, j++) {
+ uint32_t comp = w[i + 6];
+ /* If component is not used, set the value to a known constant
+ * to detect if it is wrongly used.
+ */
+ if (comp == (uint32_t)-1)
+ val->constant->values[0].u64[j] = 0xdeadbeefdeadbeef;
+ else
+ val->constant->values[0].u64[j] = u64[comp];
+ }
+ } else {
+ uint32_t u32[8];
+ for (unsigned i = 0; i < len0; i++)
+ u32[i] = v0->constant->values[0].u32[i];
+
+ for (unsigned i = 0; i < len1; i++)
+ u32[len0 + i] = v1->constant->values[0].u32[i];
+
+ for (unsigned i = 0, j = 0; i < count - 6; i++, j++) {
+ uint32_t comp = w[i + 6];
+ /* If component is not used, set the value to a known constant
+ * to detect if it is wrongly used.
+ */
+ if (comp == (uint32_t)-1)
+ val->constant->values[0].u32[j] = 0xdeadbeef;
+ else
+ val->constant->values[0].u32[j] = u32[comp];
}
}
break;