Fix crash in vkDestroyPipelineLayout().

MVKPipelineLayout hold retained/released pointers to MVKDescriptorSetLayout,
instead of copies of MVKDescriptorSetLayout instances.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index ab8f920..3cdd3fb 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -24,6 +24,7 @@
 - Revert to supporting host-coherent memory for linear images on macOS.
 - Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle.
 - Fix crash when `VkDeviceCreateInfo` specifies queue families out of numerical order.
+- Fix crash in `vkDestroyPipelineLayout()`.
 - Remove error logging on `VK_TIMEOUT` of `VkSemaphore` and `VkFence`.
 - Consolidate the various linkable objects into a `MVKLinkableMixin` template base class.
 - Use `MVKVector` whenever possible in MoltenVK, especially within render loop.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
index 30d48c2..020af29 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
@@ -102,10 +102,12 @@
 	/** Constructs an instance for the specified device. */
 	MVKPipelineLayout(MVKDevice* device, const VkPipelineLayoutCreateInfo* pCreateInfo);
 
+	~MVKPipelineLayout() override;
+
 protected:
 	void propogateDebugName() override {}
 
-	MVKVectorInline<MVKDescriptorSetLayout, 8> _descriptorSetLayouts;
+	MVKVectorInline<MVKDescriptorSetLayout*, 8> _descriptorSetLayouts;
 	MVKVectorInline<MVKShaderResourceBinding, 8> _dslMTLResourceIndexOffsets;
 	MVKVectorInline<VkPushConstantRange, 8> _pushConstants;
 	MVKShaderResourceBinding _pushConstantsMTLResourceIndexes;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index 265d922..1d1ae2d 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -47,11 +47,11 @@
 	for (uint32_t dsIdx = 0; dsIdx < dsCnt; dsIdx++) {
 		MVKDescriptorSet* descSet = descriptorSets[dsIdx];
 		uint32_t dslIdx = firstSet + dsIdx;
-		auto& dsl = _descriptorSetLayouts[dslIdx];
-		dsl.bindDescriptorSet(cmdEncoder, descSet,
-							  _dslMTLResourceIndexOffsets[dslIdx],
-							  dynamicOffsets, &pDynamicOffsetIndex);
-		setConfigurationResult(dsl.getConfigurationResult());
+		MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[dslIdx];
+		dsl->bindDescriptorSet(cmdEncoder, descSet,
+							   _dslMTLResourceIndexOffsets[dslIdx],
+							   dynamicOffsets, &pDynamicOffsetIndex);
+		setConfigurationResult(dsl->getConfigurationResult());
 	}
 }
 
@@ -60,9 +60,9 @@
                                           MVKVector<VkWriteDescriptorSet>& descriptorWrites,
                                           uint32_t set) {
 	clearConfigurationResult();
-	auto& dsl = _descriptorSetLayouts[set];
-	dsl.pushDescriptorSet(cmdEncoder, descriptorWrites, _dslMTLResourceIndexOffsets[set]);
-	setConfigurationResult(dsl.getConfigurationResult());
+	MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[set];
+	dsl->pushDescriptorSet(cmdEncoder, descriptorWrites, _dslMTLResourceIndexOffsets[set]);
+	setConfigurationResult(dsl->getConfigurationResult());
 }
 
 // A null cmdEncoder can be passed to perform a validation pass
@@ -71,9 +71,9 @@
                                           uint32_t set,
                                           const void* pData) {
 	clearConfigurationResult();
-	auto& dsl = _descriptorSetLayouts[set];
-	dsl.pushDescriptorSet(cmdEncoder, descUpdateTemplate, pData, _dslMTLResourceIndexOffsets[set]);
-	setConfigurationResult(dsl.getConfigurationResult());
+	MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[set];
+	dsl->pushDescriptorSet(cmdEncoder, descUpdateTemplate, pData, _dslMTLResourceIndexOffsets[set]);
+	setConfigurationResult(dsl->getConfigurationResult());
 }
 
 void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConversionConfiguration& context) {
@@ -82,9 +82,9 @@
     // Add resource bindings defined in the descriptor set layouts
 	uint32_t dslCnt = (uint32_t)_descriptorSetLayouts.size();
 	for (uint32_t dslIdx = 0; dslIdx < dslCnt; dslIdx++) {
-        _descriptorSetLayouts[dslIdx].populateShaderConverterContext(context,
-                                                                     _dslMTLResourceIndexOffsets[dslIdx],
-                                                                     dslIdx);
+		_descriptorSetLayouts[dslIdx]->populateShaderConverterContext(context,
+																	  _dslMTLResourceIndexOffsets[dslIdx],
+																	  dslIdx);
 	}
 
 	// Add any resource bindings used by push-constants
@@ -113,16 +113,16 @@
     // with each DSL as it is added. The final accumulation of resource index offsets
     // becomes the resource index offsets that will be used for push contants.
 
-    // According to the Vulkan spec, VkDescriptorSetLayout is intended to be consumed when
-    // passed to any Vulkan function, and may be safely destroyed by app immediately after.
-    // In order for this pipeline layout to retain the content of a VkDescriptorSetLayout,
-    // this pipeline holds onto copies of the MVKDescriptorSetLayout instances, so that the
-    // originals created by the app can be safely destroyed.
+    // According to the Vulkan spec, VkDescriptorSetLayout is intended to be consumed when passed
+	// to any Vulkan function, and may be safely destroyed by app immediately after. In order for
+	// this pipeline layout to retain the VkDescriptorSetLayout, the MVKDescriptorSetLayout
+	// instance is retained, so that it will live on here after it has been destroyed by the API.
 
 	_descriptorSetLayouts.reserve(pCreateInfo->setLayoutCount);
 	for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) {
 		MVKDescriptorSetLayout* pDescSetLayout = (MVKDescriptorSetLayout*)pCreateInfo->pSetLayouts[i];
-		_descriptorSetLayouts.push_back(*pDescSetLayout);
+		pDescSetLayout->retain();
+		_descriptorSetLayouts.push_back(pDescSetLayout);
 		_dslMTLResourceIndexOffsets.push_back(_pushConstantsMTLResourceIndexes);
 		_pushConstantsMTLResourceIndexes += pDescSetLayout->_mtlResourceCounts;
 	}
@@ -150,6 +150,10 @@
 	}
 }
 
+MVKPipelineLayout::~MVKPipelineLayout() {
+	for (auto dsl : _descriptorSetLayouts) { dsl->release(); }
+}
+
 
 #pragma mark -
 #pragma mark MVKPipeline