Merge pull request #1697 from billhollings/optional-vk12-extn-hooks

Add hooks for optional but currently unsupported Vulkan 1.2 extensions.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index bd42b74..e39a981 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -117,12 +117,12 @@
 		.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
 		.pNext = nullptr,
 		.samplerMirrorClampToEdge = _metalFeatures.samplerMirrorClampToEdge,
-		.drawIndirectCount = false,									// VK_KHR_draw_indirect_count
+		.drawIndirectCount = false,
 		.storageBuffer8BitAccess = true,
 		.uniformAndStorageBuffer8BitAccess = true,
 		.storagePushConstant8 = true,
-		.shaderBufferInt64Atomics = false,							// VK_KHR_shader_atomic_int64
-		.shaderSharedInt64Atomics = false,							// VK_KHR_shader_atomic_int64
+		.shaderBufferInt64Atomics = false,
+		.shaderSharedInt64Atomics = false,
 		.shaderFloat16 = true,
 		.shaderInt8 = true,
 		.descriptorIndexing = false,		// Requires _metalFeatures.arrayOfTextures && _metalFeatures.arrayOfSamplers && shaderStorageBufferArrayNonUniformIndexing
@@ -146,7 +146,7 @@
 		.descriptorBindingPartiallyBound = true,
 		.descriptorBindingVariableDescriptorCount = true,
 		.runtimeDescriptorArray = true,
-		.samplerFilterMinmax = false,								// VK_EXT_sampler_filter_minmax
+		.samplerFilterMinmax = false,
 		.scalarBlockLayout = true,
 		.imagelessFramebuffer = true,
 		.uniformBufferStandardLayout = true,
@@ -157,9 +157,9 @@
 		.bufferDeviceAddress = mvkOSVersionIsAtLeast(12.05, 16.0),
 		.bufferDeviceAddressCaptureReplay = false,
 		.bufferDeviceAddressMultiDevice = false,
-		.vulkanMemoryModel = false,									// VK_KHR_vulkan_memory_model
-		.vulkanMemoryModelDeviceScope = false,						// VK_KHR_vulkan_memory_model
-		.vulkanMemoryModelAvailabilityVisibilityChains = false,		// VK_KHR_vulkan_memory_model
+		.vulkanMemoryModel = false,
+		.vulkanMemoryModelDeviceScope = false,
+		.vulkanMemoryModelAvailabilityVisibilityChains = false,
 		.shaderOutputViewportIndex = true,
 		.shaderOutputLayer = true,
 		.subgroupBroadcastDynamicId = true,
@@ -295,6 +295,12 @@
 				shaderDrawParamsFeatures->shaderDrawParameters = supportedFeats11.shaderDrawParameters;
 				break;
 			}
+			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES: {
+				auto* i64Features = (VkPhysicalDeviceShaderAtomicInt64Features*)next;
+				i64Features->shaderBufferInt64Atomics = supportedFeats12.shaderBufferInt64Atomics;
+				i64Features->shaderSharedInt64Atomics = supportedFeats12.shaderSharedInt64Atomics;
+				break;
+			}
 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: {
 				auto* f16Features = (VkPhysicalDeviceShaderFloat16Int8Features*)next;
 				f16Features->shaderFloat16 = supportedFeats12.shaderFloat16;
@@ -333,6 +339,13 @@
 				varPtrFeatures->variablePointers = supportedFeats11.variablePointers;
 				break;
 			}
