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;