Disable the variableMultisampleRate feature for now.

We actually can't support this. Metal's validation layer complains if
a pipeline has a different raster sample count from that of the
framebuffer, even in the no-attachment case. This means that the
`defaultRasterSampleCount` property must be set correctly if Metal
supports no-attachment rendering, and the sample count of the dummy
texture must be set properly otherwise.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index e21d8aa..83add58 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -1265,7 +1265,6 @@
     _features.shaderClipDistance = true;
     _features.shaderInt16 = true;
     _features.multiDrawIndirect = true;
-    _features.variableMultisampleRate = true;
     _features.inheritedQueries = true;
 
 	_features.shaderSampledImageArrayDynamicIndexing = _metalFeatures.arrayOfTextures;
@@ -1407,7 +1406,7 @@
 //    VkBool32    sparseResidency8Samples;
 //    VkBool32    sparseResidency16Samples;
 //    VkBool32    sparseResidencyAliased;
-//    VkBool32    variableMultisampleRate;                      // done
+//    VkBool32    variableMultisampleRate;
 //    VkBool32    inheritedQueries;                             // done
 //} VkPhysicalDeviceFeatures;
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index ce836c1..0d4eae3 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -1353,6 +1353,7 @@
     // Multisampling
     if (pCreateInfo->pMultisampleState) {
         plDesc.sampleCount = mvkSampleCountFromVkSampleCountFlagBits(pCreateInfo->pMultisampleState->rasterizationSamples);
+        mvkRenderSubpass->setDefaultSampleCount(pCreateInfo->pMultisampleState->rasterizationSamples);
         plDesc.alphaToCoverageEnabled = pCreateInfo->pMultisampleState->alphaToCoverageEnable;
         plDesc.alphaToOneEnabled = pCreateInfo->pMultisampleState->alphaToOneEnable;
     }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
index f8decda..ca51bd0 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
@@ -67,6 +67,9 @@
 	/** Returns the Vulkan sample count of the attachments used in this subpass. */
 	VkSampleCountFlagBits getSampleCount();
 
+	/** Sets the default sample count for when there are no attachments used in this subpass. */
+	void setDefaultSampleCount(VkSampleCountFlagBits count) { _defaultSampleCount = count; }
+
 	/** Returns whether or not this is a multiview subpass. */
 	bool isMultiview() const { return _viewMask != 0; }
 
@@ -141,6 +144,7 @@
 	MVKSmallVector<uint32_t, kMVKDefaultAttachmentCount> _preserveAttachments;
 	VkAttachmentReference2 _depthStencilAttachment;
 	id<MTLTexture> _mtlDummyTex = nil;
+	VkSampleCountFlagBits _defaultSampleCount = VK_SAMPLE_COUNT_1_BIT;
 };
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
index c3eeb6a..464f1d0 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
@@ -259,10 +259,11 @@
 
 	_mtlDummyTex = nil;
 	if (caUsedCnt == 0 && dsRPAttIdx == VK_ATTACHMENT_UNUSED) {
+		uint32_t sampleCount = mvkSampleCountFromVkSampleCountFlagBits(_defaultSampleCount);
         if (_renderPass->getDevice()->_pMetalFeatures->renderWithoutAttachments) {
             // We support having no attachments.
 #if MVK_MACOS_OR_IOS
-            mtlRPDesc.defaultRasterSampleCount = 1;
+            mtlRPDesc.defaultRasterSampleCount = sampleCount;
 #endif
             return;
         }
@@ -271,11 +272,32 @@
 		VkExtent2D fbExtent = framebuffer->getExtent2D();
 		MTLTextureDescriptor* mtlTexDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatR8Unorm width: fbExtent.width height: fbExtent.height mipmapped: NO];
 		if (isMultiview()) {
+#if MVK_MACOS
+			if (sampleCount > 1 && _renderPass->getDevice()->_pMetalFeatures->multisampleLayeredRendering) {
+				mtlTexDesc.textureType = MTLTextureType2DMultisampleArray;
+				mtlTexDesc.sampleCount = sampleCount;
+			} else {
+				mtlTexDesc.textureType = MTLTextureType2DArray;
+			}
+#else
 			mtlTexDesc.textureType = MTLTextureType2DArray;
+#endif
 			mtlTexDesc.arrayLength = getViewCountInMetalPass(passIdx);
 		} else if (framebuffer->getLayerCount() > 1) {
+#if MVK_MACOS
+			if (sampleCount > 1 && _renderPass->getDevice()->_pMetalFeatures->multisampleLayeredRendering) {
+				mtlTexDesc.textureType = MTLTextureType2DMultisampleArray;
+				mtlTexDesc.sampleCount = sampleCount;
+			} else {
+				mtlTexDesc.textureType = MTLTextureType2DArray;
+			}
+#else
 			mtlTexDesc.textureType = MTLTextureType2DArray;
+#endif
 			mtlTexDesc.arrayLength = framebuffer->getLayerCount();
+		} else if (sampleCount > 1) {
+			mtlTexDesc.textureType = MTLTextureType2DMultisample;
+			mtlTexDesc.sampleCount = sampleCount;
 		}
 #if MVK_IOS
 		if ([_renderPass->getMTLDevice() supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v3]) {