Selaa lähdekoodia

[spirv] Emit OpSource debug instruction (#1145)

Lei Zhang 7 vuotta sitten
vanhempi
commit
f6f79e744d

+ 10 - 2
docs/SPIR-V.rst

@@ -357,6 +357,14 @@ compiler. They have "no semantic impact and can safely be removed" according
 to the SPIR-V spec. And they are subject to changes without notice. So we do
 not suggest to use them for reflection.
 
+Source code shader profile
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The source code shader profile version can be re-discovered by the "Version"
+operand in ``OpSource`` instruction. For ``*s_<major>_<minor>``, the "Verison"
+operand in ``OpSource`` will be set as ``<major>`` * 100 + ``<minor>`` * 10.
+For example, ``vs_5_1`` will have 510, ``ps_6_2`` will have 620.
+
 Read-only vs. read-write resource types
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2528,7 +2536,7 @@ generated. ``.RestartStrip()`` method calls will be translated into the SPIR-V
 Shader Model 6.0 Wave Intrinsics
 ================================
 
- ... note ::
+::
 
   Wave intrinsics requires SPIR-V 1.3, which is supported by Vulkan 1.1.
   If you use wave intrinsics in your source code, the generated SPIR-V code
@@ -2558,7 +2566,7 @@ Reduction     ``WaveActiveMin()``          ``OpGroupNonUniform*Min``           `
 Reduction     ``WaveActiveMax()``          ``OpGroupNonUniform*Max``           ``Reduction``
 Scan/Prefix   ``WavePrefixSum()``          ``OpGroupNonUniform*Add``           ``ExclusiveScan``
 Scan/Prefix   ``WavePrefixProduct()``      ``OpGroupNonUniform*Mul``           ``ExclusiveScan``
-Scan/Prefix   ``WavePrefixCountBits()`     ``OpGroupNonUniformBallotBitCount`` ``ExclusiveScan``
+Scan/Prefix   ``WavePrefixCountBits()``    ``OpGroupNonUniformBallotBitCount`` ``ExclusiveScan``
 Broadcast     ``WaveReadLaneAt()``         ``OpGroupNonUniformBroadcast``
 Broadcast     ``WaveReadLaneFirst()``      ``OpGroupNonUniformBroadcastFirst``
 Quad          ``QuadReadAcrossX()``        ``OpGroupNonUniformQuadSwap``

+ 6 - 0
tools/clang/include/clang/SPIRV/ModuleBuilder.h

@@ -329,6 +329,8 @@ public:
                             std::string targetName,
                             llvm::ArrayRef<uint32_t> interfaces);
 
+  inline void setShaderModelVersion(uint32_t major, uint32_t minor);
+
   /// \brief Adds an execution mode to the module under construction.
   void addExecutionMode(uint32_t entryPointId, spv::ExecutionMode em,
                         llvm::ArrayRef<uint32_t> params);
@@ -500,6 +502,10 @@ void ModuleBuilder::addEntryPoint(spv::ExecutionModel em, uint32_t targetId,
   theModule.addEntryPoint(em, targetId, std::move(targetName), interfaces);
 }
 
+void ModuleBuilder::setShaderModelVersion(uint32_t major, uint32_t minor) {
+  theModule.setShaderModelVersion(major * 100 + minor * 10);
+}
+
 void ModuleBuilder::addExtension(llvm::StringRef extension) {
   theModule.addExtension(extension);
 }

+ 8 - 1
tools/clang/include/clang/SPIRV/Structure.h

@@ -306,6 +306,7 @@ public:
                             std::string targetName,
                             llvm::ArrayRef<uint32_t> intefaces);
   inline void addExecutionMode(Instruction &&);
+  inline void setShaderModelVersion(uint32_t);
   // TODO: source code debug information
   inline void addDebugName(uint32_t targetId, llvm::StringRef name,
                            llvm::Optional<uint32_t> memberIndex = llvm::None);
@@ -336,6 +337,7 @@ private:
   llvm::Optional<spv::MemoryModel> memoryModel;
   std::vector<EntryPoint> entryPoints;
   std::vector<Instruction> executionModes;
+  uint32_t shaderModelVersion;
   // TODO: source code debug information
   std::set<DebugName> debugNames;
   llvm::SetVector<std::pair<uint32_t, const Decoration *>> decorations;
@@ -446,7 +448,8 @@ TypeIdPair::TypeIdPair(const Type &ty, uint32_t id) : type(ty), resultId(id) {}
 // === Module inline implementations ===
 
 SPIRVModule::SPIRVModule()
-    : addressingModel(llvm::None), memoryModel(llvm::None) {}
+    : addressingModel(llvm::None), memoryModel(llvm::None),
+      shaderModelVersion(0) {}
 
 void SPIRVModule::setVersion(uint32_t version) { header.version = version; }
 void SPIRVModule::setBound(uint32_t newBound) { header.bound = newBound; }
@@ -488,6 +491,10 @@ void SPIRVModule::addExecutionMode(Instruction &&execMode) {
   executionModes.push_back(std::move(execMode));
 }
 
