Merge pull request #1031 from cdavis5e/retain-descriptor-sets

MVKCmdBindDescriptorSets: Retain given objects.
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
index b2985ee..98616cb 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
@@ -139,11 +139,13 @@
 
 	void encode(MVKCommandEncoder* cmdEncoder) override;
 
+	~MVKCmdBindDescriptorSetsStatic() override;
+
 protected:
 	MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
 
 	MVKSmallVector<MVKDescriptorSet*, N> _descriptorSets;
-	MVKPipelineLayout* _pipelineLayout;
+	MVKPipelineLayout* _pipelineLayout = nullptr;
 	VkPipelineBindPoint _pipelineBindPoint;
 	uint32_t _firstSet;
 };
@@ -211,7 +213,6 @@
 	MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
 
 	MVKSmallVector<char, N> _pushConstants;
-	MVKPipelineLayout* _pipelineLayout;
 	VkShaderStageFlags _stageFlags;
 	uint32_t _offset;
 };
@@ -245,7 +246,7 @@
 	void clearDescriptorWrites();
 
 	MVKSmallVector<VkWriteDescriptorSet, 1> _descriptorWrites;
-	MVKPipelineLayout* _pipelineLayout;
+	MVKPipelineLayout* _pipelineLayout = nullptr;
 	VkPipelineBindPoint _pipelineBindPoint;
 	uint32_t _set;
 };
@@ -272,7 +273,7 @@
 	MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
 
 	MVKDescriptorUpdateTemplate* _descUpdateTemplate;
-	MVKPipelineLayout* _pipelineLayout;
+	MVKPipelineLayout* _pipelineLayout = nullptr;
 	void* _pData = nullptr;
 	uint32_t _set;
 };
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
index 4e12de5..00029a6 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
@@ -193,10 +193,14 @@
 													   uint32_t firstSet,
 													   uint32_t setCount,
 													   const VkDescriptorSet* pDescriptorSets) {
+	if (_pipelineLayout) { _pipelineLayout->release(); }
+
 	_pipelineBindPoint = pipelineBindPoint;
 	_pipelineLayout = (MVKPipelineLayout*)layout;
 	_firstSet = firstSet;
 
+	_pipelineLayout->retain();
+
 	// Add the descriptor sets
 	_descriptorSets.clear();	// Clear for reuse
 	_descriptorSets.reserve(setCount);
@@ -212,6 +216,11 @@
 	_pipelineLayout->bindDescriptorSets(cmdEncoder, _descriptorSets.contents(), _firstSet, MVKArrayRef<uint32_t>());
 }
 
+template <size_t N>
+MVKCmdBindDescriptorSetsStatic<N>::~MVKCmdBindDescriptorSetsStatic() {
+	if (_pipelineLayout) { _pipelineLayout->release(); }
+}
+
 template class MVKCmdBindDescriptorSetsStatic<1>;
 template class MVKCmdBindDescriptorSetsStatic<4>;
 template class MVKCmdBindDescriptorSetsStatic<8>;
@@ -262,7 +271,6 @@
 											uint32_t offset,
 											uint32_t size,
 											const void* pValues) {
-	_pipelineLayout = (MVKPipelineLayout*)layout;
 	_stageFlags = stageFlags;
 	_offset = offset;
 
@@ -302,10 +310,14 @@
 											 uint32_t set,
 											 uint32_t descriptorWriteCount,
 											 const VkWriteDescriptorSet* pDescriptorWrites) {
+	if (_pipelineLayout) { _pipelineLayout->release(); }
+
 	_pipelineBindPoint = pipelineBindPoint;
 	_pipelineLayout = (MVKPipelineLayout*)layout;
 	_set = set;
 
+	_pipelineLayout->retain();
+
 	// Add the descriptor writes
 	MVKDevice* mvkDvc = cmdBuff->getDevice();
 	clearDescriptorWrites();	// Clear for reuse
@@ -360,6 +372,7 @@
 
 MVKCmdPushDescriptorSet::~MVKCmdPushDescriptorSet() {
 	clearDescriptorWrites();
+	if (_pipelineLayout) { _pipelineLayout->release(); }
 }
 
 void MVKCmdPushDescriptorSet::clearDescriptorWrites() {
@@ -393,9 +406,14 @@
 														 VkPipelineLayout layout,
 														 uint32_t set,
 														 const void* pData) {
+	if (_pipelineLayout) { _pipelineLayout->release(); }
+
 	_descUpdateTemplate = (MVKDescriptorUpdateTemplate*)descUpdateTemplate;
 	_pipelineLayout = (MVKPipelineLayout*)layout;
 	_set = set;
+
+	_pipelineLayout->retain();
+
 	if (_pData) delete[] (char*)_pData;
 	// Work out how big the memory block in pData is.
 	const VkDescriptorUpdateTemplateEntryKHR* pEntry =
@@ -443,6 +461,7 @@
 }
 
 MVKCmdPushDescriptorSetWithTemplate::~MVKCmdPushDescriptorSetWithTemplate() {
+	if (_pipelineLayout) { _pipelineLayout->release(); }
 	if (_pData) delete[] (char*)_pData;
 }