ソースを参照

Support isfrontface as uint. (#919)

Xiang Li 7 年 前
コミット
4f7016af53

+ 36 - 0
lib/HLSL/DxilPreparePasses.cpp

@@ -416,13 +416,49 @@ public:
   bool runOnModule(Module &M) override {
     if (M.HasDxilModule()) {
       DxilModule::ClearDxilMetadata(M);
+      patchIsFrontfaceTy(M);
       M.GetDxilModule().EmitDxilMetadata();
       return true;
     }
 
     return false;
   }
+private:
+  void patchIsFrontfaceTy(Module &M);
 };
+
+void patchIsFrontface(DxilSignatureElement &Elt, bool bForceUint) {
+  // If force to uint, change i1 to u32.
+  // If not force to uint, change u32 to i1.
+  if (bForceUint && Elt.GetCompType() == CompType::Kind::I1)
+    Elt.SetCompType(CompType::Kind::U32);
+  else if (!bForceUint && Elt.GetCompType() == CompType::Kind::U32)
+    Elt.SetCompType(CompType::Kind::I1);
+}
+
+void patchIsFrontface(DxilSignature &sig, bool bForceUint) {
+  for (auto &Elt : sig.GetElements()) {
+    if (Elt->GetSemantic()->GetKind() == Semantic::Kind::IsFrontFace) {
+      patchIsFrontface(*Elt, bForceUint);
+    }
+  }
+}
+
+void DxilEmitMetadata::patchIsFrontfaceTy(Module &M) {
+  DxilModule &DM = M.GetDxilModule();
+  const ShaderModel *pSM = DM.GetShaderModel();
+  if (!pSM->IsGS() && !pSM->IsPS())
+    return;
+  unsigned ValMajor, ValMinor;
+  DM.GetValidatorVersion(ValMajor, ValMinor);
+  bool bForceUint = ValMajor >= 1 && ValMinor >= 2;
+  if (pSM->IsPS()) {
+    patchIsFrontface(DM.GetInputSignature(), bForceUint);
+  } else if (pSM->IsGS()) {
+    patchIsFrontface(DM.GetOutputSignature(), bForceUint);
+  }
+}
+
 }
 
 char DxilEmitMetadata::ID = 0;

+ 4 - 4
lib/HLSL/DxilValidation.cpp

@@ -3347,12 +3347,12 @@ static void ValidateSignatureElement(DxilSignatureElement &SE,
     }
     // NOTE: clip cull distance size is checked at ValidateSignature.
     break;
-  case DXIL::SemanticKind::IsFrontFace:
-    if (!compBool || SE.GetCols() != 1) {
+  case DXIL::SemanticKind::IsFrontFace: {
+    if (!(compInt && compWidth == 32) || SE.GetCols() != 1) {
       ValCtx.EmitFormatError(ValidationRule::MetaSemanticCompType,
-                             {SE.GetSemantic()->GetName(), "bool"});
+                             {SE.GetSemantic()->GetName(), "uint"});
     }
-    break;
+  } break;
   case DXIL::SemanticKind::RenderTargetArrayIndex:
   case DXIL::SemanticKind::ViewPortArrayIndex:
   case DXIL::SemanticKind::VertexID:

+ 8 - 0
tools/clang/test/CodeGenHLSL/quick-test/isfrontface.hlsl

@@ -0,0 +1,8 @@
+// RUN: %dxc -T ps_6_0 -E main %s | FileCheck %s
+
+// Make sure use uint isfrontface works.
+// CHECK: main
+
+float main(uint b : SV_IsFrontFace) : SV_Target {
+  return b;
+}

+ 39 - 0
tools/clang/test/CodeGenHLSL/quick-test/isfrontface2.hlsl

