Browse Source

[dxil2spv] Translate SV_Position to BuiltIn::Position (#4423)

SV_Position elements in DXIL input signature should be treated as SPIR-V
BuiltIn variables with the Position type rather than regular stage IO
variables with a Location.
Natalie Chouinard 3 years ago
parent
commit
b292f9482b

+ 3 - 4
tools/clang/test/Dxil2Spv/passthru-ps.ll

@@ -109,13 +109,12 @@ attributes #1 = { nounwind }
 ; ; Schema: 0
 ;                OpCapability Shader
 ;                OpMemoryModel Logical GLSL450
-;                OpEntryPoint Fragment %PSMain "PSMain" %SV_Position %COLOR %SV_Target
+;                OpEntryPoint Fragment %PSMain "PSMain" %gl_Position %COLOR %SV_Target
 ;                OpExecutionMode %PSMain OriginUpperLeft
-;                OpName %SV_Position "SV_Position"
 ;                OpName %COLOR "COLOR"
 ;                OpName %SV_Target "SV_Target"
 ;                OpName %PSMain "PSMain"
-;                OpDecorate %SV_Position Location 0
+;                OpDecorate %gl_Position BuiltIn Position
 ;                OpDecorate %COLOR Location 1
 ;                OpDecorate %SV_Target Location 0
 ;        %uint = OpTypeInt 32 0
@@ -131,7 +130,7 @@ attributes #1 = { nounwind }
 ;          %15 = OpTypeFunction %void
 ; %_ptr_Input_float = OpTypePointer Input %float
 ; %_ptr_Output_float = OpTypePointer Output %float
-; %SV_Position = OpVariable %_ptr_Input_v4float Input
+; %gl_Position = OpVariable %_ptr_Input_v4float Input
 ;       %COLOR = OpVariable %_ptr_Input_v4float Input
 ;   %SV_Target = OpVariable %_ptr_Output_v4float Output
 ;      %PSMain = OpFunction %void None %15

+ 7 - 8
tools/clang/test/Dxil2Spv/passthru-vs.ll

@@ -123,15 +123,14 @@ attributes #1 = { nounwind }
 ; ; Schema: 0
 ;                OpCapability Shader
 ;                OpMemoryModel Logical GLSL450
-;                OpEntryPoint Vertex %VSMain "VSMain" %POSITION %COLOR %SV_Position %COLOR_0
+;                OpEntryPoint Vertex %VSMain "VSMain" %POSITION %COLOR %gl_Position %COLOR_0
 ;                OpName %POSITION "POSITION"
 ;                OpName %COLOR "COLOR"
-;                OpName %SV_Position "SV_Position"
 ;                OpName %COLOR_0 "COLOR"
 ;                OpName %VSMain "VSMain"
 ;                OpDecorate %POSITION Location 0
 ;                OpDecorate %COLOR Location 1
-;                OpDecorate %SV_Position Location 0
+;                OpDecorate %gl_Position BuiltIn Position
 ;                OpDecorate %COLOR_0 Location 1
 ;        %uint = OpTypeInt 32 0
 ;      %uint_0 = OpConstant %uint 0
@@ -148,7 +147,7 @@ attributes #1 = { nounwind }
 ; %_ptr_Output_float = OpTypePointer Output %float
 ;    %POSITION = OpVariable %_ptr_Input_v4float Input
 ;       %COLOR = OpVariable %_ptr_Input_v4float Input
-; %SV_Position = OpVariable %_ptr_Output_v4float Output
+; %gl_Position = OpVariable %_ptr_Output_v4float Output
 ;     %COLOR_0 = OpVariable %_ptr_Output_v4float Output
 ;      %VSMain = OpFunction %void None %16
 ;          %17 = OpLabel
@@ -168,13 +167,13 @@ attributes #1 = { nounwind }
 ;          %32 = OpLoad %float %31
 ;          %33 = OpAccessChain %_ptr_Input_float %POSITION %uint_3
 ;          %34 = OpLoad %float %33
-;          %36 = OpAccessChain %_ptr_Output_float %SV_Position %uint_0
+;          %36 = OpAccessChain %_ptr_Output_float %gl_Position %uint_0
 ;                OpStore %36 %28
-;          %37 = OpAccessChain %_ptr_Output_float %SV_Position %uint_1
+;          %37 = OpAccessChain %_ptr_Output_float %gl_Position %uint_1
 ;                OpStore %37 %30
-;          %38 = OpAccessChain %_ptr_Output_float %SV_Position %uint_2
+;          %38 = OpAccessChain %_ptr_Output_float %gl_Position %uint_2
 ;                OpStore %38 %32
-;          %39 = OpAccessChain %_ptr_Output_float %SV_Position %uint_3
+;          %39 = OpAccessChain %_ptr_Output_float %gl_Position %uint_3
 ;                OpStore %39 %34
 ;          %40 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_0
 ;                OpStore %40 %20

+ 45 - 23
tools/clang/tools/dxil2spv/lib/dxil2spv.cpp

@@ -175,29 +175,43 @@ void Translator::createStageIOVariables(
   // Translate DXIL input signature to SPIR-V stage input vars.
   for (const std::unique_ptr<hlsl::DxilSignatureElement> &elem :
        inputSignature) {
-    clang::spirv::SpirvVariable *var = spvBuilder.addStageIOVar(
-        toSpirvType(elem.get()), spv::StorageClass::Input,
-        elem->GetSemanticName(), false, {});
-    unsigned id = elem->GetID();
-    interfaceVars.push_back(var);
-    inputSignatureElementMap[id] = var;
-
-    // Use unique DXIL signature element ID as SPIR-V Location.
-    spvBuilder.decorateLocation(var, id);
+    createStageIOVariable(elem.get());
   }
 
   // Translate DXIL input signature to SPIR-V stage ouput vars.
   for (const std::unique_ptr<hlsl::DxilSignatureElement> &elem :
        outputSignature) {
-    clang::spirv::SpirvVariable *var = spvBuilder.addStageIOVar(
-        toSpirvType(elem.get()), spv::StorageClass::Output,
-        elem->GetSemanticName(), false, {});
-    unsigned id = elem->GetID();
-    interfaceVars.push_back(var);
-    outputSignatureElementMap[id] = var;
+    createStageIOVariable(elem.get());
+  }
+}
+
+void Translator::createStageIOVariable(hlsl::DxilSignatureElement *elem) {
+  const spirv::SpirvType *spirvType = toSpirvType(elem);
+  spv::StorageClass storageClass =
+      elem->IsInput() ? spv::StorageClass::Input : spv::StorageClass::Output;
+  const unsigned id = elem->GetID();
+  spirv::SpirvVariable *var = nullptr;
+  switch (elem->GetKind()) {
+  case hlsl::Semantic::Kind::Position: {
+    var = spvBuilder.addStageBuiltinVar(spirvType, storageClass,
+                                        spv::BuiltIn::Position, false, {});
+    break;
+  }
+  default: {
+    var = spvBuilder.addStageIOVar(spirvType, storageClass,
+                                   elem->GetSemanticName(), false, {});
 
     // Use unique DXIL signature element ID as SPIR-V Location.
     spvBuilder.decorateLocation(var, id);
+    break;
+  }
+  }
+  interfaceVars.push_back(var);
+
+  if (storageClass == spv::StorageClass::Input) {
+    inputSignatureElementMap[id] = var;
+  } else {
+    outputSignatureElementMap[id] = var;
   }
 }
 
@@ -264,26 +278,33 @@ void Translator::createInstruction(llvm::Instruction &instruction) {
     switch (dxilOpcode) {
     case hlsl::DXIL::OpCode::LoadInput: {
       createLoadInputInstruction(callInstruction);
-    } break;
+      break;
+    }
     case hlsl::DXIL::OpCode::StoreOutput: {
       createStoreOutputInstruction(callInstruction);
-    } break;
+      break;
+    }
     case hlsl::DXIL::OpCode::ThreadId: {
       createThreadIdInstruction(callInstruction);
-    } break;
+      break;
+    }
     case hlsl::DXIL::OpCode::CreateHandle: {
       createHandleInstruction(callInstruction);
-    } break;
+      break;
+    }
     case hlsl::DXIL::OpCode::BufferLoad: {
       createBufferLoadInstruction(callInstruction);
-    } break;
+      break;
+    }
     case hlsl::DXIL::OpCode::BufferStore: {
       createBufferStoreInstruction(callInstruction);
-    } break;
+      break;
+    }
     default: {
       emitError("Unhandled DXIL opcode: %0")
           << hlsl::OP::GetOpCodeName(dxilOpcode);
-    } break;
+      break;
+    }
     }
   }
   // Handle binary operator instructions.
@@ -415,7 +436,8 @@ void Translator::createBinaryOpInstruction(llvm::BinaryOperator &instruction) {
 
     result = spvBuilder.createBinaryOp(spv::Op::OpShiftLeftLogical, uint32, val,
                                        spvShift, {});
-  } break;
+    break;
+  }
   default: {
     emitError("Unhandled LLVM binary opcode: %0") << opcode;
     return;

+ 4 - 0
tools/clang/tools/dxil2spv/lib/dxil2spv.h

@@ -65,6 +65,10 @@ private:
       const std::vector<std::unique_ptr<hlsl::DxilSignatureElement>>
           &outputSignature);
 
+  // Create SPIR-V stage IO variable or Builtin variable from DXIL signature
+  // element.
+  void createStageIOVariable(hlsl::DxilSignatureElement *elem);
+
   // Create SPIR-V module variables from DXIL resources.
   void createModuleVariables(
       const std::vector<std::unique_ptr<hlsl::DxilResource>> &resources);