[Mesa-dev] [PATCH v3 1/2] spirv: fix OpSConvert when the source is unsigned

Samuel Iglesias Gonsálvez siglesias at igalia.com
Tue Mar 13 12:40:48 UTC 2018


OpSConvert interprets the MSB of the unsigned value as the sign bit and
extends it to the new type. If we want to preserve the value, we need
to use OpUConvert opcode.

v2:
- No need to check dst type.
- Fix typo in comment.

v3:
- Use src/dst bitsize to get the proper conversion opcode. (Jason)

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
---
 src/compiler/spirv/vtn_alu.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c
index d0c9e316935..9dcd183a48d 100644
--- a/src/compiler/spirv/vtn_alu.c
+++ b/src/compiler/spirv/vtn_alu.c
@@ -354,10 +354,19 @@ vtn_nir_alu_op_for_spirv_opcode(struct vtn_builder *b,
    case SpvOpConvertFToS:
    case SpvOpConvertSToF:
    case SpvOpConvertUToF:
-   case SpvOpSConvert:
    case SpvOpFConvert:
       return nir_type_conversion_op(src, dst, nir_rounding_mode_undef);
 
+   case SpvOpSConvert: {
+      /* SPIR-V expects to interpret the unsigned value as signed and
+       * sign extend. Return the opcode accordingly.
+       */
+      unsigned src_bit_size = nir_alu_type_get_type_size(src);
+      nir_alu_type src_type = nir_type_int | src_bit_size;
+      unsigned dst_bit_size = nir_alu_type_get_type_size(dst);
+      nir_alu_type dst_type = nir_type_int | dst_bit_size;
+      return nir_type_conversion_op(src_type, dst_type, nir_rounding_mode_undef);
+   }
    /* Derivatives: */
    case SpvOpDPdx:         return nir_op_fddx;
    case SpvOpDPdy:         return nir_op_fddy;
-- 
2.14.1



More information about the mesa-dev mailing list