|
@@ -128,17 +128,18 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci)
|
|
: theCompilerInstance(ci), astContext(ci.getASTContext()),
|
|
: theCompilerInstance(ci), astContext(ci.getASTContext()),
|
|
diags(ci.getDiagnostics()),
|
|
diags(ci.getDiagnostics()),
|
|
entryFunctionName(ci.getCodeGenOpts().HLSLEntryFunction),
|
|
entryFunctionName(ci.getCodeGenOpts().HLSLEntryFunction),
|
|
- shaderStage(getSpirvShaderStageFromHlslProfile(
|
|
|
|
|
|
+ shaderModel(*hlsl::ShaderModel::GetByName(
|
|
ci.getCodeGenOpts().HLSLProfile.c_str())),
|
|
ci.getCodeGenOpts().HLSLProfile.c_str())),
|
|
theContext(), theBuilder(&theContext),
|
|
theContext(), theBuilder(&theContext),
|
|
- declIdMapper(shaderStage, theBuilder, diags),
|
|
|
|
|
|
+ declIdMapper(shaderModel, theBuilder, diags),
|
|
typeTranslator(theBuilder, diags), entryFunctionId(0),
|
|
typeTranslator(theBuilder, diags), entryFunctionId(0),
|
|
- curFunction(nullptr) {}
|
|
|
|
|
|
+ curFunction(nullptr) {
|
|
|
|
+ if (shaderModel.GetKind() == hlsl::ShaderModel::Kind::Invalid)
|
|
|
|
+ emitError("unknown shader module: %0") << shaderModel.GetName();
|
|
|
|
+}
|
|
|
|
|
|
void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {
|
|
void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {
|
|
- const spv::ExecutionModel em = getSpirvShaderStageFromHlslProfile(
|
|
|
|
- theCompilerInstance.getCodeGenOpts().HLSLProfile.c_str());
|
|
|
|
- AddRequiredCapabilitiesForExecutionModel(em);
|
|
|
|
|
|
+ AddRequiredCapabilitiesForShaderModel();
|
|
|
|
|
|
// Addressing and memory model are required in a valid SPIR-V module.
|
|
// Addressing and memory model are required in a valid SPIR-V module.
|
|
theBuilder.setAddressingModel(spv::AddressingModel::Logical);
|
|
theBuilder.setAddressingModel(spv::AddressingModel::Logical);
|
|
@@ -162,10 +163,11 @@ void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {
|
|
doDecl(workQueue[i]);
|
|
doDecl(workQueue[i]);
|
|
}
|
|
}
|
|
|
|
|
|
- theBuilder.addEntryPoint(shaderStage, entryFunctionId, entryFunctionName,
|
|
|
|
|
|
+ theBuilder.addEntryPoint(getSpirvShaderStage(shaderModel), entryFunctionId,
|
|
|
|
+ entryFunctionName,
|
|
declIdMapper.collectStageVariables());
|
|
declIdMapper.collectStageVariables());
|
|
|
|
|
|
- AddExecutionModeForEntryPoint(shaderStage, entryFunctionId);
|
|
|
|
|
|
+ AddExecutionModeForEntryPoint(entryFunctionId);
|
|
|
|
|
|
// Add Location decorations to stage input/output variables.
|
|
// Add Location decorations to stage input/output variables.
|
|
declIdMapper.finalizeStageIOLocations();
|
|
declIdMapper.finalizeStageIOLocations();
|
|
@@ -184,7 +186,7 @@ void SPIRVEmitter::doDecl(const Decl *decl) {
|
|
} else {
|
|
} else {
|
|
// TODO: Implement handling of other Decl types.
|
|
// TODO: Implement handling of other Decl types.
|
|
emitWarning("Decl type '%0' is not supported yet.")
|
|
emitWarning("Decl type '%0' is not supported yet.")
|
|
- << std::string(decl->getDeclKindName());
|
|
|
|
|
|
+ << decl->getDeclKindName();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2253,9 +2255,7 @@ uint32_t SPIRVEmitter::translateAPFloat(const llvm::APFloat &floatValue,
|
|
}
|
|
}
|
|
|
|
|
|
spv::ExecutionModel
|
|
spv::ExecutionModel
|
|
-SPIRVEmitter::getSpirvShaderStageFromHlslProfile(const char *profile) {
|
|
|
|
- assert(profile && "nullptr passed as HLSL profile.");
|
|
|
|
-
|
|
|
|
|
|
+SPIRVEmitter::getSpirvShaderStage(const hlsl::ShaderModel &model) {
|
|
// DXIL Models are:
|
|
// DXIL Models are:
|
|
// Profile (DXIL Model) : HLSL Shader Kind : SPIR-V Shader Stage
|
|
// Profile (DXIL Model) : HLSL Shader Kind : SPIR-V Shader Stage
|
|
// vs_<version> : Vertex Shader : Vertex Shader
|
|
// vs_<version> : Vertex Shader : Vertex Shader
|
|
@@ -2264,32 +2264,30 @@ SPIRVEmitter::getSpirvShaderStageFromHlslProfile(const char *profile) {
|
|
// gs_<version> : Geometry Shader : Geometry Shader
|
|
// gs_<version> : Geometry Shader : Geometry Shader
|
|
// ps_<version> : Pixel Shader : Fragment Shader
|
|
// ps_<version> : Pixel Shader : Fragment Shader
|
|
// cs_<version> : Compute Shader : Compute Shader
|
|
// cs_<version> : Compute Shader : Compute Shader
|
|
- switch (profile[0]) {
|
|
|
|
- case 'v':
|
|
|
|
|
|
+ switch (model.GetKind()) {
|
|
|
|
+ case hlsl::ShaderModel::Kind::Vertex:
|
|
return spv::ExecutionModel::Vertex;
|
|
return spv::ExecutionModel::Vertex;
|
|
- case 'h':
|
|
|
|
|
|
+ case hlsl::ShaderModel::Kind::Hull:
|
|
return spv::ExecutionModel::TessellationControl;
|
|
return spv::ExecutionModel::TessellationControl;
|
|
- case 'd':
|
|
|
|
|
|
+ case hlsl::ShaderModel::Kind::Domain:
|
|
return spv::ExecutionModel::TessellationEvaluation;
|
|
return spv::ExecutionModel::TessellationEvaluation;
|
|
- case 'g':
|
|
|
|
|
|
+ case hlsl::ShaderModel::Kind::Geometry:
|
|
return spv::ExecutionModel::Geometry;
|
|
return spv::ExecutionModel::Geometry;
|
|
- case 'p':
|
|
|
|
|
|
+ case hlsl::ShaderModel::Kind::Pixel:
|
|
return spv::ExecutionModel::Fragment;
|
|
return spv::ExecutionModel::Fragment;
|
|
- case 'c':
|
|
|
|
|
|
+ case hlsl::ShaderModel::Kind::Compute:
|
|
return spv::ExecutionModel::GLCompute;
|
|
return spv::ExecutionModel::GLCompute;
|
|
default:
|
|
default:
|
|
- emitError("Unknown HLSL Profile: %0") << profile;
|
|
|
|
- return spv::ExecutionModel::Fragment;
|
|
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
+ llvm_unreachable("unknown shader model");
|
|
}
|
|
}
|
|
|
|
|
|
-void SPIRVEmitter::AddRequiredCapabilitiesForExecutionModel(
|
|
|
|
- spv::ExecutionModel em) {
|
|
|
|
- if (em == spv::ExecutionModel::TessellationControl ||
|
|
|
|
- em == spv::ExecutionModel::TessellationEvaluation) {
|
|
|
|
|
|
+void SPIRVEmitter::AddRequiredCapabilitiesForShaderModel() {
|
|
|
|
+ if (shaderModel.IsHS() || shaderModel.IsDS()) {
|
|
theBuilder.requireCapability(spv::Capability::Tessellation);
|
|
theBuilder.requireCapability(spv::Capability::Tessellation);
|
|
emitError("Tasselation shaders are currently not supported.");
|
|
emitError("Tasselation shaders are currently not supported.");
|
|
- } else if (em == spv::ExecutionModel::Geometry) {
|
|
|
|
|
|
+ } else if (shaderModel.IsGS()) {
|
|
theBuilder.requireCapability(spv::Capability::Geometry);
|
|
theBuilder.requireCapability(spv::Capability::Geometry);
|
|
emitError("Geometry shaders are currently not supported.");
|
|
emitError("Geometry shaders are currently not supported.");
|
|
} else {
|
|
} else {
|
|
@@ -2297,9 +2295,8 @@ void SPIRVEmitter::AddRequiredCapabilitiesForExecutionModel(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void SPIRVEmitter::AddExecutionModeForEntryPoint(spv::ExecutionModel execModel,
|
|
|
|
- uint32_t entryPointId) {
|
|
|
|
- if (execModel == spv::ExecutionModel::Fragment) {
|
|
|
|
|
|
+void SPIRVEmitter::AddExecutionModeForEntryPoint(uint32_t entryPointId) {
|
|
|
|
+ if (shaderModel.IsPS()) {
|
|
// TODO: Implement the logic to determine the proper Execution Mode for
|
|
// TODO: Implement the logic to determine the proper Execution Mode for
|
|
// fragment shaders. Currently using OriginUpperLeft as default.
|
|
// fragment shaders. Currently using OriginUpperLeft as default.
|
|
theBuilder.addExecutionMode(entryPointId,
|
|
theBuilder.addExecutionMode(entryPointId,
|