Merge pull request #2108 from spnda/format_feature_flags2
Add: KHR_format_feature_flags2
diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md
index 4a4c465..eb12a83 100644
--- a/Docs/MoltenVK_Runtime_UserGuide.md
+++ b/Docs/MoltenVK_Runtime_UserGuide.md
@@ -325,6 +325,7 @@
- `VK_KHR_device_group_creation`
- `VK_KHR_driver_properties`
- `VK_KHR_dynamic_rendering`
+- `VK_KHR_format_feature_flags2`
- `VK_KHR_fragment_shader_barycentric`
- *Requires Metal 2.2 on Mac or Metal 2.3 on iOS.*
- `VK_KHR_get_memory_requirements2`
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 14b84f1..e6abcc0 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -894,6 +894,22 @@
void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties2KHR* pFormatProperties) {
pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
+
+ for (auto* next = (VkBaseOutStructure*)pFormatProperties->pNext; next; next = next->pNext) {
+ switch (next->sType) {
+ case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR: {
+ auto* properties3 = (VkFormatProperties3*)next;
+ auto& properties = _pixelFormats.getVkFormatProperties3(format);
+ properties3->linearTilingFeatures = properties.linearTilingFeatures;
+ properties3->optimalTilingFeatures = properties.optimalTilingFeatures;
+ properties3->bufferFeatures = properties.bufferFeatures;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
getFormatProperties(format, &pFormatProperties->formatProperties);
}
@@ -1005,15 +1021,14 @@
maxLayers = 1;
sampleCounts = VK_SAMPLE_COUNT_1_BIT;
} else {
- VkFormatProperties fmtProps;
- getFormatProperties(format, &fmtProps);
+ VkFormatProperties3& fmtProps = _pixelFormats.getVkFormatProperties3(format);
// Compressed multisampled textures aren't supported.
// Chroma-subsampled multisampled textures aren't supported.
// Multisampled cube textures aren't supported.
// Non-renderable multisampled textures aren't supported.
if (mvkFmt == kMVKFormatCompressed || isChromaSubsampled ||
mvkIsAnyFlagEnabled(flags, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ||
- !mvkIsAnyFlagEnabled(fmtProps.optimalTilingFeatures, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ) {
+ !mvkIsAnyFlagEnabled(fmtProps.optimalTilingFeatures, VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT) ) {
sampleCounts = VK_SAMPLE_COUNT_1_BIT;
}
// BGRG and GBGR images may only have one mip level and one layer.
@@ -2526,7 +2541,11 @@
// to fill out the VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT struct.
uint32_t maxStorage = 0, maxUniform = 0;
bool singleTexelStorage = true, singleTexelUniform = true;
- _pixelFormats.enumerateSupportedFormats({0, 0, VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT}, true, [&](VkFormat vk) {
+
+ VkFormatProperties3 fmtProps = {}; // We don't initialize sType as enumerateSupportedFormats doesn't care.
+ fmtProps.bufferFeatures = VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
+
+ _pixelFormats.enumerateSupportedFormats(fmtProps, true, [&](VkFormat vk) {
MTLPixelFormat mtlFmt = _pixelFormats.getMTLPixelFormat(vk);
if ( !mtlFmt ) { return false; } // If format is invalid, avoid validation errors on MTLDevice format alignment calls
@@ -2536,7 +2555,7 @@
} else {
alignment = [_mtlDevice minimumLinearTextureAlignmentForPixelFormat: mtlFmt];
}
- VkFormatProperties& props = _pixelFormats.getVkFormatProperties(vk);
+ VkFormatProperties3& props = _pixelFormats.getVkFormatProperties3(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
@@ -2564,11 +2583,11 @@
break;
}
}
- if (mvkAreAllFlagsEnabled(props.bufferFeatures, VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) {
+ if (mvkAreAllFlagsEnabled(props.bufferFeatures, VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT)) {
maxUniform = max(maxUniform, uint32_t(alignment));
if (alignment > texelSize) { singleTexelUniform = false; }
}
- if (mvkAreAllFlagsEnabled(props.bufferFeatures, VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) {
+ if (mvkAreAllFlagsEnabled(props.bufferFeatures, VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT)) {
maxStorage = max(maxStorage, uint32_t(alignment));
if (alignment > texelSize) { singleTexelStorage = false; }
}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 61bb96b..d9d6a8b 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -931,7 +931,7 @@
_is3DCompressed = (getImageType() == VK_IMAGE_TYPE_3D) && (pixFmts->getFormatType(pCreateInfo->format) == kMVKFormatCompressed) && !_device->_pMetalFeatures->native3DCompressedTextures;
_isDepthStencilAttachment = (mvkAreAllFlagsEnabled(pCreateInfo->usage, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ||
- mvkAreAllFlagsEnabled(pixFmts->getVkFormatProperties(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT));
+ mvkAreAllFlagsEnabled(pixFmts->getVkFormatProperties3(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT));
_canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews;
_rowByteAlignment = _isLinear || _isLinearForAtomics ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this) : mvkEnsurePowerOfTwo(pixFmts->getBytesPerBlock(pCreateInfo->format));
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
index 0e1ecd7..cbb8aa8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
@@ -147,7 +147,7 @@
VkExtent2D blockTexelSize;
uint32_t bytesPerBlock;
MVKFormatType formatType;
- VkFormatProperties properties;
+ VkFormatProperties3 properties;
VkComponentMapping componentMapping;
const char* name;
bool hasReportedSubstitution;
@@ -344,7 +344,8 @@
MTLTextureSwizzleChannels getMTLTextureSwizzleChannels(VkFormat vkFormat);
/** Returns the default properties for the specified Vulkan format. */
- VkFormatProperties& getVkFormatProperties(VkFormat vkFormat);
+ VkFormatProperties getVkFormatProperties(VkFormat format);
+ VkFormatProperties3& getVkFormatProperties3(VkFormat vkFormat);
/** Returns the Metal format capabilities supported by the specified Vulkan format, without substitution. */
MVKMTLFmtCaps getCapabilities(VkFormat vkFormat, bool isExtended = false);
@@ -397,15 +398,15 @@
bool isExtended = false);
/** Enumerates all formats that support the given features, calling a specified function for each one. */
- void enumerateSupportedFormats(VkFormatProperties properties, bool any, std::function<bool(VkFormat)> func);
+ void enumerateSupportedFormats(const VkFormatProperties3& properties, bool any, std::function<bool(VkFormat)> func);
/**
* Returns the Metal MTLVertexFormat corresponding to the specified
* Vulkan VkFormat as used as a vertex attribute format.
*/
MTLVertexFormat getMTLVertexFormat(VkFormat vkFormat);
-
-
+
+ static VkFormatFeatureFlags convertFormatPropertiesFlagBits(VkFormatFeatureFlags2 flags);
#pragma mark Construction
MVKPixelFormats(MVKPhysicalDevice* physicalDevice = nullptr);
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
index afec11c..c91a92f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
@@ -420,10 +420,19 @@
return mvkMTLTextureSwizzleChannelsFromVkComponentMapping(getVkComponentMapping(vkFormat));
}
-VkFormatProperties& MVKPixelFormats::getVkFormatProperties(VkFormat vkFormat) {
+VkFormatProperties3& MVKPixelFormats::getVkFormatProperties3(VkFormat vkFormat) {
return getVkFormatDesc(vkFormat).properties;
}
+VkFormatProperties MVKPixelFormats::getVkFormatProperties(VkFormat vkFormat) {
+ auto& properties = getVkFormatProperties3(vkFormat);
+ VkFormatProperties ret;
+ ret.linearTilingFeatures = MVKPixelFormats::convertFormatPropertiesFlagBits(properties.linearTilingFeatures);
+ ret.optimalTilingFeatures = MVKPixelFormats::convertFormatPropertiesFlagBits(properties.optimalTilingFeatures);
+ ret.bufferFeatures = MVKPixelFormats::convertFormatPropertiesFlagBits(properties.bufferFeatures);
+ return ret;
+}
+
MVKMTLFmtCaps MVKPixelFormats::getCapabilities(VkFormat vkFormat, bool isExtended) {
return getCapabilities(getVkFormatDesc(vkFormat).mtlPixelFormat, isExtended);
}
@@ -459,8 +468,8 @@
return getMTLVertexFormatDesc(mtlFormat).name;
}
-void MVKPixelFormats::enumerateSupportedFormats(VkFormatProperties properties, bool any, std::function<bool(VkFormat)> func) {
- static const auto areFeaturesSupported = [any](uint32_t a, uint32_t b) {
+void MVKPixelFormats::enumerateSupportedFormats(const VkFormatProperties3& properties, bool any, std::function<bool(VkFormat)> func) {
+ static const auto areFeaturesSupported = [any](VkFlags64 a, VkFlags64 b) {
if (b == 0) return true;
if (any)
return mvkIsAnyFlagEnabled(a, b);
@@ -792,6 +801,11 @@
return _mtlVertexFormatDescriptions[fmtIdx];
}
+VkFormatFeatureFlags MVKPixelFormats::convertFormatPropertiesFlagBits(VkFormatFeatureFlags2 flags) {
+ // Truncate to 32-bits and just return. All current values are identical.
+ return static_cast<VkFormatFeatureFlags>(flags);
+}
+
#pragma mark Construction
@@ -811,7 +825,7 @@
#define addVkFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, SWIZ_R, SWIZ_G, SWIZ_B, SWIZ_A) \
MVKAssert(fmtIdx < _vkFormatCount, "Attempting to describe %d VkFormats, but only have space for %d. Increase the value of _vkFormatCount", fmtIdx + 1, _vkFormatCount); \
_vkFormatDescriptions[fmtIdx++] = { VK_FORMAT_ ##VK_FMT, MTLPixelFormat ##MTL_FMT, MTLPixelFormat ##MTL_FMT_ALT, MTLVertexFormat ##MTL_VTX_FMT, MTLVertexFormat ##MTL_VTX_FMT_ALT, \
- CSPC, CSCB, { BLK_W, BLK_H }, BLK_BYTE_CNT, kMVKFormat ##MVK_FMT_TYPE, { 0, 0, 0 }, \
+ CSPC, CSCB, { BLK_W, BLK_H }, BLK_BYTE_CNT, kMVKFormat ##MVK_FMT_TYPE, { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, nullptr, 0, 0, 0 }, \
{ VK_COMPONENT_SWIZZLE_ ##SWIZ_R, VK_COMPONENT_SWIZZLE_ ##SWIZ_G, VK_COMPONENT_SWIZZLE_ ##SWIZ_B, VK_COMPONENT_SWIZZLE_ ##SWIZ_A }, \
"VK_FORMAT_" #VK_FMT, false }
@@ -2094,33 +2108,33 @@
}
// Enumeration of Vulkan format features aligned to the MVKMTLFmtCaps enumeration.
-typedef enum : VkFormatFeatureFlags {
+typedef enum : VkFormatFeatureFlags2 {
kMVKVkFormatFeatureFlagsTexNone = 0,
- kMVKVkFormatFeatureFlagsTexRead = (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
- VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
- VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
- VK_FORMAT_FEATURE_BLIT_SRC_BIT),
- kMVKVkFormatFeatureFlagsTexFilter = (VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT),
- kMVKVkFormatFeatureFlagsTexWrite = (VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT),
- kMVKVkFormatFeatureFlagsTexAtomic = (VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT),
- kMVKVkFormatFeatureFlagsTexColorAtt = (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
- VK_FORMAT_FEATURE_BLIT_DST_BIT),
- kMVKVkFormatFeatureFlagsTexDSAtt = (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
- VK_FORMAT_FEATURE_BLIT_DST_BIT),
- kMVKVkFormatFeatureFlagsTexBlend = (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT),
- kMVKVkFormatFeatureFlagsTexTransfer = (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
- VK_FORMAT_FEATURE_TRANSFER_DST_BIT),
- kMVKVkFormatFeatureFlagsTexChromaSubsampling = (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR |
- VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR),
- kMVKVkFormatFeatureFlagsTexMultiPlanar = (VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR |
- VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR |
- VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR |
- VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR |
- VK_FORMAT_FEATURE_DISJOINT_BIT_KHR),
- kMVKVkFormatFeatureFlagsBufRead = (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT),
- kMVKVkFormatFeatureFlagsBufWrite = (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT),
- kMVKVkFormatFeatureFlagsBufAtomic = (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT),
- kMVKVkFormatFeatureFlagsBufVertex = (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT),
+ kMVKVkFormatFeatureFlagsTexRead = (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
+ VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
+ VK_FORMAT_FEATURE_2_BLIT_SRC_BIT),
+ kMVKVkFormatFeatureFlagsTexFilter = (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT),
+ kMVKVkFormatFeatureFlagsTexWrite = (VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT),
+ kMVKVkFormatFeatureFlagsTexAtomic = (VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT),
+ kMVKVkFormatFeatureFlagsTexColorAtt = (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_2_BLIT_DST_BIT),
+ kMVKVkFormatFeatureFlagsTexDSAtt = (VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_2_BLIT_DST_BIT),
+ kMVKVkFormatFeatureFlagsTexBlend = (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT),
+ kMVKVkFormatFeatureFlagsTexTransfer = (VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
+ VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT),
+ kMVKVkFormatFeatureFlagsTexChromaSubsampling = (VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR |
+ VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR),
+ kMVKVkFormatFeatureFlagsTexMultiPlanar = (VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR |
+ VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR |
+ VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR |
+ VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR |
+ VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR),
+ kMVKVkFormatFeatureFlagsBufRead = (VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT),
+ kMVKVkFormatFeatureFlagsBufWrite = (VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT),
+ kMVKVkFormatFeatureFlagsBufAtomic = (VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT),
+ kMVKVkFormatFeatureFlagsBufVertex = (VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT),
} MVKVkFormatFeatureFlags;
// Sets the VkFormatProperties (optimal/linear/buffer) for the Vulkan format.
@@ -2131,7 +2145,7 @@
mvkEnableFlags(VK_FEATS, kMVKVkFormatFeatureFlags ##TYPE ##CAP); \
}
- VkFormatProperties& vkProps = vkDesc.properties;
+ VkFormatProperties3& vkProps = vkDesc.properties;
MVKMTLFmtCaps mtlPixFmtCaps = getMTLPixelFormatDesc(vkDesc.mtlPixelFormat).mtlFmtCaps;
vkProps.optimalTilingFeatures = kMVKVkFormatFeatureFlagsTexNone;
vkProps.linearTilingFeatures = kMVKVkFormatFeatureFlagsTexNone;
@@ -2178,7 +2192,7 @@
// Vulkan forbids blits between chroma-subsampled formats.
// If we can't write the stencil reference from the shader, we can't blit stencil.
if (chromaSubsamplingComponentBits > 0 || (isStencilFormat(vkDesc.mtlPixelFormat) && !supportsStencilFeedback)) {
- mvkDisableFlags(vkProps.optimalTilingFeatures, (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT));
+ mvkDisableFlags(vkProps.optimalTilingFeatures, (VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT));
}
// These formats require swizzling. In order to support rendering, we'll have to swizzle
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
index 3385594..7279665 100644
--- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
@@ -64,6 +64,7 @@
MVK_EXTENSION(KHR_external_semaphore, KHR_EXTERNAL_SEMAPHORE, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(KHR_external_semaphore_capabilities, KHR_EXTERNAL_SEMAPHORE_CAPABILITIES, INSTANCE, 10.11, 8.0, 1.0)
MVK_EXTENSION(KHR_fragment_shader_barycentric, KHR_FRAGMENT_SHADER_BARYCENTRIC, DEVICE, 10.15, 14.0, 1.0)
+MVK_EXTENSION(KHR_format_feature_flags2, KHR_FORMAT_FEATURE_FLAGS_2, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(KHR_get_memory_requirements2, KHR_GET_MEMORY_REQUIREMENTS_2, DEVICE, 10.11, 8.0, 1.0)
MVK_EXTENSION(KHR_get_physical_device_properties2, KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2, INSTANCE, 10.11, 8.0, 1.0)
MVK_EXTENSION(KHR_get_surface_capabilities2, KHR_GET_SURFACE_CAPABILITIES_2, INSTANCE, 10.11, 8.0, 1.0)