+			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES: {
+				auto* vmmFeatures = (VkPhysicalDeviceVulkanMemoryModelFeatures*)next;
+				vmmFeatures->vulkanMemoryModel = supportedFeats12.vulkanMemoryModel;
+				vmmFeatures->vulkanMemoryModelDeviceScope = supportedFeats12.vulkanMemoryModelDeviceScope;
+				vmmFeatures->vulkanMemoryModelAvailabilityVisibilityChains = supportedFeats12.vulkanMemoryModelAvailabilityVisibilityChains;
+				break;
+			}
 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR: {
 				auto* barycentricFeatures = (VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR*)next;
 				barycentricFeatures->fragmentShaderBarycentric = true;
@@ -475,8 +488,8 @@
 	supportedProps12.supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;	// Metal allows you to set the stencil resolve filter to either Sample0 or the same sample used for depth resolve. This is impossible to express in Vulkan.
 	supportedProps12.independentResolveNone = true;
 	supportedProps12.independentResolve = true;
-	supportedProps12.filterMinmaxSingleComponentFormats = false;			// VK_EXT_sampler_filter_minmax;
-	supportedProps12.filterMinmaxImageComponentMapping = false;				// VK_EXT_sampler_filter_minmax;
+	supportedProps12.filterMinmaxSingleComponentFormats = false;
+	supportedProps12.filterMinmaxImageComponentMapping = false;
 	supportedProps12.maxTimelineSemaphoreValueDifference = std::numeric_limits<uint64_t>::max();
 	supportedProps12.framebufferIntegerColorSampleCounts = _metalFeatures.supportedSampleCounts;
 
@@ -554,6 +567,12 @@
 				physicalDeviceDriverProps->conformanceVersion = supportedProps12.conformanceVersion;
 				break;
 			}
+			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES: {
+				auto* sfmmProps = (VkPhysicalDeviceSamplerFilterMinmaxProperties*)next;
+				sfmmProps->filterMinmaxSingleComponentFormats = supportedProps12.filterMinmaxSingleComponentFormats;
+				sfmmProps->filterMinmaxImageComponentMapping = supportedProps12.filterMinmaxImageComponentMapping;
+				break;
+			}
 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES: {
                 auto* timelineSem4Props = (VkPhysicalDeviceTimelineSemaphoreProperties*)next;
                 timelineSem4Props->maxTimelineSemaphoreValueDifference = supportedProps12.maxTimelineSemaphoreValueDifference;
@@ -4509,9 +4528,9 @@
 				enableFeatures(&_enabled8BitStorageFeatures.storageBuffer8BitAccess,
 							   &requestedFeatures->storageBuffer8BitAccess,
 							   &pd8BitStorageFeatures.storageBuffer8BitAccess, 3);
-//				enableFeatures(&_enabledShaderAtomicInt64Features.shaderBufferInt64Atomics,		//VK_KHR_shader_atomic_int64
-//							   &requestedFeatures->shaderBufferInt64Atomics,
-//							   &pdShaderAtomicInt64Features.shaderBufferInt64Atomics, 2);
+				enableFeatures(&_enabledShaderAtomicInt64Features.shaderBufferInt64Atomics,
+							   &requestedFeatures->shaderBufferInt64Atomics,
+							   &pdShaderAtomicInt64Features.shaderBufferInt64Atomics, 2);
 				enableFeatures(&_enabledShaderFloat16Int8Features.shaderFloat16,
 							   &requestedFeatures->shaderFloat16,
 							   &pdShaderFloat16Int8Features.shaderFloat16, 2);
@@ -4542,9 +4561,9 @@
 				enableFeatures(&_enabledBufferDeviceAddressFeatures.bufferDeviceAddress,
 							   &requestedFeatures->bufferDeviceAddress,
 							   &pdBufferDeviceAddressFeatures.bufferDeviceAddress, 3);
-//				enableFeatures(&_enabledVulkanMemoryModelFeatures.vulkanMemoryModel,		// VK_KHR_vulkan_memory_model
-//							   &requestedFeatures->vulkanMemoryModel,
-//							   &pdVulkanMemoryModelFeatures.vulkanMemoryModel, 3);
+				enableFeatures(&_enabledVulkanMemoryModelFeatures.vulkanMemoryModel,
+							   &requestedFeatures->vulkanMemoryModel,
+							   &pdVulkanMemoryModelFeatures.vulkanMemoryModel, 3);
 				break;
 			}
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def
index dba229d..3235a20 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def
@@ -51,6 +51,7 @@
 MVK_DEVICE_FEATURE(ScalarBlockLayout,              SCALAR_BLOCK_LAYOUT,                1)
 MVK_DEVICE_FEATURE(SeparateDepthStencilLayouts,    SEPARATE_DEPTH_STENCIL_LAYOUTS,     1)
 MVK_DEVICE_FEATURE(ShaderDrawParameters,           SHADER_DRAW_PARAMETERS,             1)
