Merge pull request #565 from mbarriault/master

Several fixes regarding tessellation, especially in indexed and instanced rendering
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm
index f54bb15..6e8a7b5 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm
@@ -108,7 +108,7 @@
     if (pipeline->isTessellationPipeline()) {
         inControlPointCount = pipeline->getInputControlPointCount();
         outControlPointCount = pipeline->getOutputControlPointCount();
-        patchCount = (uint32_t)mvkCeilingDivide(_vertexCount * _instanceCount, inControlPointCount);
+        patchCount = (uint32_t)mvkCeilingDivide(_vertexCount, inControlPointCount);
     }
     for (uint32_t s : stages) {
         auto stage = MVKGraphicsStage(s);
@@ -295,7 +295,7 @@
     if (pipeline->isTessellationPipeline()) {
         inControlPointCount = pipeline->getInputControlPointCount();
         outControlPointCount = pipeline->getOutputControlPointCount();
-        patchCount = (uint32_t)mvkCeilingDivide(_indexCount * _instanceCount, inControlPointCount);
+        patchCount = (uint32_t)mvkCeilingDivide(_indexCount, inControlPointCount);
     }
     for (uint32_t s : stages) {
         auto stage = MVKGraphicsStage(s);
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandPipelineStateFactoryShaderSource.h b/MoltenVK/MoltenVK/Commands/MVKCommandPipelineStateFactoryShaderSource.h
index c551587..f819633 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandPipelineStateFactoryShaderSource.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandPipelineStateFactoryShaderSource.h
@@ -176,7 +176,7 @@
 };                                                                                                              \n\
 #endif                                                                                                          \n\
                                                                                                                 \n\
-#if __METAL_VERSION >= 120                                                                                      \n\
+#if __METAL_VERSION__ >= 120                                                                                    \n\
 kernel void cmdDrawIndirectConvertBuffers(const device char* srcBuff [[buffer(0)]],                             \n\
                                           device char* destBuff [[buffer(1)]],                                  \n\
                                           constant uint32_t& srcStride [[buffer(2)]],                           \n\
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
index 272e6b3..8bd1c2c 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
@@ -218,7 +218,7 @@
     bool addFragmentShaderToPipeline(MTLRenderPipelineDescriptor* plDesc, const VkGraphicsPipelineCreateInfo* pCreateInfo, SPIRVToMSLConverterContext& shaderContext);
     bool addVertexInputToPipeline(MTLRenderPipelineDescriptor* plDesc, const VkPipelineVertexInputStateCreateInfo* pVI, const SPIRVToMSLConverterContext& shaderContext);
     void addTessellationToPipeline(MTLRenderPipelineDescriptor* plDesc, const SPIRVTessReflectionData& reflectData, const VkPipelineTessellationStateCreateInfo* pTS);
-    void addFragmentOutputToPipeline(MTLRenderPipelineDescriptor* plDesc, const SPIRVTessReflectionData& reflectData, const VkGraphicsPipelineCreateInfo* pCreateInfo);
+    void addFragmentOutputToPipeline(MTLRenderPipelineDescriptor* plDesc, const SPIRVTessReflectionData& reflectData, const VkGraphicsPipelineCreateInfo* pCreateInfo, bool isTessellationVertexPipeline = false);
     bool isRenderingPoints(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData);
 
 	const VkPipelineShaderStageCreateInfo* _pVertexSS = nullptr;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index 925a01f..78ce185 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -161,7 +161,7 @@
 void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage) {
 
     id<MTLRenderCommandEncoder> mtlCmdEnc = cmdEncoder->_mtlRenderEncoder;
-    if ( !mtlCmdEnc ) { return; }   // Pre-renderpass. Come back later.
+    if ( stage != kMVKGraphicsStageTessControl && !mtlCmdEnc ) { return; }   // Pre-renderpass. Come back later.
 
     switch (stage) {
         case kMVKGraphicsStageVertex:
@@ -446,7 +446,7 @@
 
 	// Even though this won't be used for rasterization, we still have to set up the rasterization state to
 	// match the render pass, or Metal will complain.
-	addFragmentOutputToPipeline(plDesc, reflectData, pCreateInfo);
+	addFragmentOutputToPipeline(plDesc, reflectData, pCreateInfo, true);
 
 	return plDesc;
 }
@@ -935,7 +935,7 @@
 	plDesc.tessellationPartitionMode = mvkMTLTessellationPartitionModeFromSpvExecutionMode(reflectData.partitionMode);
 }
 
-void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescriptor* plDesc, const SPIRVTessReflectionData& reflectData, const VkGraphicsPipelineCreateInfo* pCreateInfo) {
+void MVKGraphicsPipeline::addFragmentOutputToPipeline(MTLRenderPipelineDescriptor* plDesc, const SPIRVTessReflectionData& reflectData, const VkGraphicsPipelineCreateInfo* pCreateInfo, bool isTessellationVertexPipeline) {
 
     // Retrieve the render subpass for which this pipeline is being constructed
     MVKRenderPass* mvkRendPass = (MVKRenderPass*)pCreateInfo->renderPass;
@@ -943,7 +943,7 @@
 
 	// Topology
 	if (pCreateInfo->pInputAssemblyState) {
-		plDesc.inputPrimitiveTopologyMVK = isRenderingPoints(pCreateInfo, reflectData)
+		plDesc.inputPrimitiveTopologyMVK = (isTessellationVertexPipeline || isRenderingPoints(pCreateInfo, reflectData))
 												? MTLPrimitiveTopologyClassPoint
 												: mvkMTLPrimitiveTopologyClassFromVkPrimitiveTopology(pCreateInfo->pInputAssemblyState->topology);
 	}
diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
index fbb17af..5b8bb2e 100644
--- a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
+++ b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
@@ -841,6 +841,7 @@
         mvkEnableFlag(mtlUsage, MTLTextureUsagePixelFormatView);
     }
     if ( mvkAreFlagsEnabled(vkImageUsageFlags, VK_IMAGE_USAGE_STORAGE_BIT) ) {
+        mvkEnableFlag(mtlUsage, MTLTextureUsageShaderRead);
         mvkEnableFlag(mtlUsage, MTLTextureUsageShaderWrite);
         mvkEnableFlag(mtlUsage, MTLTextureUsagePixelFormatView);
     }