Merge pull request #622 from cdavis5e/new-spirv-cross

Update SPIRV-Cross.
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDebug.mm b/MoltenVK/MoltenVK/Commands/MVKCmdDebug.mm
index 45ee566..ae28ec3 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDebug.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDebug.mm
@@ -41,9 +41,14 @@
 #pragma mark MVKCmdDebugMarkerBegin
 
 // Vulkan debug groups are more general than Metal's.
-// Always push on command buffer instead of the encoder.
+// If a renderpass is active, push on the render command encoder, otherwise push on the command buffer.
 void MVKCmdDebugMarkerBegin::encode(MVKCommandEncoder* cmdEncoder) {
-	[cmdEncoder->_mtlCmdBuffer pushDebugGroup: _markerName];
+	id<MTLRenderCommandEncoder> mtlCmdEnc = cmdEncoder->_mtlRenderEncoder;
+	if (mtlCmdEnc) {
+		[mtlCmdEnc pushDebugGroup: _markerName];
+	} else {
+		[cmdEncoder->_mtlCmdBuffer pushDebugGroup: _markerName];
+	}
 }
 
 MVKCmdDebugMarkerBegin::MVKCmdDebugMarkerBegin(MVKCommandTypePool<MVKCmdDebugMarkerBegin>* pool)
@@ -54,9 +59,14 @@
 #pragma mark MVKCmdDebugMarkerEnd
 
 // Vulkan debug groups are more general than Metal's.
-// Always pop from command buffer instead of the encoder.
+// If a renderpass is active, pop from the render command encoder, otherwise pop from the command buffer.
 void MVKCmdDebugMarkerEnd::encode(MVKCommandEncoder* cmdEncoder) {
-	[cmdEncoder->_mtlCmdBuffer popDebugGroup];
+	id<MTLRenderCommandEncoder> mtlCmdEnc = cmdEncoder->_mtlRenderEncoder;
+	if (mtlCmdEnc) {
+		[mtlCmdEnc popDebugGroup];
+	} else {
+		[cmdEncoder->_mtlCmdBuffer popDebugGroup];
+	}
 }
 
 MVKCmdDebugMarkerEnd::MVKCmdDebugMarkerEnd(MVKCommandTypePool<MVKCmdDebugMarkerEnd>* pool)
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
index 3646abf..4d46a5b 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm
@@ -74,7 +74,7 @@
 
 void MVKCmdEndRenderPass::encode(MVKCommandEncoder* cmdEncoder) {
 //	MVKLogDebug("Encoding vkCmdEndRenderPass(). Elapsed time: %.6f ms.", mvkGetElapsedMilliseconds());
-	cmdEncoder->endMetalRenderEncoding();
+	cmdEncoder->endRenderpass();
 }
 
 MVKCmdEndRenderPass::MVKCmdEndRenderPass(MVKCommandTypePool<MVKCmdEndRenderPass>* pool)
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
index ba86b4b..2591f74 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
@@ -301,6 +301,9 @@
     /** Called by each compute dispatch command to establish any outstanding state just prior to performing the dispatch. */
     void finalizeDispatchState();
 
