Support multiple source languages, adding HLSL as an option.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 7a7baa2..1c6abec 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -160,15 +160,22 @@
//
// Translate glslang profile to SPIR-V source language.
-spv::SourceLanguage TranslateSourceLanguage(EProfile profile)
+spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile)
{
- switch (profile) {
- case ENoProfile:
- case ECoreProfile:
- case ECompatibilityProfile:
- return spv::SourceLanguageGLSL;
- case EEsProfile:
- return spv::SourceLanguageESSL;
+ switch (source) {
+ case glslang::EShSourceGlsl:
+ switch (profile) {
+ case ENoProfile:
+ case ECoreProfile:
+ case ECompatibilityProfile:
+ return spv::SourceLanguageGLSL;
+ case EEsProfile:
+ return spv::SourceLanguageESSL;
+ default:
+ return spv::SourceLanguageUnknown;
+ }
+ case glslang::EShSourceHlsl:
+ return spv::SourceLanguageHLSL;
default:
return spv::SourceLanguageUnknown;
}
@@ -587,7 +594,7 @@
spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
builder.clearAccessChain();
- builder.setSource(TranslateSourceLanguage(glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
+ builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
stdBuiltins = builder.import("GLSL.std.450");
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
shaderEntry = builder.makeEntrypoint(glslangIntermediate->getEntryPoint().c_str());
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index 7cf1c87..7ee86b5 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -64,7 +64,7 @@
// (for non-sparse mask enums, this is the number of enumurants)
//
-const int SourceLanguageCeiling = 5;
+const int SourceLanguageCeiling = 6; // HLSL todo: need official enumerant
const char* SourceString(int source)
{
@@ -74,6 +74,7 @@
case 2: return "GLSL";
case 3: return "OpenCL_C";
case 4: return "OpenCL_CPP";
+ case 5: return "HLSL";
case SourceLanguageCeiling:
default: return "Bad";
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index 5620aba..7447fcf 100755
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -61,6 +61,7 @@
SourceLanguageGLSL = 2,
SourceLanguageOpenCL_C = 3,
SourceLanguageOpenCL_CPP = 4,
+ SourceLanguageHLSL = 5,
};
enum ExecutionModel {
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 408f114..2e0db6d 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -74,6 +74,7 @@
EOptionVulkanRules = 0x2000,
EOptionDefaultDesktop = 0x4000,
EOptionOutputPreprocessed = 0x8000,
+ EOptionReadHlsl = 0x10000,
};
//
@@ -538,6 +539,9 @@
case 'd':
Options |= EOptionDefaultDesktop;
break;
+ case 'D':
+ Options |= EOptionReadHlsl;
+ break;
case 'e':
// HLSL todo: entry point handle needs much more sophistication.
// This is okay for one compilation unit with one entry point.
@@ -627,6 +631,8 @@
messages = (EShMessages)(messages | EShMsgVulkanRules);
if (Options & EOptionOutputPreprocessed)
messages = (EShMessages)(messages | EShMsgOnlyPreprocessor);
+ if (Options & EOptionReadHlsl)
+ messages = (EShMessages)(messages | EShMsgReadHlsl);
}
//
@@ -1047,6 +1053,7 @@
" creates the default configuration file (redirect to a .conf file)\n"
" -d default to desktop (#version 110) when there is no shader #version\n"
" (default is ES version 100)\n"
+ " -D input is HLSL\n"
" -e specify entry-point name\n"
" -h print this usage message\n"
" -i intermediate tree (glslang AST) is printed out\n"
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index 4b2bf83..230929a 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -307,11 +307,19 @@
glslang::ReleaseGlobalLock();
}
-bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion, int& version, EProfile& profile, int spv)
+// Return true if the shader was correctly specified for version/profile/stage.
+bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
+ EShSource source, int& version, EProfile& profile, int spv)
{
const int FirstProfileVersion = 150;
bool correct = true;
+ if (source == EShSourceHlsl) {
+ version = defaultVersion;
+ profile = ENoProfile;
+ return correct;
+ }
+
// Get a good version...
if (version == 0) {
version = defaultVersion;
@@ -552,7 +560,8 @@
}
int spv = (messages & EShMsgSpvRules) ? 100 : 0; // TODO find path to get real version number here, for now non-0 is what matters
- bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, version, profile, spv);
+ EShSource source = (messages & EShMsgReadHlsl) ? EShSourceHlsl : EShSourceGlsl;
+ bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, source, version, profile, spv);
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
bool warnVersionNotFirst = false;
if (! versionWillBeError && versionNotFirstToken) {
@@ -563,6 +572,7 @@
}
int vulkan = (messages & EShMsgVulkanRules) ? 100 : 0; // TODO find path to get real version number here, for now non-0 is what matters
+ intermediate.setSource(source);
intermediate.setVersion(version);
intermediate.setProfile(profile);
intermediate.setSpv(spv);
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index b1e833b..efffb71 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -124,7 +124,8 @@
//
class TIntermediate {
public:
- explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), spv(0),
+ explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
+ source(EShSourceNone), language(l), profile(p), version(v), spv(0), treeRoot(0),
numMains(0), numErrors(0), numPushConstants(0), recursive(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),
@@ -143,8 +144,10 @@
bool postProcess(TIntermNode*, EShLanguage);
void output(TInfoSink&, bool tree);
- void removeTree();
+ void removeTree();
+ void setSource(EShSource s) { source = s; }
+ EShSource getSource() const { return source; }
void setEntryPoint(const char* ep) { entryPoint = ep; }
const TString& getEntryPoint() const { return entryPoint; }
void setVersion(int v) { version = v; }
@@ -339,12 +342,13 @@
bool userOutputUsed() const;
static int getBaseAlignmentScalar(const TType&, int& size);
- const EShLanguage language;
+ const EShLanguage language; // stage, known at construction time
+ EShSource source; // source language, known a bit later
TString entryPoint;
- TIntermNode* treeRoot;
EProfile profile;
int version;
int spv;
+ TIntermNode* treeRoot;
std::set<std::string> requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
TBuiltInResource resources;
int numMains;
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 7a708f2..e676211 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -86,7 +86,7 @@
EShLangFragment,
EShLangCompute,
EShLangCount,
-} EShLanguage;
+} EShLanguage; // would be better as stage, but this is ancient now
typedef enum {
EShLangVertexMask = (1 << EShLangVertex),
@@ -99,6 +99,12 @@
namespace glslang {
+typedef enum {
+ EShSourceNone,
+ EShSourceGlsl,
+ EShSourceHlsl,
+} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
+
const char* StageName(EShLanguage);
} // end namespace glslang
@@ -132,6 +138,7 @@
EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation
EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor
+ EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
};
//