+MVK_DEVICE_FEATURE(ShaderAtomicInt64,              SHADER_ATOMIC_INT64,                2)
 MVK_DEVICE_FEATURE(ShaderFloat16Int8,              SHADER_FLOAT16_INT8,                2)
 MVK_DEVICE_FEATURE(ShaderSubgroupExtendedTypes,    SHADER_SUBGROUP_EXTENDED_TYPES,     1)
 MVK_DEVICE_FEATURE(SubgroupSizeControl,            SUBGROUP_SIZE_CONTROL,              2)
@@ -58,6 +59,7 @@
 MVK_DEVICE_FEATURE(TimelineSemaphore,              TIMELINE_SEMAPHORE,                 1)
 MVK_DEVICE_FEATURE(UniformBufferStandardLayout,    UNIFORM_BUFFER_STANDARD_LAYOUT,     1)
 MVK_DEVICE_FEATURE(VariablePointer,                VARIABLE_POINTER,                   2)
+MVK_DEVICE_FEATURE(VulkanMemoryModel,              VULKAN_MEMORY_MODEL,                3)
 MVK_DEVICE_FEATURE_EXTN(FragmentShaderBarycentric, FRAGMENT_SHADER_BARYCENTRIC, KHR,   1)
 MVK_DEVICE_FEATURE_EXTN(PortabilitySubset,         PORTABILITY_SUBSET,          KHR,  15)
 MVK_DEVICE_FEATURE_EXTN(FragmentShaderInterlock,   FRAGMENT_SHADER_INTERLOCK,   EXT,   3)
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index dc85fd4..3304235 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -2076,6 +2076,7 @@
 
 MVKSampler::MVKSampler(MVKDevice* device, const VkSamplerCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
     _ycbcrConversion = NULL;
+	const VkSamplerReductionModeCreateInfo* pSampReductInfo = nullptr;
     for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
 		switch (next->sType) {
 			case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR: {
@@ -2083,6 +2084,10 @@
 				_ycbcrConversion = (MVKSamplerYcbcrConversion*)(sampConvInfo->conversion);
 				break;
 			}
+			case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO: {
+				pSampReductInfo = (const VkSamplerReductionModeCreateInfo*)next;
+				break;
+			}
 			default:
 				break;
 		}
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
index 5192947..0e78c86 100644
--- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
@@ -51,6 +51,7 @@
 MVK_EXTENSION(KHR_descriptor_update_template,      KHR_DESCRIPTOR_UPDATE_TEMPLATE,       DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_device_group,                    KHR_DEVICE_GROUP,                     DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_device_group_creation,           KHR_DEVICE_GROUP_CREATION,            INSTANCE, 10.11,  8.0)
+MVK_EXTENSION(KHR_draw_indirect_count,             KHR_DRAW_INDIRECT_COUNT,              DEVICE,   MVK_NA, MVK_NA)
 MVK_EXTENSION(KHR_driver_properties,               KHR_DRIVER_PROPERTIES,                DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_dynamic_rendering,               KHR_DYNAMIC_RENDERING,                DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_external_fence,                  KHR_EXTERNAL_FENCE,                   DEVICE,   10.11,  8.0)
@@ -75,6 +76,7 @@
 MVK_EXTENSION(KHR_sampler_mirror_clamp_to_edge,    KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE,     DEVICE,   10.11, 14.0)
 MVK_EXTENSION(KHR_sampler_ycbcr_conversion,        KHR_SAMPLER_YCBCR_CONVERSION,         DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_separate_depth_stencil_layouts,  KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS,   DEVICE,   10.11,  8.0)
+MVK_EXTENSION(KHR_shader_atomic_int64,             KHR_SHADER_ATOMIC_INT64,              DEVICE,   MVK_NA, MVK_NA)
 MVK_EXTENSION(KHR_shader_draw_parameters,          KHR_SHADER_DRAW_PARAMETERS,           DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_shader_float_controls,           KHR_SHADER_FLOAT_CONTROLS,            DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_shader_float16_int8,             KHR_SHADER_FLOAT16_INT8,              DEVICE,   10.11,  8.0)
@@ -86,6 +88,7 @@
 MVK_EXTENSION(KHR_timeline_semaphore,              KHR_TIMELINE_SEMAPHORE,               DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_uniform_buffer_standard_layout,  KHR_UNIFORM_BUFFER_STANDARD_LAYOUT,   DEVICE,   10.11,  8.0)
 MVK_EXTENSION(KHR_variable_pointers,               KHR_VARIABLE_POINTERS,                DEVICE,   10.11,  8.0)
+MVK_EXTENSION(KHR_vulkan_memory_model,             KHR_VULKAN_MEMORY_MODEL,              DEVICE,   MVK_NA, MVK_NA)
 MVK_EXTENSION(EXT_buffer_device_address,           EXT_BUFFER_DEVICE_ADDRESS,            DEVICE,   12.05,  16.0)
 MVK_EXTENSION(EXT_debug_marker,                    EXT_DEBUG_MARKER,                     DEVICE,   10.11,  8.0)
 MVK_EXTENSION(EXT_debug_report,                    EXT_DEBUG_REPORT,                     INSTANCE, 10.11,  8.0)
@@ -103,6 +106,7 @@
 MVK_EXTENSION(EXT_private_data,                    EXT_PRIVATE_DATA,                     DEVICE,   10.11,  8.0)
 MVK_EXTENSION(EXT_robustness2,                     EXT_ROBUSTNESS_2,                     DEVICE,   10.11,  8.0)
 MVK_EXTENSION(EXT_sample_locations,                EXT_SAMPLE_LOCATIONS,                 DEVICE,   10.13, 11.0)
+MVK_EXTENSION(EXT_sampler_filter_minmax,           EXT_SAMPLER_FILTER_MINMAX,            DEVICE,   MVK_NA, MVK_NA)
 MVK_EXTENSION(EXT_scalar_block_layout,             EXT_SCALAR_BLOCK_LAYOUT,              DEVICE,   10.11,  8.0)
 MVK_EXTENSION(EXT_separate_stencil_usage,          EXT_SEPARATE_STENCIL_USAGE,           DEVICE,   10.11,  8.0)
 MVK_EXTENSION(EXT_shader_stencil_export,           EXT_SHADER_STENCIL_EXPORT,            DEVICE,   10.14, 12.0)
@@ -112,6 +116,7 @@
 MVK_EXTENSION(EXT_texel_buffer_alignment,          EXT_TEXEL_BUFFER_ALIGNMENT,           DEVICE,   10.13, 11.0)
 MVK_EXTENSION(EXT_texture_compression_astc_hdr,    EXT_TEXTURE_COMPRESSION_ASTC_HDR,     DEVICE,   11.0,  13.0)
 MVK_EXTENSION(EXT_vertex_attribute_divisor,        EXT_VERTEX_ATTRIBUTE_DIVISOR,         DEVICE,   10.11,  8.0)
+MVK_EXTENSION(AMD_draw_indirect_count,             AMD_DRAW_INDIRECT_COUNT,              DEVICE,   MVK_NA, MVK_NA)
 MVK_EXTENSION(AMD_gpu_shader_half_float,           AMD_GPU_SHADER_HALF_FLOAT,            DEVICE,   10.11,  8.0)
 MVK_EXTENSION(AMD_negative_viewport_height,        AMD_NEGATIVE_VIEWPORT_HEIGHT,         DEVICE,   10.11,  8.0)
 MVK_EXTENSION(AMD_shader_image_load_store_lod,     AMD_SHADER_IMAGE_LOAD_STORE_LOD,      DEVICE,   11.0,   8.0)