Browse Source

[spirv] Add support for PS [earlydepthstencil] attribute (#1074)

Lei Zhang 7 years ago
parent
commit
b05430d9fb

+ 12 - 10
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -535,8 +535,6 @@ void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {
   theBuilder.addEntryPoint(getSpirvShaderStage(shaderModel), entryFunctionId,
                            entryFunctionName, declIdMapper.collectStageVars());
 
-  AddExecutionModeForEntryPoint(entryFunctionId);
-
   // Add Location decorations to stage input/output variables.
   if (!declIdMapper.decorateStageIOLocations())
     return;
@@ -8090,13 +8088,6 @@ void SPIRVEmitter::AddRequiredCapabilitiesForShaderModel() {
   }
 }
 
-void SPIRVEmitter::AddExecutionModeForEntryPoint(uint32_t entryPointId) {
-  if (shaderModel.IsPS()) {
-    theBuilder.addExecutionMode(entryPointId,
-                                spv::ExecutionMode::OriginUpperLeft, {});
-  }
-}
-
 bool SPIRVEmitter::processGeometryShaderAttributes(const FunctionDecl *decl,
                                                    uint32_t *arraySize) {
   bool success = true;
@@ -8186,6 +8177,15 @@ bool SPIRVEmitter::processGeometryShaderAttributes(const FunctionDecl *decl,
   return success;
 }
 
+void SPIRVEmitter::processPixelShaderAttributes(const FunctionDecl *decl) {
+  theBuilder.addExecutionMode(entryFunctionId,
+                              spv::ExecutionMode::OriginUpperLeft, {});
+  if (auto *numThreadsAttr = decl->getAttr<HLSLEarlyDepthStencilAttr>()) {
+    theBuilder.addExecutionMode(entryFunctionId,
+                                spv::ExecutionMode::EarlyFragmentTests, {});
+  }
+}
+
 void SPIRVEmitter::processComputeShaderAttributes(const FunctionDecl *decl) {
   // If not explicitly specified, x, y, and z should be defaulted to 1.
   uint32_t x = 1, y = 1, z = 1;
@@ -8312,7 +8312,9 @@ bool SPIRVEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
   declIdMapper.setEntryFunctionId(entryFunctionId);
 
   // Handle attributes specific to each shader stage
-  if (shaderModel.IsCS()) {
+  if (shaderModel.IsPS()) {
+    processPixelShaderAttributes(decl);
+  } else if (shaderModel.IsCS()) {
     processComputeShaderAttributes(decl);
   } else if (shaderModel.IsHS()) {
     if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))

+ 4 - 4
tools/clang/lib/SPIRV/SPIRVEmitter.h

@@ -507,10 +507,6 @@ private:
 
   void AddRequiredCapabilitiesForShaderModel();
 
-  /// \brief Adds the execution mode for the given entry point based on the
-  /// shader model.
-  void AddExecutionModeForEntryPoint(uint32_t entryPointId);
-
   /// \brief Adds necessary execution modes for the hull/domain shaders based on
   /// the HLSL attributes of the entry point function.
   /// In the case of hull shaders, also writes the number of output control
@@ -525,6 +521,10 @@ private:
   bool processGeometryShaderAttributes(const FunctionDecl *entryFunction,
                                        uint32_t *arraySize);
 
+  /// \brief Adds necessary execution modes for the pixel shader based on the
+  /// HLSL attributes of the entry point function.
+  void processPixelShaderAttributes(const FunctionDecl *decl);
+
   /// \brief Adds necessary execution modes for the compute shader based on the
   /// HLSL attributes of the entry point function.
   void processComputeShaderAttributes(const FunctionDecl *entryFunction);

+ 6 - 0
tools/clang/test/CodeGenSPIRV/attribute.earlydepthstencil.ps.hlsl

@@ -0,0 +1,6 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK: OpExecutionMode %main EarlyFragmentTests
+
+[earlydepthstencil]
+float4 main() : SV_Target { return 1.0; }

+ 3 - 0
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -904,6 +904,9 @@ TEST_F(FileTest, IntrinsicsGetRenderTargetSamplePosition) {
 }
 
 // For attributes
+TEST_F(FileTest, AttributeEarlyDepthStencil) {
+  runFileTest("attribute.earlydepthstencil.ps.hlsl");
+}
 TEST_F(FileTest, AttributeNumThreads) {
   runFileTest("attribute.numthreads.hlsl");
 }