Merge pull request #525 from billhollings/master

Update to latest SPIRV-Cross version.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index babb789..59a3e04 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -18,11 +18,25 @@
 
 Released TBD
 
+- Add support for tessellation.
 - Allow zero offset and stride combo in VkVertexInputBindingDescription.
 - Fix potential memory leak on synchronous command buffer submission.
 - Increase shader float constant accuracy beyond 6 digits of precision.
 - MoltenVKShaderConverterTool support cs & csh for compute shader file extensions.
 - `fetchDependencies`: Stop on first error.
+- Fix a possible race condition around MVKMTLBufferAllocation.
+- Fix memory overrun if no vertex buffer found with same binding as a vertex attribute.
+- Update to latest SPIRV-Cross version:
+	- MSL: Add support for Metal 2 indirect argument buffers.
+	- MSL: Add support for tessellation control & evaluation shaders.
+	- MSL: Force unnamed array builtin attributes to have a name.
+	- MSL: Set location of builtins based on client input.
+	- MSL: Ignore duplicate builtin vertex attributes.
+	- Add stable C API and ABI.
+	- Fix case where a struct is loaded which contains a row-major matrix.
+	- Ensure locale handling is safe for multi-threading.
+	- Add support for sanitizing address and threads.
+	- Deal more flexibly with for-loop & while-loop variations.
 
 
 
diff --git a/ExternalRevisions/SPIRV-Cross_repo_revision b/ExternalRevisions/SPIRV-Cross_repo_revision
index 89a5efd..bd8a8a6 100644
--- a/ExternalRevisions/SPIRV-Cross_repo_revision
+++ b/ExternalRevisions/SPIRV-Cross_repo_revision
@@ -1 +1 @@
-6f50806698c2de18ba32ef4bbd953ad761a00cf2
+ed55e0ac6d797a338e7c19dad785237f0efc4d86
diff --git a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
index 16c80c5..4232935 100644
--- a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
+++ b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
@@ -104,6 +104,12 @@
     return true;
 }
 
+MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverterContext::stageSupportsVertexAttributes() const {
+	return (options.entryPointStage == spv::ExecutionModelVertex ||
+			options.entryPointStage == spv::ExecutionModelTessellationControl ||
+			options.entryPointStage == spv::ExecutionModelTessellationEvaluation);
+}
+
 // Check them all in case inactive VA's duplicate locations used by active VA's.
 MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverterContext::isVertexAttributeLocationUsed(uint32_t location) const {
     for (auto& va : vertexAttributes) {
@@ -122,7 +128,7 @@
 
 MVK_PUBLIC_SYMBOL void SPIRVToMSLConverterContext::markAllAttributesAndResourcesUsed() {
 
-	if (options.entryPointStage == spv::ExecutionModelVertex) {
+	if (stageSupportsVertexAttributes()) {
 		for (auto& va : vertexAttributes) { va.isUsedByShader = true; }
 	}
 
@@ -133,7 +139,7 @@
 
     if ( !options.matches(other.options) ) { return false; }
 
-	if (options.entryPointStage == spv::ExecutionModelVertex) {
+	if (stageSupportsVertexAttributes()) {
 		for (const auto& va : vertexAttributes) {
 			if (va.isUsedByShader && !contains(other.vertexAttributes, va)) { return false; }
 		}
@@ -154,9 +160,7 @@
 	options.needsPatchOutputBuffer = srcContext.options.needsPatchOutputBuffer;
 	options.needsInputThreadgroupMem = srcContext.options.needsInputThreadgroupMem;
 
-	if (options.entryPointStage == spv::ExecutionModelVertex ||
-		options.entryPointStage == spv::ExecutionModelTessellationControl ||
-		options.entryPointStage == spv::ExecutionModelTessellationEvaluation) {
+	if (stageSupportsVertexAttributes()) {
 		for (auto& va : vertexAttributes) {
 			va.isUsedByShader = false;
 			for (auto& srcVA : srcContext.vertexAttributes) {
@@ -202,45 +206,6 @@
 
 	if (shouldLogSPIRV) { logSPIRV("Converting"); }
 
-	// Add vertex attributes
-	vector<spirv_cross::MSLVertexAttr> vtxAttrs;
-	spirv_cross::MSLVertexAttr va;
-	for (auto& ctxVA : context.vertexAttributes) {
-		va.location = ctxVA.location;
-        va.msl_buffer = ctxVA.mslBuffer;
-        va.msl_offset = ctxVA.mslOffset;
-        va.msl_stride = ctxVA.mslStride;
-        va.per_instance = ctxVA.isPerInstance;
-        switch (ctxVA.format) {
-        case MSLVertexFormat::Other:
-            va.format = spirv_cross::MSL_VERTEX_FORMAT_OTHER;
-            break;
-        case MSLVertexFormat::UInt8:
-            va.format = spirv_cross::MSL_VERTEX_FORMAT_UINT8;
-            break;
-        case MSLVertexFormat::UInt16:
-            va.format = spirv_cross::MSL_VERTEX_FORMAT_UINT16;
-            break;
-        }
-		va.builtin = ctxVA.builtin;
-        va.used_by_shader = ctxVA.isUsedByShader;
-		vtxAttrs.push_back(va);
-	}
-
-	// Add resource bindings
-	vector<spirv_cross::MSLResourceBinding> resBindings;
-	spirv_cross::MSLResourceBinding rb;
-	for (auto& ctxRB : context.resourceBindings) {
-		rb.desc_set = ctxRB.descriptorSet;
-		rb.binding = ctxRB.binding;
-		rb.stage = ctxRB.stage;
-		rb.msl_buffer = ctxRB.mslBuffer;
-		rb.msl_texture = ctxRB.mslTexture;
-		rb.msl_sampler = ctxRB.mslSampler;
-        rb.used_by_shader = ctxRB.isUsedByShader;
-		resBindings.push_back(rb);
-	}
-
 	spirv_cross::CompilerMSL* pMSLCompiler = nullptr;
 
 #ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
@@ -294,7 +259,43 @@
 		scOpts.vertex.flip_vert_y = context.options.shouldFlipVertexY;
 		pMSLCompiler->set_common_options(scOpts);
 
-		_msl = pMSLCompiler->compile(&vtxAttrs, &resBindings);
+		// Add vertex attributes
+		if (context.stageSupportsVertexAttributes()) {
+			spirv_cross::MSLVertexAttr va;
+			for (auto& ctxVA : context.vertexAttributes) {
+				va.location = ctxVA.location;
+				va.msl_buffer = ctxVA.mslBuffer;
+				va.msl_offset = ctxVA.mslOffset;
+				va.msl_stride = ctxVA.mslStride;
+				va.per_instance = ctxVA.isPerInstance;
+				switch (ctxVA.format) {
+					case MSLVertexFormat::Other:
+						va.format = spirv_cross::MSL_VERTEX_FORMAT_OTHER;
+						break;
+					case MSLVertexFormat::UInt8:
+						va.format = spirv_cross::MSL_VERTEX_FORMAT_UINT8;
+						break;
+					case MSLVertexFormat::UInt16:
+						va.format = spirv_cross::MSL_VERTEX_FORMAT_UINT16;
+						break;
+				}
+				pMSLCompiler->add_msl_vertex_attribute(va);
+			}
+		}
+
+		// Add resource bindings
+		spirv_cross::MSLResourceBinding rb;
+		for (auto& ctxRB : context.resourceBindings) {
+			rb.desc_set = ctxRB.descriptorSet;
+			rb.binding = ctxRB.binding;
+			rb.stage = ctxRB.stage;
+			rb.msl_buffer = ctxRB.mslBuffer;
+			rb.msl_texture = ctxRB.mslTexture;
+			rb.msl_sampler = ctxRB.mslSampler;
+			pMSLCompiler->add_msl_resource_binding(rb);
+		}
+
+		_msl = pMSLCompiler->compile();
 
         if (shouldLogMSL) { logSource(_msl, "MSL", "Converted"); }
 
@@ -310,25 +311,26 @@
 	}
 #endif
 
-    // Populate content extracted from the SPRI-V compiler.
+	// Populate the shader context with info from the compilation run, including
+	// which vertex attributes and resource bindings are used by the shader
 	populateEntryPoint(_entryPoint, pMSLCompiler, context.options);
 	context.options.isRasterizationDisabled = pMSLCompiler && pMSLCompiler->get_is_rasterization_disabled();
 	context.options.needsAuxBuffer = pMSLCompiler && pMSLCompiler->needs_aux_buffer();
 	context.options.needsOutputBuffer = pMSLCompiler && pMSLCompiler->needs_output_buffer();
 	context.options.needsPatchOutputBuffer = pMSLCompiler && pMSLCompiler->needs_patch_output_buffer();
 	context.options.needsInputThreadgroupMem = pMSLCompiler && pMSLCompiler->needs_input_threadgroup_mem();
-	delete pMSLCompiler;
 
-	// Copy whether the vertex attributes and resource bindings are used by the shader
-	uint32_t vaCnt = (uint32_t)vtxAttrs.size();
-	for (uint32_t vaIdx = 0; vaIdx < vaCnt; vaIdx++) {
-		context.vertexAttributes[vaIdx].isUsedByShader = vtxAttrs[vaIdx].used_by_shader;
+	if (context.stageSupportsVertexAttributes()) {
+		for (auto& ctxVA : context.vertexAttributes) {
+			ctxVA.isUsedByShader = pMSLCompiler->is_msl_vertex_attribute_used(ctxVA.location);
+		}
 	}
-	uint32_t rbCnt = (uint32_t)resBindings.size();
-	for (uint32_t rbIdx = 0; rbIdx < rbCnt; rbIdx++) {
-		context.resourceBindings[rbIdx].isUsedByShader = resBindings[rbIdx].used_by_shader;
+	for (auto& ctxRB : context.resourceBindings) {
+		ctxRB.isUsedByShader = pMSLCompiler->is_msl_resource_binding_used(ctxRB.stage, ctxRB.descriptorSet, ctxRB.binding);
 	}
 
+	delete pMSLCompiler;
+
     // To check GLSL conversion
     if (shouldLogGLSL) {
 		spirv_cross::CompilerGLSL* pGLSLCompiler = nullptr;
diff --git a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h
index 4cf7cb3..3f8800b 100644
--- a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h
+++ b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h
@@ -150,6 +150,9 @@
 		std::vector<MSLVertexAttribute> vertexAttributes;
 		std::vector<MSLResourceBinding> resourceBindings;
 
+		/** Returns whether the pipeline stage being converted supports vertex attributes. */
+		bool stageSupportsVertexAttributes() const;
+
         /** Returns whether the vertex attribute at the specified location is used by the shader. */
         bool isVertexAttributeLocationUsed(uint32_t location) const;