Reduce memory requirements for event commands.

Convert MVKCmdWaitEvents to template class based on number of events.
Add separate MVKCmdSetEvent and MVKCmdResetEvent classes.
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
index 5b07da5..63b020e 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
@@ -34,7 +34,7 @@
 #pragma mark MVKCmdPipelineBarrier
 
 /**
- * Represents an abstract Vulkan command to add a pipeline barrier.
+ * Vulkan command to add a pipeline barrier.
  * Template class to balance vector pre-allocations between very common low counts and fewer larger counts.
  */
 template <size_t N>
@@ -208,22 +208,46 @@
 #pragma mark -
 #pragma mark MVKCmdSetResetEvent
 
-/** Vulkan command to set or reset an event. */
+/** Abstract Vulkan command to set or reset an event. */
 class MVKCmdSetResetEvent : public MVKCommand {
 
 public:
 	VkResult setContent(MVKCommandBuffer* cmdBuff,
 						VkEvent event,
-						VkPipelineStageFlags stageMask,
-						bool status);
+						VkPipelineStageFlags stageMask);
 
+protected:
+	MVKEvent* _mvkEvent;
+
+};
+
+
+#pragma mark -
+#pragma mark MVKCmdSetEvent
+
+/** Vulkan command to set an event. */
+class MVKCmdSetEvent : public MVKCmdSetResetEvent {
+
+public:
 	void encode(MVKCommandEncoder* cmdEncoder) override;
 
 protected:
 	MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
 
-	MVKEvent* _mvkEvent;
-	bool _status;
+};
+
+
+#pragma mark -
+#pragma mark MVKCmdResetEvent
+
+/** Vulkan command to reset an event. */
+class MVKCmdResetEvent : public MVKCmdSetResetEvent {
+
+public:
+	void encode(MVKCommandEncoder* cmdEncoder) override;
+
+protected:
+	MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
 
 };
 
@@ -232,6 +256,11 @@
 #pragma mark MVKCmdWaitEvents
 
 /** Vulkan command to wait for an event to be signaled. */
+/**
+ * Vulkan command to wait for an event to be signaled.
+ * Template class to balance vector pre-allocations between very common low counts and fewer larger counts.
+ */
+template <size_t N>
 class MVKCmdWaitEvents : public MVKCommand {
 
 public:
@@ -252,6 +281,10 @@
 protected:
 	MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
 
-	MVKVectorInline<MVKEvent*, 4> _mvkEvents;
+	MVKVectorInline<MVKEvent*, N> _mvkEvents;
 
 };
+
+// Concrete template class implementations.
+typedef MVKCmdWaitEvents<1> MVKCmdWaitEvents1;
+typedef MVKCmdWaitEvents<8> MVKCmdWaitEventsMulti;
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
index cac6f6d..d3d495d 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
@@ -406,33 +406,44 @@
 
 VkResult MVKCmdSetResetEvent::setContent(MVKCommandBuffer* cmdBuff,
 										 VkEvent event,
-										 VkPipelineStageFlags stageMask,
-										 bool status) {
+										 VkPipelineStageFlags stageMask) {
 	_mvkEvent = (MVKEvent*)event;
-	_status = status;
 
 	return VK_SUCCESS;
 }
 
