Revert "Revert "GL_ext_vulkan_glsl_relaxed extension support, and cross stage aware IO mapper""
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index fdbf027..923ded3 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -110,6 +110,7 @@
bool NaNClamp = false;
bool stripDebugInfo = false;
bool beQuiet = false;
+bool VulkanRulesRelaxed = false;
//
// Return codes from main/exit().
@@ -195,6 +196,17 @@
std::array<std::array<TPerSetBaseBinding, EShLangCount>, glslang::EResCount> baseBindingForSet;
std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
+std::vector<std::pair<std::string, glslang::TBlockStorageClass>> blockStorageOverrides;
+
+bool setGlobalUniformBlock = false;
+std::string globalUniformName;
+unsigned int globalUniformBinding;
+unsigned int globalUniformSet;
+
+bool setGlobalBufferBlock = false;
+std::string atomicCounterBlockName;
+unsigned int atomicCounterBlockSet;
+
// Add things like "#define ..." to a preamble to use in the beginning of the shader.
class TPreamble {
public:
@@ -397,6 +409,115 @@
}
//
+// Process an optional binding base of one the forms:
+// --argname name {uniform|buffer|push_constant}
+void ProcessBlockStorage(int& argc, char**& argv, std::vector<std::pair<std::string, glslang::TBlockStorageClass>>& storage)
+{
+ if (argc < 3)
+ usage();
+
+ glslang::TBlockStorageClass blockStorage = glslang::EbsNone;
+
+ std::string strBacking(argv[2]);
+ if (strBacking == "uniform")
+ blockStorage = glslang::EbsUniform;
+ else if (strBacking == "buffer")
+ blockStorage = glslang::EbsStorageBuffer;
+ else if (strBacking == "push_constant")
+ blockStorage = glslang::EbsPushConstant;
+ else {
+ printf("%s: invalid block storage\n", strBacking.c_str());
+ usage();
+ }
+
+ storage.push_back(std::make_pair(std::string(argv[1]), blockStorage));
+
+ argc -= 2;
+ argv += 2;
+}
+
+inline bool isNonDigit(char c) {
+ // a non-digit character valid in a glsl identifier
+ return (c == '_') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+// whether string isa valid identifier to be used in glsl
+bool isValidIdentifier(const char* str) {
+ std::string idn(str);
+
+ if (idn.length() == 0) {
+ return false;
+ }
+
+ if (idn.length() >= 3 && idn.substr(0, 3) == "gl_") {
+ // identifiers startin with "gl_" are reserved
+ return false;
+ }
+
+ if (!isNonDigit(idn[0])) {
+ return false;
+ }
+
+ for (unsigned int i = 1; i < idn.length(); ++i) {
+ if (!(isdigit(idn[i]) || isNonDigit(idn[i]))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Process settings for either the global buffer block or global unfirom block
+// of the form:
+// --argname name set binding
+void ProcessGlobalBlockSettings(int& argc, char**& argv, std::string* name, unsigned int* set, unsigned int* binding)
+{
+ if (argc < 4)
+ usage();
+
+ unsigned int curArg = 1;
+
+ assert(name || set || binding);
+
+ if (name) {
+ if (!isValidIdentifier(argv[curArg])) {
+ printf("%s: invalid identifier\n", argv[curArg]);
+ usage();
+ }
+ *name = argv[curArg];
+
+ curArg++;
+ }
+
+ if (set) {
+ errno = 0;
+ int setVal = ::strtol(argv[curArg], NULL, 10);
+ if (errno || setVal < 0) {
+ printf("%s: invalid set\n", argv[curArg]);
+ usage();
+ }
+ *set = setVal;
+
+ curArg++;
+ }
+
+ if (binding) {
+ errno = 0;
+ int bindingVal = ::strtol(argv[curArg], NULL, 10);
+ if (errno || bindingVal < 0) {
+ printf("%s: invalid binding\n", argv[curArg]);
+ usage();
+ }
+ *binding = bindingVal;
+
+ curArg++;
+ }
+
+ argc -= (curArg - 1);
+ argv += (curArg - 1);
+}
+
+//
// Do all command-line argument parsing. This includes building up the work-items
// to be processed later, and saving all the command-line options.
//
@@ -569,6 +690,17 @@
lowerword == "resource-set-binding" ||
lowerword == "rsb") {
ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding);
+ } else if (lowerword == "set-block-storage" ||
+ lowerword == "sbs") {
+ ProcessBlockStorage(argc, argv, blockStorageOverrides);
+ } else if (lowerword == "set-atomic-counter-block" ||
+ lowerword == "sacb") {
+ ProcessGlobalBlockSettings(argc, argv, &atomicCounterBlockName, &atomicCounterBlockSet, nullptr);
+ setGlobalBufferBlock = true;
+ } else if (lowerword == "set-default-uniform-block" ||
+ lowerword == "sdub") {
+ ProcessGlobalBlockSettings(argc, argv, &globalUniformName, &globalUniformSet, &globalUniformBinding);
+ setGlobalUniformBlock = true;
} else if (lowerword == "shift-image-bindings" || // synonyms
lowerword == "shift-image-binding" ||
lowerword == "sib") {
@@ -721,6 +853,9 @@
else
Error("unknown -O option");
break;
+ case 'R':
+ VulkanRulesRelaxed = true;
+ break;
case 'S':
if (argc <= 1)
Error("no <stage> specified for -S");
@@ -1068,6 +1203,24 @@
shader->setUniformLocationBase(uniformBase);
#endif
+ if (VulkanRulesRelaxed) {
+ for (auto& storageOverride : blockStorageOverrides) {
+ shader->addBlockStorageOverride(storageOverride.first.c_str(),
+ storageOverride.second);
+ }
+
+ if (setGlobalBufferBlock) {
+ shader->setAtomicCounterBlockName(atomicCounterBlockName.c_str());
+ shader->setAtomicCounterBlockSet(atomicCounterBlockSet);
+ }
+
+ if (setGlobalUniformBlock) {
+ shader->setGlobalUniformBlockName(globalUniformName.c_str());
+ shader->setGlobalUniformSet(globalUniformSet);
+ shader->setGlobalUniformBinding(globalUniformBinding);
+ }
+ }
+
shader->setNanMinMaxClamp(NaNClamp);
#ifdef ENABLE_HLSL
@@ -1091,6 +1244,8 @@
if (targetHlslFunctionality1)
shader->setEnvTargetHlslFunctionality1();
#endif
+ if (VulkanRulesRelaxed)
+ shader->setEnvInputVulkanRulesRelaxed();
}
shaders.push_back(shader);
@@ -1572,6 +1727,9 @@
" is searched first, followed by left-to-right order of -I\n"
" -Od disables optimization; may cause illegal SPIR-V for HLSL\n"
" -Os optimizes SPIR-V to minimize size\n"
+ " -R use relaxed verification rules for generating Vulkan SPIR-V,\n"
+ " allowing the use of default uniforms, atomic_uints, and\n"
+ " gl_VertexID and gl_InstanceID keywords.\n"
" -S <stage> uses specified stage rather than parsing the file extension\n"
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
" -U<name> | --undef-macro <name> | --U <name>\n"
@@ -1649,6 +1807,22 @@
" --resource-set-binding [stage] set\n"
" set descriptor set for all resources\n"
" --rsb synonym for --resource-set-binding\n"
+ " --set-block-backing name {uniform|buffer|push_constant}\n"
+ " changes the backing type of a uniform, buffer,\n"
+ " or push_constant block declared in\n"
+ " in the program, when using -R option.\n"
+ " This can be used to change the backing\n"
+ " for existing blocks as well as implicit ones\n"
+ " such as 'gl_DefaultUniformBlock'.\n"
+ " --sbs synonym for set-block-storage\n"
+ " --set-atomic-counter-block name set\n"
+ " set name, and descriptor set for\n"
+ " atomic counter blocks, with -R opt\n"
+ " --sacb synonym for set-atomic-counter-block\n"
+ " --set-default-uniform-block name set binding\n"
+ " set name, descriptor set, and binding for\n"
+ " global default-uniform-block, with -R opt\n"
+ " --sdub synonym for set-default-uniform-block\n"
" --shift-image-binding [stage] num\n"
" base binding number for images (uav)\n"
" --shift-image-binding [stage] [num set]...\n"