2
0
Эх сурвалжийг харах

Fix implementation of d3dcolortoubyte4 (#2345)

* Fix implimentation of d3dcolortoubyte4

* Address CR comment

* Remove lang version flag

* Add relevant except from staco
Vishal Sharma 6 жил өмнө
parent
commit
c1d78e5116

+ 17 - 6
lib/HLSL/HLOperationLower.cpp

@@ -600,18 +600,29 @@ Value *TrivialBarrier(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
 Value *TranslateD3DColorToUByte4(CallInst *CI, IntrinsicOp IOP,
                                  OP::OpCode opcode,
                                  HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
-  hlsl::OP *hlslOP = &helper.hlslOP;
   IRBuilder<> Builder(CI);
   Value *val = CI->getArgOperand(HLOperandIndex::kUnaryOpSrc0Idx);
   Type *Ty = val->getType();
 
-  Constant *toByteConst = ConstantFP::get(Ty->getScalarType(), 255);
-  if (Ty != Ty->getScalarType()) {
-    toByteConst =
-        ConstantVector::getSplat(Ty->getVectorNumElements(), toByteConst);
+  // Use the same scaling factor used by FXC (i.e., 255.001953)
+  // Excerpt from stackoverflow discussion:
+  // "Built-in rounding, necessary because of truncation. 0.001953 * 256 = 0.5"
+  Constant *toByteConst = ConstantFP::get(Ty->getScalarType(), 255.001953);
+
+  if (Ty->isVectorTy()) {
+    static constexpr int supportedVecElemCount = 4;
+    if (Ty->getVectorNumElements() == supportedVecElemCount) {
+      toByteConst = ConstantVector::getSplat(supportedVecElemCount, toByteConst);
+      // Swizzle the input val -> val.zyxw
+      std::vector<int> mask { 2, 1, 0, 3 };
+      val = Builder.CreateShuffleVector(val, val, mask);
+    } else {
+      CI->getContext().emitError(CI, "Unsupported input type for intrinsic D3DColorToUByte4");
+      return UndefValue::get(CI->getType());
+    }
   }
+
   Value *byte4 = Builder.CreateFMul(toByteConst, val);
-  byte4 = TrivialDxilUnaryOperation(OP::OpCode::Round_ne, byte4, hlslOP, Builder);
   return Builder.CreateCast(Instruction::CastOps::FPToSI, byte4, CI->getType());
 }
 

+ 16 - 0
tools/clang/test/CodeGenHLSL/batch/expressions/intrinsics/d3dcolortoubyte4/d3dcolortoubyte4-const-input.hlsl

@@ -0,0 +1,16 @@
+// RUN: %dxc -E main -T vs_6_0 %s | FileCheck %s
+
+// Test the following:
+// 1) Input i to D3DCOLORtoUBYTE4() is swizzled to i.zyxw
+// 2) Swizzled value is multiplied with constant 255.001953
+
+// CHECK: 7650058
+// CHECK: 5100039
+// CHECK: 2550019
+// CHECK: 10200078
+
+int4 main (): OUT
+{
+    return D3DCOLORtoUBYTE4(float4(10000, 20000, 30000, 40000));
+}
+

+ 28 - 0
tools/clang/test/CodeGenHLSL/batch/expressions/intrinsics/d3dcolortoubyte4/d3dcolortoubyte4-var-input.hlsl

@@ -0,0 +1,28 @@
+// RUN: %dxc -E main -T vs_6_0 %s | FileCheck %s
+
+// Test the following:
+// 1) Input to D3DCOLORtoUBYTE4() is multipled by 255.001953
+// 2) No rounding is applied
+
+// CHECK: fmul
+// CHECK: 0x406FE01000000000
+// CHECK: fmul
+// CHECK: 0x406FE01000000000
+// CHECK: fmul
+// CHECK: 0x406FE01000000000
+// CHECK: fmul
+// CHECK: 0x406FE01000000000
+// CHECK-NOT: Round
+// CHECK-NOT: Round
+// CHECK-NOT: Round
+// CHECK-NOT: Round
+// CHECK: fptosi
+// CHECK: fptosi
+// CHECK: fptosi
+// CHECK: fptosi
+
+
+int4 main (float4 f : IN): OUT
+{
+    return D3DCOLORtoUBYTE4(f);
+}

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/intrinsic5.hlsl

@@ -1,6 +1,6 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
 
-// CHECK: Round_ne
+// CHECK-NOT: Round_ne
 // CHECK: fptosi
 // CHECK: IsInf
 // CHECK: IsNaN

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/intrinsic5_minprec.hlsl

@@ -1,6 +1,6 @@
 // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
 
-// CHECK: Round_ne
+// CHECK-NOT: Round_ne
 // CHECK: fptosi
 // CHECK: IsInf
 // CHECK: IsNaN