+	/** Ends the current renderpass. */
+	void endRenderpass();
+
 	/** 
 	 * Ends all encoding operations on the current Metal command encoder.
 	 *
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
index 7548626..7df3be2 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
@@ -332,7 +332,12 @@
 
 // Returns a name for use as a MTLRenderCommandEncoder label
 NSString* MVKCommandEncoder::getMTLRenderCommandEncoderName() {
-	NSString* rpName = _renderPass ? _renderPass->getDebugName() : nil;
+	NSString* rpName;
+
+	rpName = _renderPass->getDebugName();
+	if (rpName) { return rpName; }
+
+	rpName = _cmdBuffer->getDebugName();
 	if (rpName) { return rpName; }
 
 	MVKCommandUse cmdUse = (_renderSubpassIndex == 0) ? kMVKCommandUseBeginRenderPass : kMVKCommandUseNextSubpass;
@@ -418,6 +423,14 @@
     _computePushConstants.encode();
 }
 
+void MVKCommandEncoder::endRenderpass() {
+	endMetalRenderEncoding();
+
+	_renderPass = nullptr;
+	_framebuffer = nullptr;
+	_renderSubpassIndex = 0;
+}
+
 void MVKCommandEncoder::endMetalRenderEncoding() {
 //    MVKLogDebugIf(_mtlRenderEncoder, "Render subpass end MTLRenderCommandEncoder.");
     [_mtlRenderEncoder endEncoding];
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index c082c9f..21976c6 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -1281,6 +1281,7 @@
 
 	bool wasAdded = false;
 	MVKShaderLibraryCache* slCache = getShaderLibraryCache(shaderModule->getKey());
+	slCache->setShaderModule(shaderModule);
 	MVKShaderLibrary* shLib = slCache->getShaderLibrary(pContext, shaderModule, &wasAdded);
 	if (wasAdded) { markDirty(); }
 	return shLib;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
index d6fbbbe..b01add4 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
@@ -55,9 +55,6 @@
 	/** Returns the Vulkan API opaque object controlling this object. */
 	MVKVulkanAPIObject* getVulkanAPIObject() override { return _owner->getVulkanAPIObject(); };
 
-	/** Returns the Metal shader function, possibly specialized. */
-	MVKMTLFunction getMTLFunction(const VkSpecializationInfo* pSpecializationInfo);
-
 	/** Constructs an instance from the specified MSL source code. */
 	MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
 					 const std::string& mslSourceCode,
@@ -79,10 +76,14 @@
 	friend MVKShaderModule;
 
 	void propogateDebugName();
+	NSString* getDebugName();
+	void setShaderModule(MVKShaderModule* shaderModule);
+	MVKMTLFunction getMTLFunction(const VkSpecializationInfo* pSpecializationInfo);
 	void handleCompilationError(NSError* err, const char* opDesc);
     MTLFunctionConstant* getFunctionConstant(NSArray<MTLFunctionConstant*>* mtlFCs, NSUInteger mtlFCID);
 
 	MVKVulkanAPIDeviceObject* _owner;
+	MVKShaderModule* _shaderModule = nullptr;
 	id<MTLLibrary> _mtlLibrary;
 	SPIRVEntryPoint _entryPoint;
 	std::string _msl;
@@ -110,6 +111,11 @@
 	MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext,
 									   MVKShaderModule* shaderModule,
 									   bool* pWasAdded = nullptr);
+	/**
+	 * Sets the shader module associated with this library cache.
+	 * This is set after creation because libraries can be loaded from a pipeline cache.
+	 */
+	void setShaderModule(MVKShaderModule* shaderModule);
 
 	MVKShaderLibraryCache(MVKVulkanAPIDeviceObject* owner) : _owner(owner) {};
 
@@ -128,6 +134,7 @@
 	void merge(MVKShaderLibraryCache* other);
 
 	MVKVulkanAPIDeviceObject* _owner;
+	MVKShaderModule* _shaderModule = nullptr;
 	std::vector<std::pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>> _shaderLibraries;
 };
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
index 94f366f..974a29d 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm
@@ -31,7 +31,15 @@
 #pragma mark -
 #pragma mark MVKShaderLibrary
 
-void MVKShaderLibrary::propogateDebugName() { setLabelIfNotNil(_mtlLibrary, _owner->getDebugName()); }
+void MVKShaderLibrary::propogateDebugName() { setLabelIfNotNil(_mtlLibrary, getDebugName()); }
+
+// First choice is to name after shader module if it exists, otherwise name after owner.
+NSString* MVKShaderLibrary::getDebugName() {
+	NSString* dbName = _shaderModule ? _shaderModule-> getDebugName() : nil;
+	if (dbName) { return dbName; }
+
+	return _owner ? _owner-> getDebugName() : nil;
+}
 
 // If the size of the workgroup dimension is specialized, extract it from the
 // specialization info, otherwise use the value specified in the SPIR-V shader code.