+void SPIRVModule::setShaderModelVersion(uint32_t version) {
+  shaderModelVersion = version;
+}
+
 void SPIRVModule::addDebugName(uint32_t targetId, llvm::StringRef name,
                                llvm::Optional<uint32_t> memberIndex) {
 

+ 3 - 0
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -537,6 +537,9 @@ void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {
   if (context.getDiagnostics().hasErrorOccurred())
     return;
 
+  theBuilder.setShaderModelVersion(shaderModel.GetMajor(),
+                                   shaderModel.GetMinor());
+
   TranslationUnitDecl *tu = context.getTranslationUnitDecl();
 
   // The entry function is the seed of the queue.

+ 12 - 6
tools/clang/lib/SPIRV/Structure.cpp

@@ -138,9 +138,9 @@ void Function::take(InstBuilder *builder) {
   // validation rules.
   std::vector<BasicBlock *> orderedBlocks;
   if (!blocks.empty()) {
-    BlockReadableOrderVisitor([&orderedBlocks](BasicBlock *block) {
-      orderedBlocks.push_back(block);
-    }).visit(blocks.front().get());
+    BlockReadableOrderVisitor(
+        [&orderedBlocks](BasicBlock *block) { orderedBlocks.push_back(block); })
+        .visit(blocks.front().get());
   }
 
   // Write out all basic blocks.
@@ -162,9 +162,9 @@ void Function::addVariable(uint32_t varType, uint32_t varId,
 
 void Function::getReachableBasicBlocks(std::vector<BasicBlock *> *bbVec) const {
   if (!blocks.empty()) {
-    BlockReadableOrderVisitor([&bbVec](BasicBlock *block) {
-      bbVec->push_back(block);
-    }).visit(blocks.front().get());
+    BlockReadableOrderVisitor(
+        [&bbVec](BasicBlock *block) { bbVec->push_back(block); })
+        .visit(blocks.front().get());
   }
 }
 
@@ -282,6 +282,12 @@ void SPIRVModule::take(InstBuilder *builder) {
     consumer(inst.take());
   }
 
+  if (shaderModelVersion != 0)
+    builder
+        ->opSource(spv::SourceLanguage::HLSL, shaderModelVersion, llvm::None,
+                   llvm::None)
+        .x();
+
   // BasicBlock debug names should be emitted only for blocks that are
   // reachable.
   // The debug name for a basic block is stored in the basic block object.

+ 1 - 0
tools/clang/test/CodeGenSPIRV/bezier.domain.hlsl2spv

@@ -50,6 +50,7 @@ DS_OUTPUT BezierEvalDS( HS_CONSTANT_DATA_OUTPUT input,
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint TessellationEvaluation %BezierEvalDS "BezierEvalDS" %gl_PerVertexIn %gl_PerVertexOut %gl_TessLevelOuter %gl_TessLevelInner %in_var_TANGENT %in_var_TEXCOORD %in_var_TANUCORNER %in_var_TANVCORNER %in_var_TANWEIGHTS %gl_TessCoord %in_var_BEZIERPOS %out_var_NORMAL %out_var_TEXCOORD %out_var_TANGENT %out_var_BITANGENT
 // OpExecutionMode %BezierEvalDS Quads
+// OpSource HLSL 600
 // OpName %bb_entry "bb.entry"
 // OpName %src_BezierEvalDS "src.BezierEvalDS"
 // OpName %BezierEvalDS "BezierEvalDS"

+ 1 - 0
tools/clang/test/CodeGenSPIRV/bezier.hull.hlsl2spv

@@ -64,6 +64,7 @@ BEZIER_CONTROL_POINT SubDToBezierHS(InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POIN
 // OpExecutionMode %SubDToBezierHS SpacingFractionalOdd
 // OpExecutionMode %SubDToBezierHS VertexOrderCcw
 // OpExecutionMode %SubDToBezierHS OutputVertices 3
+// OpSource HLSL 600
 // OpName %if_true "if.true"
 // OpName %if_merge "if.merge"
 // OpName %bb_entry "bb.entry"

+ 1 - 0
tools/clang/test/CodeGenSPIRV/empty-struct-interface.vs.hlsl2spv

@@ -16,6 +16,7 @@ VSOut main(VSIn input)
 // OpCapability Shader
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Vertex %main "main" %gl_PerVertexOut
+// OpSource HLSL 600
 // OpName %bb_entry "bb.entry"
 // OpName %src_main "src.main"
 // OpName %main "main"

+ 1 - 0
tools/clang/test/CodeGenSPIRV/passthru-cs.hlsl2spv

@@ -27,6 +27,7 @@ void main( uint3 DTid : SV_DispatchThreadID )
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
 // OpExecutionMode %main LocalSize 1 1 1
+// OpSource HLSL 600
 // OpName %bb_entry "bb.entry"
 // OpName %type_ByteAddressBuffer "type.ByteAddressBuffer"
 // OpName %Buffer0 "Buffer0"

+ 1 - 0
tools/clang/test/CodeGenSPIRV/passthru-ps.hlsl2spv

@@ -15,6 +15,7 @@ float4 main(float4 input: COLOR): SV_Target
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
 // OpExecutionMode %main OriginUpperLeft
+// OpSource HLSL 600
 // OpName %bb_entry "bb.entry"
 // OpName %src_main "src.main"
 // OpName %main "main"

+ 1 - 0
tools/clang/test/CodeGenSPIRV/passthru-vs.hlsl2spv

@@ -22,6 +22,7 @@ PSInput VSmain(float4 position: POSITION, float4 color: COLOR) {
 // OpCapability Shader
 // OpMemoryModel Logical GLSL450
 // OpEntryPoint Vertex %VSmain "VSmain" %gl_PerVertexOut %in_var_POSITION %in_var_COLOR %out_var_COLOR
+// OpSource HLSL 600
 // OpName %bb_entry "bb.entry"
 // OpName %src_VSmain "src.VSmain"
 // OpName %VSmain "VSmain"