spirv: fix bug when OpSpecConstantOp calls a conversion
authorSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Mon, 20 Nov 2017 12:12:12 +0000 (13:12 +0100)
committerSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Thu, 7 Dec 2017 09:19:34 +0000 (10:19 +0100)
In that case, nir_eval_const_opcode() will evaluate the conversion
but as it was using destination's bit_size, the resulting
value was just a cast of the source constant value. By passing the
source's bit size, it does the conversion properly.

Fixes:

dEQP-VK.spirv_assembly.instruction.*.opspecconstantop.*convert*

v2:
- Remove invalid conversion op cases.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/compiler/spirv/spirv_to_nir.c

index c6efefb26f73a52892d5d1682d82a73ba2ccba3e..e5d447f23a97c2a55c6cc836a3867919522123f1 100644 (file)
@@ -1570,16 +1570,31 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
          bool swap;
          nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(val->const_type);
          nir_alu_type src_alu_type = dst_alu_type;
+         unsigned num_components = glsl_get_vector_elements(val->const_type);
+         unsigned bit_size;
+
+         vtn_assert(count <= 7);
+
+         switch (opcode) {
+         case SpvOpSConvert:
+         case SpvOpFConvert:
+            /* We have a source in a conversion */
+            src_alu_type =
+               nir_get_nir_type_for_glsl_type(
+                  vtn_value(b, w[4], vtn_value_type_constant)->const_type);
+            /* We use the bitsize of the conversion source to evaluate the opcode later */
+            bit_size = glsl_get_bit_size(
+               vtn_value(b, w[4], vtn_value_type_constant)->const_type);
+            break;
+         default:
+            bit_size = glsl_get_bit_size(val->const_type);
+         };
+
          nir_op op = vtn_nir_alu_op_for_spirv_opcode(b, opcode, &swap,
                                                      src_alu_type,
                                                      dst_alu_type);
-
-         unsigned num_components = glsl_get_vector_elements(val->const_type);
-         unsigned bit_size =
-            glsl_get_bit_size(val->const_type);
-
          nir_const_value src[4];
-         vtn_assert(count <= 7);
+
          for (unsigned i = 0; i < count - 4; i++) {
             nir_constant *c =
                vtn_value(b, w[4 + i], vtn_value_type_constant)->constant;