Merge pull request #889 from billhollings/master

Fix crash when more than two GPUs.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 47fdd4c..9afd2df 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -17,14 +17,14 @@
 MoltenVK 1.0.42
 ---------------
 
-Released TBD
+Released 2020/06/01
 
 - Add support for extensions:
 	- `VK_KHR_external_memory` (non-functional groundwork for future 
 	  Metal-resource Vulkan extension).
 	- `VK_KHR_external_memory_capabilities` (non-functional groundwork 
 	   for future Metal-resource Vulkan extension).
-- Memory consumption improvements when handling Vulkan commands.
+- Memory consumption improvements.
 - Reinstate `VulkanSamples API-Samples` demo apps and add 
   `input_attachment` and `push_descriptors` demos.
 - `vkQueuePresentKHR()` returns a `VkResult` for each swapchain.
@@ -34,6 +34,7 @@
 	  through `vkGetPerformanceStatisticsMVK()`.
 	- Add `MVK_CONFIG_PERFORMANCE_LOGGING_INLINE` env var to enable/disable
 	  logging of performance of each activity when it happens. 
+- Fix crash when more than two GPUs.
 - Support Xcode 11.5.
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index a367988..aa16543 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -1457,6 +1457,7 @@
 		_properties.limits.maxComputeSharedMemorySize = (32 * KIBI);
 #endif
 	}
+	_properties.limits.maxSamplerLodBias = 0;	// Bias not supported in API, but can be applied in shader directly.
 
     _properties.limits.minTexelOffset = -8;
     _properties.limits.maxTexelOffset = 7;
@@ -1489,8 +1490,6 @@
     _properties.limits.mipmapPrecisionBits = 4;
     _properties.limits.viewportSubPixelBits = 0;
 
-    _properties.limits.maxSamplerLodBias = 2;
-
     _properties.limits.discreteQueuePriorities = 2;
 
     _properties.limits.minInterpolationOffset = -0.5;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
index d05604e..6195691 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
@@ -19,7 +19,6 @@
 #pragma once
 
 #include "MVKEnvironment.h"
-#include "MVKDevice.h"
 #include "MVKLayers.h"
 #include "MVKVulkanAPIObject.h"
 #include "MVKSmallVector.h"
@@ -28,6 +27,8 @@
 #include <string>
 #include <mutex>
 
+class MVKPhysicalDevice;
+class MVKDevice;
 class MVKSurface;
 class MVKDebugReportCallback;
 class MVKDebugUtilsMessenger;
@@ -189,7 +190,7 @@
 
 	MVKConfiguration _mvkConfig;
 	VkApplicationInfo _appInfo;
-	MVKSmallVector<MVKPhysicalDevice, 2> _physicalDevices;
+	MVKSmallVector<MVKPhysicalDevice*, 2> _physicalDevices;
 	MVKSmallVector<MVKDebugReportCallback*> _debugReportCallbacks;
 	MVKSmallVector<MVKDebugUtilsMessenger*> _debugUtilMessengers;
 	std::unordered_map<std::string, MVKEntryPoint> _entryPoints;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
index 728a12b..4e618f4 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
@@ -18,6 +18,7 @@
 
 
 #include "MVKInstance.h"
+#include "MVKDevice.h"
 #include "MVKFoundation.h"
 #include "MVKSurface.h"
 #include "MVKOSExtensions.h"
@@ -62,7 +63,7 @@
 
 	// Now populate the devices
 	for (uint32_t pdIdx = 0; pdIdx < *pCount; pdIdx++) {
-		pPhysicalDevices[pdIdx] = _physicalDevices[pdIdx].getVkPhysicalDevice();
+		pPhysicalDevices[pdIdx] = _physicalDevices[pdIdx]->getVkPhysicalDevice();
 	}
 
 	return result;
@@ -89,7 +90,7 @@
 	// Now populate the device groups
 	for (uint32_t pdIdx = 0; pdIdx < *pCount; pdIdx++) {
 		pPhysicalDeviceGroupProps[pdIdx].physicalDeviceCount = 1;
-		pPhysicalDeviceGroupProps[pdIdx].physicalDevices[0] = _physicalDevices[pdIdx].getVkPhysicalDevice();
+		pPhysicalDeviceGroupProps[pdIdx].physicalDevices[0] = _physicalDevices[pdIdx]->getVkPhysicalDevice();
 		pPhysicalDeviceGroupProps[pdIdx].subsetAllocation = VK_FALSE;
 	}
 
@@ -365,8 +366,9 @@
 	// and other Obj-C classes, so wrap it all in an autorelease pool.
 	@autoreleasepool {
 		NSArray<id<MTLDevice>>* mtlDevices = availableMTLDevicesArray();
+		_physicalDevices.reserve(mtlDevices.count);
 		for (id<MTLDevice> mtlDev in mtlDevices) {
-			_physicalDevices.emplace_back(this, mtlDev);
+			_physicalDevices.push_back(new MVKPhysicalDevice(this, mtlDev));
 		}
 	}
 
@@ -683,8 +685,10 @@
 }
 
 MVKInstance::~MVKInstance() {
-	lock_guard<mutex> lock(_dcbLock);
 	_useCreationCallbacks = true;
+	mvkDestroyContainerContents(_physicalDevices);
+
+	lock_guard<mutex> lock(_dcbLock);
 	mvkDestroyContainerContents(_debugReportCallbacks);
 }
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
index 34024fa..83abbbb 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
@@ -173,8 +173,8 @@
 
 	void propagateDebugName() override {}
 
-	MVKSmallVector<MVKRenderPassAttachment, kMVKDefaultAttachmentCount> _attachments;
-	MVKSmallVector<MVKRenderSubpass, 1> _subpasses;
+	MVKSmallVector<MVKRenderPassAttachment> _attachments;
+	MVKSmallVector<MVKRenderSubpass> _subpasses;
 	MVKSmallVector<VkSubpassDependency> _subpassDependencies;
 
 };
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
index 5702394..3af05fc 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
@@ -151,7 +151,7 @@
 	void merge(MVKShaderLibraryCache* other);
 
 	MVKVulkanAPIDeviceObject* _owner;
-	MVKSmallVector<std::pair<SPIRVToMSLConversionConfiguration, MVKShaderLibrary*>, 1> _shaderLibraries;
+	MVKSmallVector<std::pair<SPIRVToMSLConversionConfiguration, MVKShaderLibrary*>> _shaderLibraries;
 };
 
 
diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
index e3407ec..8acd4ae 100644
--- a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
+++ b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
@@ -452,9 +452,10 @@
 MTLTriangleFillMode mvkMTLTriangleFillModeFromVkPolygonModeInObj(VkPolygonMode vkFillMode, MVKBaseObject* mvkObj) {
 	switch (vkFillMode) {
 		case VK_POLYGON_MODE_FILL:
-		case VK_POLYGON_MODE_POINT:
 			return MTLTriangleFillModeFill;
 
+		case VK_POLYGON_MODE_POINT:
+			MVKBaseObject::reportError(mvkObj, VK_ERROR_FORMAT_NOT_SUPPORTED, "VkPolygonMode value VK_POLYGON_MODE_POINT is not supported for render pipelines.");
 		case VK_POLYGON_MODE_LINE:
 			return MTLTriangleFillModeLines;