@@ -89,11 +97,12 @@
 				fs->destroy();
             }
         }
-		setLabelIfNotNil(mtlFunc, _owner->getDebugName());
     } else {
         reportError(VK_ERROR_INVALID_SHADER_NV, "Shader module does not contain an entry point named '%s'.", mtlFuncName.UTF8String);
     }
 
+	setLabelIfNotNil(mtlFunc, getDebugName());
+
 	return { mtlFunc, MTLSizeMake(getWorkgroupDimensionSize(_entryPoint.workgroupSize.width, pSpecializationInfo),
 								  getWorkgroupDimensionSize(_entryPoint.workgroupSize.height, pSpecializationInfo),
 								  getWorkgroupDimensionSize(_entryPoint.workgroupSize.depth, pSpecializationInfo)) };
@@ -107,6 +116,13 @@
     return nil;
 }
 
+void MVKShaderLibrary::setShaderModule(MVKShaderModule* shaderModule) {
+	if (shaderModule == _shaderModule) { return; }
+
+	_shaderModule = shaderModule;
+	propogateDebugName();
+}
+
 MVKShaderLibrary::MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner, const string& mslSourceCode, const SPIRVEntryPoint& entryPoint) : _owner(owner) {
 	MVKShaderLibraryCompiler* slc = new MVKShaderLibraryCompiler(_owner);
 	_mtlLibrary = slc->newMTLLibrary(@(mslSourceCode.c_str()));	// retained
@@ -140,6 +156,7 @@
 	_mtlLibrary = [other._mtlLibrary retain];
 	_entryPoint = other._entryPoint;
 	_msl = other._msl;
+	setShaderModule(other._shaderModule);
 }
 
 // If err object is nil, the compilation succeeded without any warnings.
@@ -204,6 +221,7 @@
 														  const string& mslSourceCode,
 														  const SPIRVEntryPoint& entryPoint) {
 	MVKShaderLibrary* shLib = new MVKShaderLibrary(_owner, mslSourceCode, entryPoint);
+	shLib->setShaderModule(_shaderModule);
 	_shaderLibraries.emplace_back(*pContext, shLib);
 	return shLib;
 }
@@ -218,6 +236,13 @@
 	}
 }
 
+void MVKShaderLibraryCache::setShaderModule(MVKShaderModule* shaderModule) {
+	if (shaderModule == _shaderModule) { return; }
+
+	_shaderModule = shaderModule;
+	for (auto& slPair : _shaderLibraries) { slPair.second->setShaderModule(_shaderModule); }
+}
+
 MVKShaderLibraryCache::~MVKShaderLibraryCache() {
 	for (auto& slPair : _shaderLibraries) { slPair.second->destroy(); }
 }
@@ -310,6 +335,7 @@
 								 const VkShaderModuleCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device), _shaderLibraryCache(this) {
 
 	_defaultLibrary = nullptr;
+	_shaderLibraryCache.setShaderModule(this);
 
 
 	size_t codeSize = pCreateInfo->codeSize;
@@ -348,6 +374,7 @@
 
 			_spvConverter.setMSL(pMSLCode, nullptr);
 			_defaultLibrary = new MVKShaderLibrary(this, _spvConverter.getMSL().c_str(), _spvConverter.getEntryPoint());
+			_defaultLibrary->setShaderModule(this);
 
 			break;
 		}
@@ -362,6 +389,7 @@
 			_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.hashShaderCode, startTime);
 
 			_defaultLibrary = new MVKShaderLibrary(this, (void*)(pMSLCode), mslCodeLen);
+			_defaultLibrary->setShaderModule(this);
 
 			break;
 		}