nv50/ir: add intermediate conversion for f2{i,u}{8,16}
authorDanilo Krummrich <dakr@redhat.com>
Tue, 16 Aug 2022 00:03:02 +0000 (02:03 +0200)
committerDanilo Krummrich <dakr@redhat.com>
Fri, 9 Sep 2022 15:32:22 +0000 (17:32 +0200)
Directly converting from a float to an 8 bit integer and from a 64 bit
float to an integer smaller than 32 bit is not supported, therefore add
an intermediate conversion to an 32 bit integer.

Reviewed-by: Karol Herbst <kherbst@redhat.com>
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18109>

src/nouveau/codegen/nv50_ir_lowering_helper.cpp

index ed5a804..58c288e 100644 (file)
@@ -85,8 +85,23 @@ LoweringHelper::handleCVT(Instruction *insn)
    DataType dTy = insn->dType;
    DataType sTy = insn->sType;
 
-   if (typeSizeof(dTy) <= 4 && typeSizeof(sTy) <= 4)
+   bld.setPosition(insn, true);
+
+   /* We can't convert from 32bit floating point to 8bit integer and from 64bit
+    * floating point to any integer smaller than 32bit, hence add an instruction
+    * to convert to a 32bit integer first.
+    */
+   if (((typeSizeof(dTy) == 1) && isFloatType(sTy)) ||
+       ((typeSizeof(dTy) <= 2) && sTy == TYPE_F64)) {
+      Value *tmp = insn->getDef(0);
+      DataType tmpTy = (isSignedIntType(dTy)) ? TYPE_S32 : TYPE_U32;
+
+      insn->setType(tmpTy, sTy);
+      insn->setDef(0, bld.getSSA());
+      bld.mkCvt(OP_CVT, dTy, tmp, tmpTy, insn->getDef(0))->saturate = 1;
+
       return true;
+   }
 
    bld.setPosition(insn, false);