SPV reflection: Add OpModuleProcessed for compile options.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index a167702..bda9922 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -880,11 +880,30 @@
spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
builder.clearAccessChain();
- builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
+ builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()),
+ glslangIntermediate->getVersion());
+
if (options.generateDebugInfo) {
- builder.setSourceFile(glslangIntermediate->getSourceFile());
- builder.setSourceText(glslangIntermediate->getSourceText());
builder.setEmitOpLines();
+ builder.setSourceFile(glslangIntermediate->getSourceFile());
+
+ // Set the source shader's text. If for SPV version 1.0, include
+ // a preamble in comments stating the OpModuleProcessed instructions.
+ // Otherwise, emit those as actual instructions.
+ 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) {
+ text.append("// OpModuleProcessed ");
+ text.append(processes[p]);
+ text.append("\n");
+ } else
+ builder.addModuleProcessed(processes[p]);
+ }
+ if (glslangIntermediate->getSpv().spv < 0x00010100 && (int)processes.size() > 0)
+ text.append("#line 1\n");
+ text.append(glslangIntermediate->getSourceText());
+ builder.setSourceText(text);
}
stdBuiltins = builder.import("GLSL.std.450");
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 9246a81..289d59a 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -2430,6 +2430,7 @@
// Debug instructions
dumpInstructions(out, strings);
+ dumpModuleProcesses(out);
dumpSourceInstructions(out);
for (int e = 0; e < (int)sourceExtensions.size(); ++e) {
Instruction sourceExtInst(0, 0, OpSourceExtension);
@@ -2637,4 +2638,15 @@
}
}
+void Builder::dumpModuleProcesses(std::vector<unsigned int>& out) const
+{
+ for (int i = 0; i < (int)moduleProcesses.size(); ++i) {
+ // TODO: switch this out for the 1.1 headers
+ const spv::Op OpModuleProcessed = (spv::Op)330;
+ Instruction moduleProcessed(OpModuleProcessed);
+ moduleProcessed.addStringOperand(moduleProcesses[i]);
+ moduleProcessed.dump(out);
+ }
+}
+
}; // end spv namespace
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 3a94919..59b1da2 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -79,6 +79,7 @@
}
void setSourceText(const std::string& text) { sourceText = text; }
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
+ void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
void setEmitOpLines() { emitOpLines = true; }
void addExtension(const char* ext) { extensions.insert(ext); }
Id import(const char*);
@@ -582,6 +583,7 @@
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void dumpSourceInstructions(std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
+ void dumpModuleProcesses(std::vector<unsigned int>&) const;
SourceLanguage source;
int sourceVersion;
@@ -591,6 +593,7 @@
bool emitOpLines;
std::set<std::string> extensions;
std::vector<const char*> sourceExtensions;
+ std::vector<const char*> moduleProcesses;
AddressingModel addressModel;
MemoryModel memoryModel;
std::set<spv::Capability> capabilities;
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 3301df4..53a33b8 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -152,6 +152,7 @@
int VulkanClientVersion = 100; // would map to, say, Vulkan 1.0
int OpenGLClientVersion = 450; // doesn't influence anything yet, but maps to OpenGL 4.50
unsigned int TargetVersion = 0x00001000; // maps to, say, SPIR-V 1.0
+std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
std::array<unsigned int, EShLangCount> baseSamplerBinding;
std::array<unsigned int, EShLangCount> baseTextureBinding;
@@ -175,6 +176,9 @@
text.append("#define ");
fixLine(def);
+ Processes.push_back("D");
+ Processes.back().append(def);
+
// The first "=" needs to turn into a space
const size_t equal = def.find_first_of("=");
if (equal != def.npos)
@@ -189,6 +193,10 @@
{
text.append("#undef ");
fixLine(undef);
+
+ Processes.push_back("U");
+ Processes.back().append(undef);
+
text.append(undef);
text.append("\n");
}
@@ -421,6 +429,8 @@
} else if (lowerword == "no-storage-format" || // synonyms
lowerword == "nsf") {
Options |= EOptionNoStorageFormat;
+ } else if (lowerword == "relaxed-errors") {
+ Options |= EOptionRelaxedErrors;
} else if (lowerword == "resource-set-bindings" || // synonyms
lowerword == "resource-set-binding" ||
lowerword == "rsb") {
@@ -459,6 +469,8 @@
sourceEntryPointName = argv[1];
bumpArg();
break;
+ } else if (lowerword == "suppress-warnings") {
+ Options |= EOptionSuppressWarnings;
} else if (lowerword == "target-env") {
if (argc > 1) {
if (strcmp(argv[1], "vulkan1.0") == 0) {
@@ -737,6 +749,7 @@
shader->setSourceEntryPoint(sourceEntryPointName);
if (UserPreamble.isSet())
shader->setPreamble(UserPreamble.get());
+ shader->addProcesses(Processes);
shader->setShiftSamplerBinding(baseSamplerBinding[compUnit.stage]);
shader->setShiftTextureBinding(baseTextureBinding[compUnit.stage]);
@@ -1162,11 +1175,11 @@
" -m memory leak mode\n"
" -o <file> save binary to <file>, requires a binary option (e.g., -V)\n"
" -q dump reflection query database\n"
- " -r relaxed semantic error-checking mode\n"
+ " -r synonym for --relaxed-errors\n"
" -s silent mode\n"
" -t multi-threaded mode\n"
" -v print version strings\n"
- " -w suppress warnings (except as required by #extension : warn)\n"
+ " -w synonym for --suppress-warnings\n"
" -x save binary output as text-based 32-bit hexadecimal numbers\n"
" --auto-map-bindings automatically bind uniform variables\n"
" without explicit bindings.\n"
@@ -1185,6 +1198,7 @@
" --ku synonym for --keep-uncalled\n"
" --no-storage-format use Unknown image format\n"
" --nsf synonym for --no-storage-format\n"
+ " --relaxed-errors relaxed GLSL semantic error-checking mode\n"
" --resource-set-binding [stage] name set binding\n"
" Set descriptor set and binding for individual resources\n"
" --resource-set-binding [stage] set\n"
@@ -1206,11 +1220,13 @@
" --source-entrypoint name the given shader source function is\n"
" renamed to be the entry point given in -e\n"
" --sep synonym for --source-entrypoint\n"
- " --target-env {vulkan1.0|opengl} set the execution environment the generated\n"
- " code will execute in (as opposed to language\n"
- " semantics selected by --client)\n"
- " default is 'vulkan1.0' under '--client vulkan'\n"
- " default is 'opengl' under '--client opengl'\n"
+ " --suppress-warnings suppress GLSL warnings\n"
+ " (except as required by #extension : warn)\n"
+ " --target-env {vulkan1.0|opengl} set the execution environment code will\n"
+ " execute in (as opposed to language\n"
+ " semantics selected by --client) defaults:\n"
+ " 'vulkan1.0' under '--client vulkan<ver>'\n"
+ " 'opengl' under '--client opengl<ver>'\n"
" --variable-name <name> Creates a C header file that contains a\n"
" uint32_t array named <name>\n"
" initialized with the shader binary code.\n"
diff --git a/Test/baseResults/spv.debugInfo.frag.out b/Test/baseResults/spv.debugInfo.frag.out
index f501528..2e0d1b3 100644
--- a/Test/baseResults/spv.debugInfo.frag.out
+++ b/Test/baseResults/spv.debugInfo.frag.out
@@ -7,9 +7,19 @@
2: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 5 "main" 24 52
- ExecutionMode 5 OriginUpperLeft
+ ExecutionMode 5 OriginLowerLeft
1: String "spv.debugInfo.frag"
- Source GLSL 450 1 "#version 450
+ Source GLSL 450 1 "// OpModuleProcessed no-storage-format
+// OpModuleProcessed resource-set-binding 3
+// OpModuleProcessed auto-map-locations
+// OpModuleProcessed client opengl100
+// OpModuleProcessed target-env opengl
+// OpModuleProcessed relaxed-errors
+// OpModuleProcessed suppress-warnings
+// OpModuleProcessed hlsl-offsets
+// OpModuleProcessed entry-point main
+#line 1
+#version 450
struct S {
int a;
@@ -84,8 +94,8 @@
MemberDecorate 53(S) 0 Offset 0
MemberDecorate 54(ubuf) 0 Offset 0
Decorate 54(ubuf) Block
- Decorate 56 DescriptorSet 0
- Decorate 69(s2d) DescriptorSet 0
+ Decorate 56 DescriptorSet 3
+ Decorate 69(s2d) DescriptorSet 3
3: TypeVoid
4: TypeFunction 3
7: TypeInt 32 1
diff --git a/Test/baseResults/spv.hlslDebugInfo.frag.out b/Test/baseResults/spv.hlslDebugInfo.frag.out
new file mode 100644
index 0000000..571e594
--- /dev/null
+++ b/Test/baseResults/spv.hlslDebugInfo.frag.out
@@ -0,0 +1,58 @@
+spv.hlslDebugInfo.vert
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 19
+
+ Capability Shader
+ 2: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Vertex 5 "newMain" 17
+ 1: String "spv.hlslDebugInfo.vert"
+ Source HLSL 500 1 "// OpModuleProcessed entry-point newMain
+// OpModuleProcessed shift-sampler-binding 2
+// OpModuleProcessed shift-texture-binding 4
+// OpModuleProcessed shift-image-binding 1
+// OpModuleProcessed shift-UBO-binding 6
+// OpModuleProcessed shift-ssbo-binding 3
+// OpModuleProcessed shift-uav-binding 5
+// OpModuleProcessed flatten-uniform-arrays
+// OpModuleProcessed no-storage-format
+// OpModuleProcessed resource-set-binding t0 0 0
+// OpModuleProcessed hlsl-iomap
+// OpModuleProcessed auto-map-bindings
+// OpModuleProcessed auto-map-locations
+// OpModuleProcessed client vulkan100
+// OpModuleProcessed target-env vulkan1.0
+// OpModuleProcessed source-entrypoint origMain
+// OpModuleProcessed hlsl-offsets
+#line 1
+float4 origMain() : SV_Position
+{
+ return (float4)0;
+}
+"
+ Name 5 "newMain"
+ Name 10 "@newMain("
+ Name 17 "@entryPointOutput"
+ Decorate 17(@entryPointOutput) BuiltIn Position
+ 3: TypeVoid
+ 4: TypeFunction 3
+ 7: TypeFloat 32
+ 8: TypeVector 7(float) 4
+ 9: TypeFunction 8(fvec4)
+ 12: 7(float) Constant 0
+ 13: 8(fvec4) ConstantComposite 12 12 12 12
+ 16: TypePointer Output 8(fvec4)
+17(@entryPointOutput): 16(ptr) Variable Output
+ 5(newMain): 3 Function None 4
+ 6: Label
+ Line 1 2 0
+ 18: 8(fvec4) FunctionCall 10(@newMain()
+ Store 17(@entryPointOutput) 18
+ Return
+ FunctionEnd
+ 10(@newMain(): 8(fvec4) Function None 9
+ 11: Label
+ Line 1 3 0
+ ReturnValue 13
+ FunctionEnd
diff --git a/Test/runtests b/Test/runtests
index c5a9337..98cd944 100755
--- a/Test/runtests
+++ b/Test/runtests
@@ -116,8 +116,12 @@
# Testing debug information
#
echo Testing SPV Debug Information
-$EXE -g -H spv.debugInfo.frag > $TARGETDIR/spv.debugInfo.frag.out
+$EXE -g --relaxed-errors --suppress-warnings --aml --hlsl-offsets --nsf \
+ -G -H spv.debugInfo.frag --rsb frag 3 > $TARGETDIR/spv.debugInfo.frag.out
diff -b $BASEDIR/spv.debugInfo.frag.out $TARGETDIR/spv.debugInfo.frag.out || HASERROR=1
+$EXE -g -D -e newMain -g --amb --aml --fua --hlsl-iomap --nsf --sib 1 --ssb 2 --sbb 3 --stb 4 --suavb 5 --sub 6 \
+ --sep origMain -H spv.hlslDebugInfo.vert --rsb vert t0 0 0 > $TARGETDIR/spv.hlslDebugInfo.frag.out
+diff -b $BASEDIR/spv.hlslDebugInfo.frag.out $TARGETDIR/spv.hlslDebugInfo.frag.out || HASERROR=1
#
# Testing Includer
diff --git a/Test/spv.hlslDebugInfo.vert b/Test/spv.hlslDebugInfo.vert
new file mode 100644
index 0000000..b2bc187
--- /dev/null
+++ b/Test/spv.hlslDebugInfo.vert
@@ -0,0 +1,4 @@
+float4 origMain() : SV_Position
+{
+ return (float4)0;
+}
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index d2964e4..2a904f4 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -675,6 +675,22 @@
}
}
+// Most processes are recorded when set in the intermediate representation,
+// These are the few that are not.
+void RecordProcesses(TIntermediate& intermediate, EShMessages messages, const std::string& sourceEntryPointName)
+{
+ if ((messages & EShMsgRelaxedErrors) != 0)
+ intermediate.addProcess("relaxed-errors");
+ if ((messages & EShMsgSuppressWarnings) != 0)
+ intermediate.addProcess("suppress-warnings");
+ if ((messages & EShMsgKeepUncalled) != 0)
+ intermediate.addProcess("keep-uncalled");
+ if (sourceEntryPointName.size() > 0) {
+ intermediate.addProcess("source-entrypoint");
+ intermediate.addProcessArgument(sourceEntryPointName);
+ }
+}
+
// This is the common setup and cleanup code for PreprocessDeferred and
// CompileDeferred.
// It takes any callable with a signature of
@@ -798,6 +814,7 @@
intermediate.setVersion(version);
intermediate.setProfile(profile);
intermediate.setSpv(spvVersion);
+ RecordProcesses(intermediate, messages, sourceEntryPointName);
if (spvVersion.vulkan >= 100)
intermediate.setOriginUpperLeft();
if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl)
@@ -1641,6 +1658,11 @@
sourceEntryPointName = name;
}
+void TShader::addProcesses(const std::vector<std::string>& p)
+{
+ intermediate->addProcesses(p);
+}
+
// Set binding base for sampler types
void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
// Set binding base for texture types (SRV)
@@ -1658,7 +1680,7 @@
// Enables binding automapping using TIoMapper
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
// Fragile: currently within one stage: simple auto-assignment of location
-void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
+void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index c1daf1b..d3219cc 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -150,6 +150,54 @@
bool containsDouble;
};
+// Track a set of strings describing how the module was processed.
+// Using the form:
+// process arg0 arg1 arg2 ...
+// process arg0 arg1 arg2 ...
+// where everything is textual, and there can be zero or more arguments
+class TProcesses {
+public:
+ TProcesses() {}
+ ~TProcesses() {}
+
+ void addProcess(const char* process)
+ {
+ processes.push_back(process);
+ }
+ void addProcess(const std::string& process)
+ {
+ processes.push_back(process);
+ }
+ void addArgument(int arg)
+ {
+ processes.back().append(" ");
+ std::string argString = std::to_string(arg);
+ processes.back().append(argString);
+ }
+ void addArgument(const char* arg)
+ {
+ processes.back().append(" ");
+ processes.back().append(arg);
+ }
+ void addArgument(const std::string& arg)
+ {
+ processes.back().append(" ");
+ processes.back().append(arg);
+ }
+ void addIfNonZero(const char* process, int value)
+ {
+ if (value != 0) {
+ addProcess(process);
+ addArgument(value);
+ }
+ }
+
+ const std::vector<std::string>& getProcesses() const { return processes; }
+
+private:
+ std::vector<std::string> processes;
+};
+
class TSymbolTable;
class TSymbol;
class TVariable;
@@ -201,46 +249,135 @@
void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; }
- void setEntryPointName(const char* ep) { entryPointName = ep; }
+ void setEntryPointName(const char* ep)
+ {
+ entryPointName = ep;
+ processes.addProcess("entry-point");
+ processes.addArgument(entryPointName);
+ }
void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
const std::string& getEntryPointName() const { return entryPointName; }
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
- void setShiftSamplerBinding(unsigned int shift) { shiftSamplerBinding = shift; }
+ void setShiftSamplerBinding(unsigned int shift)
+ {
+ shiftSamplerBinding = shift;
+ processes.addIfNonZero("shift-sampler-binding", shift);
+ }
unsigned int getShiftSamplerBinding() const { return shiftSamplerBinding; }
- void setShiftTextureBinding(unsigned int shift) { shiftTextureBinding = shift; }
+ void setShiftTextureBinding(unsigned int shift)
+ {
+ shiftTextureBinding = shift;
+ processes.addIfNonZero("shift-texture-binding", shift);
+ }
unsigned int getShiftTextureBinding() const { return shiftTextureBinding; }
- void setShiftImageBinding(unsigned int shift) { shiftImageBinding = shift; }
+ void setShiftImageBinding(unsigned int shift)
+ {
+ shiftImageBinding = shift;
+ processes.addIfNonZero("shift-image-binding", shift);
+ }
unsigned int getShiftImageBinding() const { return shiftImageBinding; }
- void setShiftUboBinding(unsigned int shift) { shiftUboBinding = shift; }
- unsigned int getShiftUboBinding() const { return shiftUboBinding; }
- void setShiftSsboBinding(unsigned int shift) { shiftSsboBinding = shift; }
- unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
- void setShiftUavBinding(unsigned int shift) { shiftUavBinding = shift; }
- unsigned int getShiftUavBinding() const { return shiftUavBinding; }
- void setResourceSetBinding(const std::vector<std::string>& shift) { resourceSetBinding = shift; }
+ void setShiftUboBinding(unsigned int shift)
+ {
+ shiftUboBinding = shift;
+ processes.addIfNonZero("shift-UBO-binding", shift);
+ }
+ unsigned int getShiftUboBinding() const { return shiftUboBinding; }
+ void setShiftSsboBinding(unsigned int shift)
+ {
+ shiftSsboBinding = shift;
+ processes.addIfNonZero("shift-ssbo-binding", shift);
+ }
+ unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
+ void setShiftUavBinding(unsigned int shift)
+ {
+ shiftUavBinding = shift;
+ processes.addIfNonZero("shift-uav-binding", shift);
+ }
+ unsigned int getShiftUavBinding() const { return shiftUavBinding; }
+ void setResourceSetBinding(const std::vector<std::string>& shift)
+ {
+ resourceSetBinding = shift;
+ if (shift.size() > 0) {
+ processes.addProcess("resource-set-binding");
+ for (int s = 0; s < (int)shift.size(); ++s)
+ processes.addArgument(shift[s]);
+ }
+ }
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
- void setAutoMapBindings(bool map) { autoMapBindings = map; }
- bool getAutoMapBindings() const { return autoMapBindings; }
- void setAutoMapLocations(bool map) { autoMapLocations = map; }
- bool getAutoMapLocations() const { return autoMapLocations; }
- void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
- bool getFlattenUniformArrays() const { return flattenUniformArrays; }
- void setNoStorageFormat(bool b) { useUnknownFormat = b; }
- bool getNoStorageFormat() const { return useUnknownFormat; }
- void setHlslOffsets() { hlslOffsets = true; }
+ void setAutoMapBindings(bool map)
+ {
+ autoMapBindings = map;
+ if (autoMapBindings)
+ processes.addProcess("auto-map-bindings");
+ }
+ bool getAutoMapBindings() const { return autoMapBindings; }
+ void setAutoMapLocations(bool map)
+ {
+ autoMapLocations = map;
+ if (autoMapLocations)
+ processes.addProcess("auto-map-locations");
+ }
+ bool getAutoMapLocations() const { return autoMapLocations; }
+ void setFlattenUniformArrays(bool flatten)
+ {
+ flattenUniformArrays = flatten;
+ if (flattenUniformArrays)
+ processes.addProcess("flatten-uniform-arrays");
+ }
+ bool getFlattenUniformArrays() const { return flattenUniformArrays; }
+ void setNoStorageFormat(bool b)
+ {
+ useUnknownFormat = b;
+ if (useUnknownFormat)
+ processes.addProcess("no-storage-format");
+ }
+ bool getNoStorageFormat() const { return useUnknownFormat; }
+ void setHlslOffsets()
+ {
+ hlslOffsets = true;
+ if (hlslOffsets)
+ processes.addProcess("hlsl-offsets");
+ }
bool usingHlslOFfsets() const { return hlslOffsets; }
- void setUseStorageBuffer() { useStorageBuffer = true; }
+ void setUseStorageBuffer()
+ {
+ useStorageBuffer = true;
+ processes.addProcess("use-storage-buffer");
+ }
bool usingStorageBuffer() const { return useStorageBuffer; }
- void setHlslIoMapping(bool b) { hlslIoMapping = b; }
- bool usingHlslIoMapping() { return hlslIoMapping; }
+ void setHlslIoMapping(bool b)
+ {
+ hlslIoMapping = b;
+ if (hlslIoMapping)
+ processes.addProcess("hlsl-iomap");
+ }
+ bool usingHlslIoMapping() { return hlslIoMapping; }
+
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
void setVersion(int v) { version = v; }
int getVersion() const { return version; }
void setProfile(EProfile p) { profile = p; }
EProfile getProfile() const { return profile; }
- void setSpv(const SpvVersion& s) { spvVersion = s; }
+ void setSpv(const SpvVersion& s)
+ {
+ spvVersion = s;
+
+ // client processes
+ if (spvVersion.vulkan > 0)
+ processes.addProcess("client vulkan100");
+ if (spvVersion.openGl > 0)
+ processes.addProcess("client opengl100");
+
+ // target-environment processes
+ if (spvVersion.vulkan == 100)
+ processes.addProcess("target-env vulkan1.0");
+ else if (spvVersion.vulkan > 0)
+ processes.addProcess("target-env vulkanUnknown");
+ if (spvVersion.openGl > 0)
+ processes.addProcess("target-env opengl");
+ }
const SpvVersion& getSpv() const { return spvVersion; }
EShLanguage getStage() const { return language; }
void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); }
@@ -462,6 +599,13 @@
const std::string& getSourceFile() const { return sourceFile; }
void addSourceText(const char* text) { sourceText = sourceText + text; }
const std::string& getSourceText() const { return sourceText; }
+ void addProcesses(const std::vector<std::string>& p) {
+ for (int i = 0; i < (int)p.size(); ++i)
+ processes.addProcess(p[i]);
+ }
+ void addProcess(const std::string& process) { processes.addProcess(process); }
+ void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
+ const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
const char* const implicitThisName = "@this";
@@ -558,6 +702,9 @@
std::string sourceFile;
std::string sourceText;
+ // for OpModuleProcessed, or equivalent
+ TProcesses processes;
+
private:
void operator=(TIntermediate&); // prevent assignments
};
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 12672ee..b968967 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -346,6 +346,7 @@
void setPreamble(const char* s) { preamble = s; }
void setEntryPoint(const char* entryPoint);
void setSourceEntryPoint(const char* sourceEntryPointName);
+ void addProcesses(const std::vector<std::string>&);
void setShiftSamplerBinding(unsigned int base);
void setShiftTextureBinding(unsigned int base);
void setShiftImageBinding(unsigned int base);