Ensure vkGetPhysicalDeviceFormatProperties() are zerod for unsupported VkFormats.

Support MTLPixelFormats with larger values.
MVKPixelFormats::getVkFormatProperties() return
reference and log error if unsupported VkFormat.
Remove tests for null format name strings.
Consolidate MVKPhysicalDevice::getFormatProperties() overloads.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index aa16543..6bdaa3f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -271,7 +271,7 @@
 
 void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties2KHR* pFormatProperties) {
 	pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
-	pFormatProperties->formatProperties = _pixelFormats.getVkFormatProperties(format);
+	getFormatProperties(format, &pFormatProperties->formatProperties);
 }
 
 VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
@@ -1307,7 +1307,7 @@
             } else {
                 alignment = [_mtlDevice minimumLinearTextureAlignmentForPixelFormat: mtlFmt];
             }
-            VkFormatProperties props = _pixelFormats.getVkFormatProperties(vk);
+            VkFormatProperties& props = _pixelFormats.getVkFormatProperties(vk);
             // For uncompressed formats, this is the size of a single texel.
             // Note that no implementations of Metal support compressed formats
             // in a linear texture (including texture buffers). It's likely that even
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
index 9e2c4a1..7e124f1 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
@@ -31,7 +31,8 @@
 // Validate these values periodically as new formats are added over time.
 static const uint32_t _vkFormatCount = 256;
 static const uint32_t _vkFormatCoreCount = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
-static const uint32_t _mtlPixelFormatCount = MTLPixelFormatX32_Stencil8 + 2;     // The actual last enum value is not available on iOS
+static const uint32_t _mtlPixelFormatCount = 128;
+static const uint32_t _mtlPixelFormatCoreCount = MTLPixelFormatX32_Stencil8 + 2;     // The actual last enum value is not available on iOS
 static const uint32_t _mtlVertexFormatCount = MTLVertexFormatHalf + 1;
 
 
@@ -233,7 +234,7 @@
 	size_t getBytesPerLayer(MTLPixelFormat mtlFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer);
 
 	/** Returns the default properties for the specified Vulkan format. */
-	VkFormatProperties getVkFormatProperties(VkFormat vkFormat);
+	VkFormatProperties& getVkFormatProperties(VkFormat vkFormat);
 
 	/** Returns the Metal format capabilities supported by the specified Vulkan format. */
 	MVKMTLFmtCaps getCapabilities(VkFormat vkFormat);
@@ -323,7 +324,10 @@
 	uint16_t _vkFormatDescIndicesByVkFormatsCore[_vkFormatCoreCount];
 	std::unordered_map<uint32_t, uint32_t> _vkFormatDescIndicesByVkFormatsExt;
 
-	// Metal formats have small values and are mapped by simple lookup array.
-	uint16_t _mtlFormatDescIndicesByMTLPixelFormats[_mtlPixelFormatCount];
+	// Most Metal formats have small values and are mapped by simple lookup array.
+	// Outliers are mapped by a map.
+	uint16_t _mtlFormatDescIndicesByMTLPixelFormatsCore[_mtlPixelFormatCoreCount];
+	std::unordered_map<NSUInteger, uint32_t> _mtlFormatDescIndicesByMTLPixelFormatsExt;
+
 	uint16_t _mtlFormatDescIndicesByMTLVertexFormats[_mtlVertexFormatCount];
 };
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
index c307579..361358c 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
@@ -198,7 +198,7 @@
 		if ( !mtlPixFmt || !vkDesc.hasReportedSubstitution ) {
 			string errMsg;
 			errMsg += "VkFormat ";
-			errMsg += (vkDesc.name) ? vkDesc.name : to_string(vkDesc.vkFormat);
+			errMsg += vkDesc.name;
 			errMsg += " is not supported on this device.";
 
 			if (mtlPixFmt) {
@@ -206,7 +206,7 @@
 
 				auto& vkDescSubs = getVkFormatDesc(mtlPixFmt);
 				errMsg += " Using VkFormat ";
-				errMsg += (vkDescSubs.name) ? vkDescSubs.name : to_string(vkDescSubs.vkFormat);
+				errMsg += vkDescSubs.name;
 				errMsg += " instead.";
 			}
 			MVKBaseObject::reportError(_physicalDevice, VK_ERROR_FORMAT_NOT_SUPPORTED, "%s", errMsg.c_str());
@@ -262,8 +262,13 @@
     return mvkCeilingDivide(texelRowsPerLayer, getVkFormatDesc(mtlFormat).blockTexelSize.height) * bytesPerRow;
 }
 