-void MVKCmdSetResetEvent::encode(MVKCommandEncoder* cmdEncoder) {
-	cmdEncoder->signalEvent(_mvkEvent, _status);
+
+#pragma mark -
+#pragma mark MVKCmdSetEvent
+
+void MVKCmdSetEvent::encode(MVKCommandEncoder* cmdEncoder) {
+	cmdEncoder->signalEvent(_mvkEvent, true);
+}
+
+
+#pragma mark -
+#pragma mark MVKCmdResetEvent
+
+void MVKCmdResetEvent::encode(MVKCommandEncoder* cmdEncoder) {
+	cmdEncoder->signalEvent(_mvkEvent, false);
 }
 
 
 #pragma mark -
 #pragma mark MVKCmdWaitEvents
 
-VkResult MVKCmdWaitEvents::setContent(MVKCommandBuffer* cmdBuff,
-									  uint32_t eventCount,
-									  const VkEvent* pEvents,
-									  VkPipelineStageFlags srcStageMask,
-									  VkPipelineStageFlags dstStageMask,
-									  uint32_t memoryBarrierCount,
-									  const VkMemoryBarrier* pMemoryBarriers,
-									  uint32_t bufferMemoryBarrierCount,
-									  const VkBufferMemoryBarrier* pBufferMemoryBarriers,
-									  uint32_t imageMemoryBarrierCount,
-									  const VkImageMemoryBarrier* pImageMemoryBarriers) {
+template <size_t N>
+VkResult MVKCmdWaitEvents<N>::setContent(MVKCommandBuffer* cmdBuff,
+										 uint32_t eventCount,
+										 const VkEvent* pEvents,
+										 VkPipelineStageFlags srcStageMask,
+										 VkPipelineStageFlags dstStageMask,
+										 uint32_t memoryBarrierCount,
+										 const VkMemoryBarrier* pMemoryBarriers,
+										 uint32_t bufferMemoryBarrierCount,
+										 const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+										 uint32_t imageMemoryBarrierCount,
+										 const VkImageMemoryBarrier* pImageMemoryBarriers) {
 	_mvkEvents.clear();	// Clear for reuse
 	_mvkEvents.reserve(eventCount);
 	for (uint32_t i = 0; i < eventCount; i++) {
@@ -442,9 +453,13 @@
 	return VK_SUCCESS;
 }
 
-void MVKCmdWaitEvents::encode(MVKCommandEncoder* cmdEncoder) {
+template <size_t N>
+void MVKCmdWaitEvents<N>::encode(MVKCommandEncoder* cmdEncoder) {
 	for (MVKEvent* mvkEvt : _mvkEvents) {
 		mvkEvt->encodeWait(cmdEncoder->_mtlCmdBuffer);
 	}
 }
 
+template class MVKCmdWaitEvents<1>;
+template class MVKCmdWaitEvents<8>;
+
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def
index a6087b4..40fee6f 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def
@@ -95,8 +95,9 @@
 MVK_CMD_TYPE_POOL(DebugMarkerBegin)
 MVK_CMD_TYPE_POOL(DebugMarkerEnd)
 MVK_CMD_TYPE_POOL(DebugMarkerInsert)
-MVK_CMD_TYPE_POOL(SetResetEvent)
-MVK_CMD_TYPE_POOL_LAST(WaitEvents)
+MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(WaitEvents, 1)
+MVK_CMD_TYPE_POOL(SetEvent)
+MVK_CMD_TYPE_POOL_LAST(ResetEvent)
 
 #undef MVK_CMD_TYPE_POOL
 #undef MVK_CMD_TYPE_POOL_LAST
diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm
index 90b79ec..b797675 100644
--- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm
+++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm
@@ -1688,9 +1688,9 @@
     VkCommandBuffer                             commandBuffer,
     VkEvent                                     event,
     VkPipelineStageFlags                        stageMask) {
-	
+
 	MVKTraceVulkanCallStart();
-	MVKAddCmd(SetResetEvent, commandBuffer, event, stageMask, true);
+	MVKAddCmd(SetEvent, commandBuffer, event, stageMask);
 	MVKTraceVulkanCallEnd();
 }
 
@@ -1698,9 +1698,9 @@
     VkCommandBuffer                             commandBuffer,
     VkEvent                                     event,
     VkPipelineStageFlags                        stageMask) {
-	
+
 	MVKTraceVulkanCallStart();
-	MVKAddCmd(SetResetEvent, commandBuffer, event, stageMask, false);
+	MVKAddCmd(ResetEvent, commandBuffer, event, stageMask);
 	MVKTraceVulkanCallEnd();
 }
 
@@ -1718,11 +1718,11 @@
 	const VkImageMemoryBarrier*                 pImageMemoryBarriers) {
 
 	MVKTraceVulkanCallStart();
-	MVKAddCmd(WaitEvents, commandBuffer, eventCount, pEvents,
-			  srcStageMask, dstStageMask,
-			  memoryBarrierCount, pMemoryBarriers,
-			  bufferMemoryBarrierCount, pBufferMemoryBarriers,
-			  imageMemoryBarrierCount, pImageMemoryBarriers);
+	MVKAddCmdFromThreshold(WaitEvents, eventCount, 1, commandBuffer,
+						   eventCount, pEvents, srcStageMask, dstStageMask,
+						   memoryBarrierCount, pMemoryBarriers,
+						   bufferMemoryBarrierCount, pBufferMemoryBarriers,
+						   imageMemoryBarrierCount, pImageMemoryBarriers);
 	MVKTraceVulkanCallEnd();
 }
 
@@ -1740,7 +1740,8 @@
 
 	MVKTraceVulkanCallStart();
 	uint32_t barrierCount = memoryBarrierCount + bufferMemoryBarrierCount + imageMemoryBarrierCount;
-	MVKAddCmdFromTwoThresholds(PipelineBarrier, barrierCount, 1, 4, commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
+	MVKAddCmdFromTwoThresholds(PipelineBarrier, barrierCount, 1, 4, commandBuffer,
+							   srcStageMask, dstStageMask, dependencyFlags,
 							   memoryBarrierCount, pMemoryBarriers,
 							   bufferMemoryBarrierCount, pBufferMemoryBarriers,
 							   imageMemoryBarrierCount, pImageMemoryBarriers);