SPV/Standalone: Support specifying arbitrary versions of SPIR-V.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
old mode 100644
new mode 100755
index e1ae7b4..f6cc6c4
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1265,14 +1265,14 @@
std::string text;
const std::vector<std::string>& processes = glslangIntermediate->getProcesses();
for (int p = 0; p < (int)processes.size(); ++p) {
- if (glslangIntermediate->getSpv().spv < 0x00010100) {
+ if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_1) {
text.append("// OpModuleProcessed ");
text.append(processes[p]);
text.append("\n");
} else
builder.addModuleProcessed(processes[p]);
}
- if (glslangIntermediate->getSpv().spv < 0x00010100 && (int)processes.size() > 0)
+ if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_1 && (int)processes.size() > 0)
text.append("#line 1\n");
text.append(glslangIntermediate->getSourceText());
builder.setSourceText(text);
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index cb5a8d2..060428b 100755
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -161,13 +161,17 @@
const char* variableName = nullptr;
bool HlslEnable16BitTypes = false;
std::vector<std::string> IncludeDirectoryList;
-int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
-glslang::EShTargetClientVersion VulkanClientVersion =
- glslang::EShTargetVulkan_1_0; // would map to, say, Vulkan 1.0
-glslang::EShTargetClientVersion OpenGLClientVersion =
- glslang::EShTargetOpenGL_450; // doesn't influence anything yet, but maps to OpenGL 4.50
-glslang::EShTargetLanguageVersion TargetVersion =
- glslang::EShTargetSpv_1_0; // maps to, say, SPIR-V 1.0
+
+// Source environment
+// (source 'Client' is currently the same as target 'Client')
+int ClientInputSemanticsVersion = 100;
+
+// Target environment
+glslang::EShClient Client = glslang::EShClientNone; // will stay EShClientNone if only validating
+glslang::EShTargetClientVersion ClientVersion; // not valid until Client is set
+glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone;
+glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set
+
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
// Per descriptor-set binding base data
@@ -421,6 +425,9 @@
// minimum needed (without overriding something else) to target Vulkan SPIR-V
const auto setVulkanSpv = []() {
+ if (Client == glslang::EShClientNone)
+ ClientVersion = glslang::EShTargetVulkan_1_0;
+ Client = glslang::EShClientVulkan;
Options |= EOptionSpv;
Options |= EOptionVulkanRules;
Options |= EOptionLinkProgram;
@@ -428,6 +435,9 @@
// minimum needed (without overriding something else) to target OpenGL SPIR-V
const auto setOpenGlSpv = []() {
+ if (Client == glslang::EShClientNone)
+ ClientVersion = glslang::EShTargetOpenGL_450;
+ Client = glslang::EShClientOpenGL;
Options |= EOptionSpv;
Options |= EOptionLinkProgram;
// undo a -H default to Vulkan
@@ -561,16 +571,30 @@
if (argc > 1) {
if (strcmp(argv[1], "vulkan1.0") == 0) {
setVulkanSpv();
- VulkanClientVersion = glslang::EShTargetVulkan_1_0;
+ ClientVersion = glslang::EShTargetVulkan_1_0;
} else if (strcmp(argv[1], "vulkan1.1") == 0) {
setVulkanSpv();
- TargetVersion = glslang::EShTargetSpv_1_3;
- VulkanClientVersion = glslang::EShTargetVulkan_1_1;
+ ClientVersion = glslang::EShTargetVulkan_1_1;
} else if (strcmp(argv[1], "opengl") == 0) {
setOpenGlSpv();
- OpenGLClientVersion = glslang::EShTargetOpenGL_450;
+ ClientVersion = glslang::EShTargetOpenGL_450;
+ } else if (strcmp(argv[1], "spirv1.0") == 0) {
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_0;
+ } else if (strcmp(argv[1], "spirv1.1") == 0) {
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_1;
+ } else if (strcmp(argv[1], "spirv1.2") == 0) {
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_2;
+ } else if (strcmp(argv[1], "spirv1.3") == 0) {
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_3;
+ } else if (strcmp(argv[1], "spirv1.4") == 0) {
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_4;
} else
- Error("--target-env expected vulkan1.0, vulkan1.1, or opengl");
+ Error("--target-env expected one of: vulkan1.0, vulkan1.1, opengl, spirv1.0, spirv1.1, spirv1.2, or spirv1.3");
}
bumpArg();
} else if (lowerword == "variable-name" || // synonyms
@@ -604,7 +628,7 @@
Options |= EOptionOutputPreprocessed;
break;
case 'G':
- // OpenGL Client
+ // OpenGL client
setOpenGlSpv();
if (argv[0][2] != 0)
ClientInputSemanticsVersion = getAttachedNumber("-G<num> client input semantics");
@@ -736,6 +760,28 @@
if ((Options & EOptionFlattenUniformArrays) != 0 &&
(Options & EOptionReadHlsl) == 0)
Error("uniform array flattening only valid when compiling HLSL source.");
+
+ // rationalize client and target language
+ if (TargetLanguage == glslang::EShTargetNone) {
+ switch (ClientVersion) {
+ case glslang::EShTargetVulkan_1_0:
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_0;
+ break;
+ case glslang::EShTargetVulkan_1_1:
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_3;
+ break;
+ case glslang::EShTargetOpenGL_450:
+ TargetLanguage = glslang::EShTargetSpv;
+ TargetVersion = glslang::EShTargetSpv_1_0;
+ break;
+ default:
+ break;
+ }
+ }
+ if (TargetLanguage != glslang::EShTargetNone && Client == glslang::EShClientNone)
+ Error("To generate SPIR-V, also specify client semantics. See -G and -V.");
}
//
@@ -936,18 +982,11 @@
// Set up the environment, some subsettings take precedence over earlier
// ways of setting things.
if (Options & EOptionSpv) {
- if (Options & EOptionVulkanRules) {
- shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
- : glslang::EShSourceGlsl,
- compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
- shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
- } else {
- shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
- : glslang::EShSourceGlsl,
- compUnit.stage, glslang::EShClientOpenGL, ClientInputSemanticsVersion);
- shader->setEnvClient(glslang::EShClientOpenGL, OpenGLClientVersion);
- }
- shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
+ shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
+ : glslang::EShSourceGlsl,
+ compUnit.stage, Client, ClientInputSemanticsVersion);
+ shader->setEnvClient(Client, ClientVersion);
+ shader->setEnvTarget(TargetLanguage, TargetVersion);
if (targetHlslFunctionality1)
shader->setEnvTargetHlslFunctionality1();
}
@@ -1515,12 +1554,16 @@
" --sep synonym for --source-entrypoint\n"
" --stdin read from stdin instead of from a file;\n"
" requires providing the shader stage using -S\n"
- " --target-env {vulkan1.0 | vulkan1.1 | opengl} \n"
+ " --target-env {vulkan1.0 | vulkan1.1 | opengl | \n"
+ " spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3}\n"
" set execution environment that emitted code\n"
- " will execute in (as opposed to the language\n"
+ " will execute in (versus source language\n"
" semantics selected by --client) defaults:\n"
" * 'vulkan1.0' under '--client vulkan<ver>'\n"
" * 'opengl' under '--client opengl<ver>'\n"
+ " * 'spirv1.0' under --target-env vulkan1.0\n"
+ " * 'spirv1.3' under --target-env vulkan1.1\n"
+ " multiple --targen-env can be specified.\n"
" --variable-name <name>\n"
" --vn <name> creates a C header file that contains a\n"
" uint32_t array named <name>\n"
diff --git a/Test/runtests b/Test/runtests
index 4a4a761..8cc8b7a 100755
--- a/Test/runtests
+++ b/Test/runtests
@@ -166,13 +166,14 @@
# Test --client and --target-env
#
echo "Testing --client and --target-env"
-$EXE --client vulkan100 spv.targetVulkan.vert || HASERROR=1
-$EXE --client opengl100 spv.targetOpenGL.vert || HASERROR=1
-$EXE --target-env vulkan1.0 spv.targetVulkan.vert || HASERROR=1
-$EXE --target-env vulkan1.1 spv.targetVulkan.vert || HASERROR=1
-$EXE --target-env opengl spv.targetOpenGL.vert || HASERROR=1
-$EXE -V100 spv.targetVulkan.vert || HASERROR=1
-$EXE -G100 spv.targetOpenGL.vert || HASERROR=1
+$EXE --client vulkan100 spv.targetVulkan.vert || HASERROR=1
+$EXE --client opengl100 spv.targetOpenGL.vert || HASERROR=1
+$EXE --target-env vulkan1.0 spv.targetVulkan.vert || HASERROR=1
+$EXE --target-env vulkan1.1 spv.targetVulkan.vert || HASERROR=1
+$EXE --target-env opengl spv.targetOpenGL.vert || HASERROR=1
+$EXE -V100 spv.targetVulkan.vert || HASERROR=1
+$EXE -G100 spv.targetOpenGL.vert || HASERROR=1
+$EXE --target-env spirv1.2 -V spv.targetVulkan.vert || HASERROR=1
#
# Testing GLSL entry point rename
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
old mode 100644
new mode 100755
index 74ab352..0708829
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -154,7 +154,10 @@
typedef enum {
EShTargetSpv_1_0 = (1 << 16),
+ EShTargetSpv_1_1 = (1 << 16) | (1 << 8),
+ EShTargetSpv_1_2 = (1 << 16) | (2 << 8),
EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
+ EShTargetSpv_1_4 = (1 << 16) | (4 << 8),
} EShTargetLanguageVersion;
struct TInputLanguage {