-VkFormatProperties MVKPixelFormats::getVkFormatProperties(VkFormat vkFormat) {
-	return	getVkFormatDesc(vkFormat).properties;
+VkFormatProperties& MVKPixelFormats::getVkFormatProperties(VkFormat vkFormat) {
+	auto& vkDesc = getVkFormatDesc(vkFormat);
+	if ( !vkDesc.isSupported() ) {
+		MVKBaseObject::reportError(_physicalDevice, VK_ERROR_FORMAT_NOT_SUPPORTED,
+								   "VkFormat %s is not supported on this device.", vkDesc.name);
+	}
+	return vkDesc.properties;
 }
 
 MVKMTLFmtCaps MVKPixelFormats::getCapabilities(VkFormat vkFormat) {
@@ -311,7 +316,7 @@
 	if ( !mtlVtxFmt && vkFormat ) {
 		string errMsg;
 		errMsg += "VkFormat ";
-		errMsg += (vkDesc.name) ? vkDesc.name : to_string(vkDesc.vkFormat);
+		errMsg += vkDesc.name;
 		errMsg += " is not supported for vertex buffers on this device.";
 
 		if (vkDesc.vertexIsSupportedOrSubstitutable()) {
@@ -319,7 +324,7 @@
 
 			auto& vkDescSubs = getVkFormatDesc(getMTLVertexFormatDesc(mtlVtxFmt).vkFormat);
 			errMsg += " Using VkFormat ";
-			errMsg += (vkDescSubs.name) ? vkDescSubs.name : to_string(vkDescSubs.vkFormat);
+			errMsg += vkDescSubs.name;
 			errMsg += " instead.";
 		}
 		MVKBaseObject::reportError(_physicalDevice, VK_ERROR_FORMAT_NOT_SUPPORTED, "%s", errMsg.c_str());
@@ -449,7 +454,9 @@
 
 // Return a reference to the Vulkan format descriptor corresponding to the VkFormat.
 MVKVkFormatDesc& MVKPixelFormats::getVkFormatDesc(VkFormat vkFormat) {
-	uint16_t fmtIdx = (vkFormat < _vkFormatCoreCount) ? _vkFormatDescIndicesByVkFormatsCore[vkFormat] : _vkFormatDescIndicesByVkFormatsExt[vkFormat];
+	uint16_t fmtIdx = ((vkFormat < _vkFormatCoreCount)
+					   ? _vkFormatDescIndicesByVkFormatsCore[vkFormat]
+					   : _vkFormatDescIndicesByVkFormatsExt[vkFormat]);
 	return _vkFormatDescriptions[fmtIdx];
 }
 
@@ -465,7 +472,9 @@
 
 // Return a reference to the Metal format descriptor corresponding to the MTLPixelFormat.
 MVKMTLFormatDesc& MVKPixelFormats::getMTLPixelFormatDesc(MTLPixelFormat mtlFormat) {
-	uint16_t fmtIdx = (mtlFormat < _mtlPixelFormatCount) ? _mtlFormatDescIndicesByMTLPixelFormats[mtlFormat] : 0;
+	uint16_t fmtIdx = ((mtlFormat < _mtlPixelFormatCoreCount)
+					   ? _mtlFormatDescIndicesByMTLPixelFormatsCore[mtlFormat]
+					   : _mtlFormatDescIndicesByMTLPixelFormatsExt[mtlFormat]);
 	return _mtlPixelFormatDescriptions[fmtIdx];
 }
 
@@ -510,6 +519,7 @@
 	uint32_t fmtIdx = 0;
 
 	// When adding to this list, be sure to ensure _vkFormatCount is large enough for the format count
+
 	// UNDEFINED must come first.
 	addVkFormatDesc( UNDEFINED, Invalid, Invalid, Invalid, Invalid, 1, 1, 0, None );
 
@@ -939,6 +949,7 @@
 	uint32_t fmtIdx = 0;
 
 	// When adding to this list, be sure to ensure _mtlVertexFormatCount is large enough for the format count
+
 	// MTLVertexFormatInvalid must come first.
 	addMTLVertexFormatDesc( Invalid, None, None );
 
@@ -1014,13 +1025,21 @@
 void MVKPixelFormats::buildMTLFormatMaps() {
 
 	// Set all MTLPixelFormats and MTLVertexFormats to undefined/invalid
-	mvkClear(_mtlFormatDescIndicesByMTLPixelFormats, _mtlPixelFormatCount);
+	mvkClear(_mtlFormatDescIndicesByMTLPixelFormatsCore, _mtlPixelFormatCoreCount);
 	mvkClear(_mtlFormatDescIndicesByMTLVertexFormats, _mtlVertexFormatCount);
 
-	// Build lookup table for MTLPixelFormat specs
+	// Build lookup table for MTLPixelFormat specs.
+	// For most Metal format values, which are small and consecutive, use a simple lookup array.
+	// For outlier format values, which can be large, use a map.
 	for (uint32_t fmtIdx = 0; fmtIdx < _mtlPixelFormatCount; fmtIdx++) {
 		MTLPixelFormat fmt = _mtlPixelFormatDescriptions[fmtIdx].mtlPixelFormat;
-		if (fmt) { _mtlFormatDescIndicesByMTLPixelFormats[fmt] = fmtIdx; }
+		if (fmt) {
+			if (fmt < _mtlPixelFormatCoreCount) {
+				_mtlFormatDescIndicesByMTLPixelFormatsCore[fmt] = fmtIdx;
+			} else {
+				_mtlFormatDescIndicesByMTLPixelFormatsExt[fmt] = fmtIdx;
+			}
+		}
 	}
 
 	// Build lookup table for MTLVertexFormat specs