Browse Source

[spirv] Interpolation modes are also allowed on VS outputs. (#2414)

Fixes #2378.
Ehsan 6 years ago
parent
commit
0a32799e58

+ 10 - 8
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -1937,10 +1937,12 @@ bool DeclResultIdMapper::createStageVars(
     }
 
     // Decorate with interpolation modes for pixel shader input variables
-    if (spvContext.isPS() && sigPoint->IsInput() &&
+    // or vertex shader output variables.
+    if (((spvContext.isPS() && sigPoint->IsInput()) ||
+         (spvContext.isVS() && sigPoint->IsOutput())) &&
         // BaryCoord*AMD buitins already encode the interpolation mode.
         semanticKind != hlsl::Semantic::Kind::Barycentrics)
-      decoratePSInterpolationMode(decl, type, varInstr);
+      decorateInterpolationMode(decl, type, varInstr);
 
     if (asInput) {
       *value = spvBuilder.createLoad(evalType, varInstr, loc);
@@ -2520,20 +2522,20 @@ DeclResultIdMapper::invertWIfRequested(SpirvInstruction *position,
   return position;
 }
 
-void DeclResultIdMapper::decoratePSInterpolationMode(const NamedDecl *decl,
-                                                     QualType type,
-                                                     SpirvVariable *varInstr) {
-  const QualType elemType = getElementType(astContext, type);
+void DeclResultIdMapper::decorateInterpolationMode(const NamedDecl *decl,
+                                                   QualType type,
+                                                   SpirvVariable *varInstr) {
   const auto loc = decl->getLocation();
 
-  if (elemType->isBooleanType() || elemType->isIntegerType()) {
+  if (isUintOrVecMatOfUintType(type) || isSintOrVecMatOfSintType(type) ||
+      isBoolOrVecMatOfBoolType(type)) {
     // TODO: Probably we can call hlsl::ValidateSignatureElement() for the
     // following check.
     if (decl->getAttr<HLSLLinearAttr>() || decl->getAttr<HLSLCentroidAttr>() ||
         decl->getAttr<HLSLNoPerspectiveAttr>() ||
         decl->getAttr<HLSLSampleAttr>()) {
       emitError("only nointerpolation mode allowed for integer input "
-                "parameters in pixel shader",
+                "parameters in pixel shader or integer output in vertex shader",
                 decl->getLocation());
     } else {
       spvBuilder.decorateFlat(varInstr, loc);

+ 2 - 2
tools/clang/lib/SPIRV/DeclResultIdMapper.h

@@ -672,8 +672,8 @@ private:
 
   /// Decorates varInstr of the given asType with proper interpolation modes
   /// considering the attributes on the given decl.
-  void decoratePSInterpolationMode(const NamedDecl *decl, QualType asType,
-                                   SpirvVariable *varInstr);
+  void decorateInterpolationMode(const NamedDecl *decl, QualType asType,
+                                 SpirvVariable *varInstr);
 
   /// Returns the proper SPIR-V storage class (Input or Output) for the given
   /// SigPoint.

+ 0 - 0
tools/clang/test/CodeGenSPIRV/spirv.interpolation.hlsl → tools/clang/test/CodeGenSPIRV/spirv.interpolation.ps.hlsl


+ 45 - 0
tools/clang/test/CodeGenSPIRV/spirv.interpolation.vs.hlsl

@@ -0,0 +1,45 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// Required by the sample interpolation mode
+// CHECK: OpCapability SampleRateShading
+
+struct VSOutput {
+                       float   fp_a: FPA;
+  linear               float1  fp_b: FPB;
+// CHECK: OpDecorate %out_var_FPC Centroid
+  centroid             float2  fp_c: FPC;
+// CHECK: OpDecorate %out_var_FPD Flat
+  nointerpolation      float3  fp_d: FPD;
+// CHECK: OpDecorate %out_var_FPE NoPerspective
+  noperspective        float4  fp_e: FPE;
+// CHECK: OpDecorate %out_var_FPF Sample
+  sample               float   fp_f: FPF;
+// CHECK: OpDecorate %out_var_FPG NoPerspective
+// CHECK: OpDecorate %out_var_FPG Sample
+  noperspective sample float2  fp_g: FPG;
+
+// CHECK: OpDecorate %out_var_INTA Flat
+                       int    int_a: INTA;
+// CHECK: OpDecorate %out_var_INTD Flat
+  nointerpolation      int3   int_d: INTD;
+
+// CHECK: OpDecorate %out_var_UINTA Flat
+                       uint  uint_a: UINTA;
+// CHECK: OpDecorate %out_var_UINTD Flat
+  nointerpolation      uint3 uint_d: UINTD;
+
+// CHECK: OpDecorate %out_var_BOOLA Flat
+                       bool  bool_a: BOOLA;
+// CHECK: OpDecorate %out_var_BOOLD Flat
+  nointerpolation      bool3 bool_d: BOOLD;
+
+// CHECK: OpDecorate %out_var_FPH Flat
+  nointerpolation      float4 fp_h[1]: FPH;
+};
+
+// CHECK: OpDecorate %out_var_TEXCOORD NoPerspective
+VSOutput main(out noperspective int a : TEXCOORD) {
+  VSOutput myOutput;
+  return myOutput;
+}
+

+ 5 - 2
tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

@@ -1392,8 +1392,11 @@ TEST_F(FileTest, SpirvStageIO16bitTypes) {
   runFileTest("spirv.stage-io.16bit.hlsl");
 }
 
-TEST_F(FileTest, SpirvInterpolation) {
-  runFileTest("spirv.interpolation.hlsl");
+TEST_F(FileTest, SpirvInterpolationPS) {
+  runFileTest("spirv.interpolation.ps.hlsl");
+}
+TEST_F(FileTest, SpirvInterpolationVS) {
+  runFileTest("spirv.interpolation.vs.hlsl");
 }
 TEST_F(FileTest, SpirvInterpolationError) {
   runFileTest("spirv.interpolation.error.hlsl", Expect::Failure);