Add linking separate shader texts to GLSLToSPRIVConverter
diff --git a/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.cpp b/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.cpp
index c01d647..a73491d 100644
--- a/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.cpp
+++ b/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.cpp
@@ -37,6 +37,23 @@
/** Returns the GLSL compiler language type corresponding to the specified MoltenVK shader stage. */
EShLanguage eshLanguageFromMVKGLSLConversionShaderStage(const MVKGLSLConversionShaderStage mvkShaderStage);
+MVK_PUBLIC_SYMBOL void GLSLToSPIRVConverter::setGLSL(const std::string& glslSrc) {
+ _glsls.clear();
+ if (glslSrc.size())
+ _glsls.push_back(glslSrc);
+}
+
+MVK_PUBLIC_SYMBOL void GLSLToSPIRVConverter::setGLSL(const char* glslSrc, size_t length) {
+ _glsls.clear();
+ if (length > 0)
+ _glsls.push_back(std::string(glslSrc, length));
+}
+
+MVK_PUBLIC_SYMBOL void GLSLToSPIRVConverter::setGLSLs(const std::vector<std::string>& glslSrcs) {
+ _glsls.clear();
+ _glsls = glslSrcs;
+}
+
MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::convert(MVKGLSLConversionShaderStage shaderStage,
bool shouldLogGLSL,
bool shouldLogSPIRV) {
@@ -51,26 +68,31 @@
EShLanguage stage = eshLanguageFromMVKGLSLConversionShaderStage(shaderStage);
TBuiltInResource glslCompilerResources;
configureGLSLCompilerResources(&glslCompilerResources);
+ std::vector<std::unique_ptr<glslang::TShader>> glslShaders;
const char *glslStrings[1];
- glslStrings[0] = _glsl.data();
+ glslang::TProgram glslProgram;
+
+ for (const auto& glsl : _glsls) {
+ glslStrings[0] = glsl.data();
- // Create and compile a shader from the source code
- glslang::TShader glslShader(stage);
- glslShader.setStrings(glslStrings, 1);
- if (glslShader.parse(&glslCompilerResources, 100, false, messages)) {
- if (shouldLogGLSL) {
- logMsg(glslShader.getInfoLog());
- logMsg(glslShader.getInfoDebugLog());
+ // Create and compile a shader from the source code
+ glslShaders.emplace_back(new glslang::TShader(stage));
+ glslShaders.back()->setStrings(glslStrings, 1);
+ if (glslShaders.back()->parse(&glslCompilerResources, 100, false, messages)) {
+ if (shouldLogGLSL) {
+ logMsg(glslShaders.back()->getInfoLog());
+ logMsg(glslShaders.back()->getInfoDebugLog());
+ }
+ } else {
+ logError(glslShaders.back()->getInfoLog());
+ logError(glslShaders.back()->getInfoDebugLog());
+ return logError("Error compiling GLSL when converting GLSL to SPIR-V.");
}
- } else {
- logError(glslShader.getInfoLog());
- logError(glslShader.getInfoDebugLog());
- return logError("Error compiling GLSL when converting GLSL to SPIR-V.");
+ // Add a shader to the program. Each shader added will be linked together.
+ glslProgram.addShader(glslShaders.back().get());
}
- // Create and link a shader program containing the single shader
- glslang::TProgram glslProgram;
- glslProgram.addShader(&glslShader);
+ // Create and link a shader program
if ( !glslProgram.link(messages) ) {
logError(glslProgram.getInfoLog());
logError(glslProgram.getInfoDebugLog());
@@ -125,8 +147,8 @@
void GLSLToSPIRVConverter::logGLSL(const char* opDesc) {
_resultLog += opDesc;
_resultLog += " GLSL:\n";
- _resultLog += _glsl;
- _resultLog += "\nEnd GLSL\n\n";
+ for (const auto& glsl : _glsls) _resultLog += glsl + "\n";
+ _resultLog += "End GLSL\n\n";
}
diff --git a/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h b/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h
index 2bc433f..7b13650 100644
--- a/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h
+++ b/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h
@@ -36,19 +36,30 @@
public:
/** Sets the GLSL source code that is to be converted to the specified string. */
- void setGLSL(const std::string& glslSrc) { _glsl = glslSrc; }
+ void setGLSL(const std::string& glslSrc);
/**
* Sets the GLSL source code that is to be converted from the first length characters
* of the buffer, and ensuring the resulting string is null-terminated.
*/
- void setGLSL(const char* glslSrc, size_t length) { _glsl.assign(glslSrc, length); }
+ void setGLSL(const char* glslSrc, size_t length);
/** Returns the GLSL source code that was set using the setGLSL() function. */
- const std::string& getGLSL() { return _glsl; }
+ const std::string& getGLSL() { return _glsls.front(); }
+
+ /**
+ * Sets the GLSL source code that is to be converted to the specified strings.
+ *
+ * A separate shader will be compiled for each source and linked together into a single
+ * program.
+ */
+ void setGLSLs(const std::vector<std::string>& glslSrcs);
+
+ /** Returns the GLSL source code that was set using the setGLSLs() function. */
+ const std::vector<std::string>& getGLSLs() { return _glsls; }
/** Returns whether the SPIR-V code has been set. */
- bool hasGLSL() { return !_glsl.empty(); }
+ bool hasGLSL() { return !_glsls.empty(); }
/**
* Converts GLSL code, set with setGLSL(), to SPIR-V code, which can be retrieved using getSPIRV().
@@ -82,7 +93,7 @@
bool validateSPIRV();
void initGLSLCompilerResources();
- std::string _glsl;
+ std::vector<std::string> _glsls;
std::vector<uint32_t> _spirv;
std::string _resultLog;
bool _wasConverted = false;