[spirv] Create hlsl::ShaderModel out of shader model string (#524)
Previously we parse the string by ourselves.
This commit is contained in:
Родитель
e4db8bda97
Коммит
50517e7f34
|
@ -139,8 +139,7 @@ void DeclResultIdMapper::createStageVariables(const DeclaratorDecl *decl,
|
|||
stageVars.insert(varId);
|
||||
} else {
|
||||
// Handle output builtin variables first
|
||||
if (shaderStage == spv::ExecutionModel::Vertex &&
|
||||
kind == StageVarKind::Position) {
|
||||
if (shaderModel.IsVS() && kind == StageVarKind::Position) {
|
||||
const uint32_t varId =
|
||||
theBuilder.addStageBuiltinVariable(typeId, spv::BuiltIn::Position);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "dxc/HLSL//DxilShaderModel.h"
|
||||
#include "spirv/1.0/spirv.hpp11"
|
||||
#include "clang/SPIRV/ModuleBuilder.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
@ -49,8 +50,8 @@ namespace spirv {
|
|||
/// * FieldDecl if the field is attached with a semantic.
|
||||
class DeclResultIdMapper {
|
||||
public:
|
||||
inline DeclResultIdMapper(spv::ExecutionModel stage, ModuleBuilder &builder,
|
||||
DiagnosticsEngine &diag);
|
||||
inline DeclResultIdMapper(const hlsl::ShaderModel &stage,
|
||||
ModuleBuilder &builder, DiagnosticsEngine &diag);
|
||||
|
||||
/// \brief Creates the stage variables by parsing the semantics attached to
|
||||
/// the given function's return value.
|
||||
|
@ -128,7 +129,7 @@ private:
|
|||
std::string getStageVarSemantic(const NamedDecl *decl) const;
|
||||
|
||||
private:
|
||||
const spv::ExecutionModel shaderStage;
|
||||
const hlsl::ShaderModel &shaderModel;
|
||||
ModuleBuilder &theBuilder;
|
||||
TypeTranslator typeTranslator;
|
||||
|
||||
|
@ -151,10 +152,10 @@ private:
|
|||
llvm::SmallVector<StageVarIdSemanticPair, 8> stageBuiltins;
|
||||
};
|
||||
|
||||
DeclResultIdMapper::DeclResultIdMapper(spv::ExecutionModel stage,
|
||||
DeclResultIdMapper::DeclResultIdMapper(const hlsl::ShaderModel &model,
|
||||
ModuleBuilder &builder,
|
||||
DiagnosticsEngine &diag)
|
||||
: shaderStage(stage), theBuilder(builder), typeTranslator(builder, diag) {}
|
||||
: shaderModel(model), theBuilder(builder), typeTranslator(builder, diag) {}
|
||||
|
||||
} // end namespace spirv
|
||||
} // end namespace clang
|
||||
|
|
|
@ -128,17 +128,18 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci)
|
|||
: theCompilerInstance(ci), astContext(ci.getASTContext()),
|
||||
diags(ci.getDiagnostics()),
|
||||
entryFunctionName(ci.getCodeGenOpts().HLSLEntryFunction),
|
||||
shaderStage(getSpirvShaderStageFromHlslProfile(
|
||||
shaderModel(*hlsl::ShaderModel::GetByName(
|
||||
ci.getCodeGenOpts().HLSLProfile.c_str())),
|
||||
theContext(), theBuilder(&theContext),
|
||||
declIdMapper(shaderStage, theBuilder, diags),
|
||||
declIdMapper(shaderModel, theBuilder, diags),
|
||||
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) {
|
||||
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.
|
||||
theBuilder.setAddressingModel(spv::AddressingModel::Logical);
|
||||
|
@ -162,10 +163,11 @@ void SPIRVEmitter::HandleTranslationUnit(ASTContext &context) {
|
|||
doDecl(workQueue[i]);
|
||||
}
|
||||
|
||||
theBuilder.addEntryPoint(shaderStage, entryFunctionId, entryFunctionName,
|
||||
theBuilder.addEntryPoint(getSpirvShaderStage(shaderModel), entryFunctionId,
|
||||
entryFunctionName,
|
||||
declIdMapper.collectStageVariables());
|
||||
|
||||
AddExecutionModeForEntryPoint(shaderStage, entryFunctionId);
|
||||
AddExecutionModeForEntryPoint(entryFunctionId);
|
||||
|
||||
// Add Location decorations to stage input/output variables.
|
||||
declIdMapper.finalizeStageIOLocations();
|
||||
|
@ -184,7 +186,7 @@ void SPIRVEmitter::doDecl(const Decl *decl) {
|
|||
} else {
|
||||
// TODO: Implement handling of other Decl types.
|
||||
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
|
||||
SPIRVEmitter::getSpirvShaderStageFromHlslProfile(const char *profile) {
|
||||
assert(profile && "nullptr passed as HLSL profile.");
|
||||
|
||||
SPIRVEmitter::getSpirvShaderStage(const hlsl::ShaderModel &model) {
|
||||
// DXIL Models are:
|
||||
// Profile (DXIL Model) : HLSL Shader Kind : SPIR-V Shader Stage
|
||||
// vs_<version> : Vertex Shader : Vertex Shader
|
||||
|
@ -2264,32 +2264,30 @@ SPIRVEmitter::getSpirvShaderStageFromHlslProfile(const char *profile) {
|
|||
// gs_<version> : Geometry Shader : Geometry Shader
|
||||
// ps_<version> : Pixel Shader : Fragment Shader
|
||||
// cs_<version> : Compute Shader : Compute Shader
|
||||
switch (profile[0]) {
|
||||
case 'v':
|
||||
switch (model.GetKind()) {
|
||||
case hlsl::ShaderModel::Kind::Vertex:
|
||||
return spv::ExecutionModel::Vertex;
|
||||
case 'h':
|
||||
case hlsl::ShaderModel::Kind::Hull:
|
||||
return spv::ExecutionModel::TessellationControl;
|
||||
case 'd':
|
||||
case hlsl::ShaderModel::Kind::Domain:
|
||||
return spv::ExecutionModel::TessellationEvaluation;
|
||||
case 'g':
|
||||
case hlsl::ShaderModel::Kind::Geometry:
|
||||
return spv::ExecutionModel::Geometry;
|
||||
case 'p':
|
||||
case hlsl::ShaderModel::Kind::Pixel:
|
||||
return spv::ExecutionModel::Fragment;
|
||||
case 'c':
|
||||
case hlsl::ShaderModel::Kind::Compute:
|
||||
return spv::ExecutionModel::GLCompute;
|
||||
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);
|
||||
emitError("Tasselation shaders are currently not supported.");
|
||||
} else if (em == spv::ExecutionModel::Geometry) {
|
||||
} else if (shaderModel.IsGS()) {
|
||||
theBuilder.requireCapability(spv::Capability::Geometry);
|
||||
emitError("Geometry shaders are currently not supported.");
|
||||
} 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
|
||||
// fragment shaders. Currently using OriginUpperLeft as default.
|
||||
theBuilder.addExecutionMode(entryPointId,
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "dxc/HLSL/DxilShaderModel.h"
|
||||
#include "clang/AST/AST.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
@ -249,14 +250,14 @@ private:
|
|||
QualType targetType);
|
||||
|
||||
private:
|
||||
spv::ExecutionModel getSpirvShaderStageFromHlslProfile(const char *profile);
|
||||
static spv::ExecutionModel
|
||||
getSpirvShaderStage(const hlsl::ShaderModel &model);
|
||||
|
||||
void AddRequiredCapabilitiesForExecutionModel(spv::ExecutionModel em);
|
||||
void AddRequiredCapabilitiesForShaderModel();
|
||||
|
||||
/// \brief Adds the execution mode for the given entry point based on the
|
||||
/// execution model.
|
||||
void AddExecutionModeForEntryPoint(spv::ExecutionModel execModel,
|
||||
uint32_t entryPointId);
|
||||
/// shader model.
|
||||
void AddExecutionModeForEntryPoint(uint32_t entryPointId);
|
||||
|
||||
private:
|
||||
/// \brief Returns true iff *all* the case values in the given switch
|
||||
|
@ -366,7 +367,7 @@ private:
|
|||
/// Entry function name and shader stage. Both of them are derived from the
|
||||
/// command line and should be const.
|
||||
const llvm::StringRef entryFunctionName;
|
||||
const spv::ExecutionModel shaderStage;
|
||||
const hlsl::ShaderModel &shaderModel;
|
||||
|
||||
SPIRVContext theContext;
|
||||
ModuleBuilder theBuilder;
|
||||
|
|
Загрузка…
Ссылка в новой задаче