@@ -0,0 +1,39 @@
+// RUN: %dxc -E main -T gs_6_0 %s | FileCheck %s
+
+// Make sure uint isfrontface works.
+// CHECK: emitStream
+// CHECK: cutStream
+// CHECK: i32 24}
+
+struct GSIn {
+  float2 uv : TEXCOORD0;
+  float4 clr : COLOR;
+  float4 pos : SV_Position;
+
+};
+
+struct GSOut {
+  float2 uv : TEXCOORD0;
+  float4 clr : COLOR;
+  float4 pos : SV_Position;
+  uint ff : SV_IsFrontFace;
+};
+
+cbuffer b : register(b0) {
+  float2 invViewportSize;
+};
+
+// geometry shader that outputs 3 vertices from a point
+[maxvertexcount(3)]
+[instance(24)]
+void main(point GSIn points[1], inout PointStream<GSOut> stream) {
+
+  GSOut o;
+  o.uv = points[0].uv;
+  o.clr = points[0].clr;
+  o.pos = points[0].pos;
+  o.ff = false;
+  stream.Append(o);
+
+  stream.RestartStrip();
+}

+ 4 - 4
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -2051,11 +2051,11 @@ float4 main( \
 
     "= !{i32 1, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 2, i32 1, i8 0, null}\n"
     "!([0-9]+) = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
-    "!([0-9]+) = !{i32 3, !\"SV_IsFrontFace\", i8 1, i8 13, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 3, null}\n",
+    "!([0-9]+) = !{i32 3, !\"SV_IsFrontFace\", i8 5, i8 13, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 3, null}\n",
 
     "= !{i32 1, !\"Value\", i8 5, i8 0, !\\1, i8 1, i32 1, i8 2, i32 1, i8 2, null}\n"
     "!\\2 = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !\\3, i8 1, i32 1, i8 1, i32 1, i8 0, null}\n"
-    "!\\4 = !{i32 3, !\"SV_IsFrontFace\", i8 1, i8 13, !\\5, i8 1, i32 1, i8 1, i32 1, i8 1, null}\n",
+    "!\\4 = !{i32 3, !\"SV_IsFrontFace\", i8 5, i8 13, !\\5, i8 1, i32 1, i8 1, i32 1, i8 1, null}\n",
 
     "signature element SV_PrimitiveID at location \\(1,0\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).\n"
     "signature element SV_IsFrontFace at location \\(1,1\\) size \\(1,1\\) violates component ordering rule \\(arb < sv < sgv\\).",
@@ -2078,13 +2078,13 @@ float4 main( \
 
     { "= !{i32 1, !\"Value\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 0, null}\n"
       "!([0-9]+) = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 1, null}\n"
-      "!([0-9]+) = !{i32 3, !\"SV_IsFrontFace\", i8 1, i8 13, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
+      "!([0-9]+) = !{i32 3, !\"SV_IsFrontFace\", i8 5, i8 13, !([0-9]+), i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
       "!([0-9]+) = !{i32 4, !\"ViewPortArrayIndex\", i8 5, i8 0, !([0-9]+), i8 1, i32 1, i8 1, i32 2, i8 0, null}\n",
       "?!dx.viewIdState ="},
 
     { "= !{i32 1, !\"Value\", i8 5, i8 0, !\\1, i8 1, i32 1, i8 1, i32 1, i8 1, null}\n"
       "!\\2 = !{i32 2, !\"SV_PrimitiveID\", i8 5, i8 10, !\\3, i8 1, i32 1, i8 1, i32 1, i8 0, null}\n"
-      "!\\4 = !{i32 3, !\"SV_IsFrontFace\", i8 1, i8 13, !\\5, i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
+      "!\\4 = !{i32 3, !\"SV_IsFrontFace\", i8 5, i8 13, !\\5, i8 1, i32 1, i8 1, i32 1, i8 2, null}\n"
       "!\\6 = !{i32 4, !\"ViewPortArrayIndex\", i8 5, i8 0, !\\7, i8 1, i32 1, i8 1, i32 1, i8 3, null}\n",
       "!1012 ="},