Merge pull request #1674 from billhollings/device-feature-tracking-enhancements
MVKDevice consolidate enabling device feature tracking.
diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
index c8899d5..cda7856 100644
--- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
+++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj
@@ -201,7 +201,6 @@
A94FB7E21C7DFB4800632CA3 /* MVKDescriptorSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7821C7DFB4800632CA3 /* MVKDescriptorSet.mm */; };
A94FB7E31C7DFB4800632CA3 /* MVKDescriptorSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7821C7DFB4800632CA3 /* MVKDescriptorSet.mm */; };
A94FB7E41C7DFB4800632CA3 /* MVKDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7831C7DFB4800632CA3 /* MVKDevice.h */; };
- A94FB7E51C7DFB4800632CA3 /* MVKDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7831C7DFB4800632CA3 /* MVKDevice.h */; };
A94FB7E61C7DFB4800632CA3 /* MVKDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7841C7DFB4800632CA3 /* MVKDevice.mm */; };
A94FB7E71C7DFB4800632CA3 /* MVKDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7841C7DFB4800632CA3 /* MVKDevice.mm */; };
A94FB7E81C7DFB4800632CA3 /* MVKDeviceMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7851C7DFB4800632CA3 /* MVKDeviceMemory.h */; };
@@ -304,6 +303,10 @@
A98149641FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h in Headers */ = {isa = PBXBuildFile; fileRef = A981494C1FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h */; };
A981496B1FB6A998005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A981496A1FB6A998005F00B4 /* MVKStrings.h */; };
A981496C1FB6A998005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A981496A1FB6A998005F00B4 /* MVKStrings.h */; };
+ A987B668289AFB6100F933C8 /* MVKDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7831C7DFB4800632CA3 /* MVKDevice.h */; };
+ A987B669289AFB8A00F933C8 /* MVKDeviceFeatureStructs.def in Headers */ = {isa = PBXBuildFile; fileRef = A987B666289AFB2400F933C8 /* MVKDeviceFeatureStructs.def */; };
+ A987B66A289AFB8B00F933C8 /* MVKDeviceFeatureStructs.def in Headers */ = {isa = PBXBuildFile; fileRef = A987B666289AFB2400F933C8 /* MVKDeviceFeatureStructs.def */; };
+ A987B66B289AFB8C00F933C8 /* MVKDeviceFeatureStructs.def in Headers */ = {isa = PBXBuildFile; fileRef = A987B666289AFB2400F933C8 /* MVKDeviceFeatureStructs.def */; };
A99C90EE229455B300A061DA /* MVKCmdDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = A99C90EC229455B200A061DA /* MVKCmdDebug.h */; };
A99C90EF229455B300A061DA /* MVKCmdDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = A99C90EC229455B200A061DA /* MVKCmdDebug.h */; };
A99C90F0229455B300A061DA /* MVKCmdDebug.mm in Sources */ = {isa = PBXBuildFile; fileRef = A99C90ED229455B300A061DA /* MVKCmdDebug.mm */; };
@@ -511,6 +514,7 @@
A981494B1FB6A3F7005F00B4 /* MVKWatermarkShaderSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKWatermarkShaderSource.h; sourceTree = "<group>"; };
A981494C1FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKWatermarkTextureContent.h; sourceTree = "<group>"; };
A981496A1FB6A998005F00B4 /* MVKStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKStrings.h; sourceTree = "<group>"; };
+ A987B666289AFB2400F933C8 /* MVKDeviceFeatureStructs.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKDeviceFeatureStructs.def; sourceTree = "<group>"; };
A99C90EC229455B200A061DA /* MVKCmdDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdDebug.h; sourceTree = "<group>"; };
A99C90ED229455B300A061DA /* MVKCmdDebug.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDebug.mm; sourceTree = "<group>"; };
A99C91002295FAC500A061DA /* MVKVulkanAPIObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKVulkanAPIObject.mm; sourceTree = "<group>"; };
@@ -620,6 +624,7 @@
A94FB7821C7DFB4800632CA3 /* MVKDescriptorSet.mm */,
A94FB7831C7DFB4800632CA3 /* MVKDevice.h */,
A94FB7841C7DFB4800632CA3 /* MVKDevice.mm */,
+ A987B666289AFB2400F933C8 /* MVKDeviceFeatureStructs.def */,
A94FB7851C7DFB4800632CA3 /* MVKDeviceMemory.h */,
A94FB7861C7DFB4800632CA3 /* MVKDeviceMemory.mm */,
A94FB7871C7DFB4800632CA3 /* MVKFramebuffer.h */,
@@ -804,6 +809,7 @@
2FEA0A4C24902F9F00EEF3AD /* MVKCommandPipelineStateFactoryShaderSource.h in Headers */,
2FEA0A4D24902F9F00EEF3AD /* MVKDescriptorSet.h in Headers */,
2FEA0A4E24902F9F00EEF3AD /* NSString+MoltenVK.h in Headers */,
+ A987B66A289AFB8B00F933C8 /* MVKDeviceFeatureStructs.def in Headers */,
2FEA0A4F24902F9F00EEF3AD /* CAMetalLayer+MoltenVK.h in Headers */,
2FEA0A5024902F9F00EEF3AD /* MVKCodec.h in Headers */,
2FEA0A5124902F9F00EEF3AD /* MVKRenderPass.h in Headers */,
@@ -863,6 +869,7 @@
files = (
A909F65F213B190700FCD6BE /* MVKExtensions.h in Headers */,
A94FB7B41C7DFB4800632CA3 /* vk_mvk_moltenvk.h in Headers */,
+ A987B669289AFB8A00F933C8 /* MVKDeviceFeatureStructs.def in Headers */,
A94FB7B01C7DFB4800632CA3 /* mvk_datatypes.h in Headers */,
A948BB7F1E51642700DE59F2 /* mvk_vulkan.h in Headers */,
A98149511FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */,
@@ -936,6 +943,7 @@
files = (
A909F660213B190700FCD6BE /* MVKExtensions.h in Headers */,
A94FB7B51C7DFB4800632CA3 /* vk_mvk_moltenvk.h in Headers */,
+ A987B66B289AFB8C00F933C8 /* MVKDeviceFeatureStructs.def in Headers */,
A94FB7B11C7DFB4800632CA3 /* mvk_datatypes.h in Headers */,
A948BB801E51642700DE59F2 /* mvk_vulkan.h in Headers */,
A98149521FB6A3F7005F00B4 /* MVKEnvironment.h in Headers */,
@@ -959,7 +967,6 @@
A98149621FB6A3F7005F00B4 /* MVKWatermarkShaderSource.h in Headers */,
A9E53DE42100B197002781DD /* MTLSamplerDescriptor+MoltenVK.h in Headers */,
A94FB8191C7DFB4800632CA3 /* MVKSync.h in Headers */,
- A94FB7E51C7DFB4800632CA3 /* MVKDevice.h in Headers */,
A9F3D9DF24732A4D00745190 /* MVKSmallVector.h in Headers */,
A94FB7D51C7DFB4800632CA3 /* MVKCommandPool.h in Headers */,
A94FB80D1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */,
@@ -982,6 +989,7 @@
A94FB7F11C7DFB4800632CA3 /* MVKImage.h in Headers */,
4553AEFE2251617100E8EBCD /* MVKBlockObserver.h in Headers */,
A94FB7B91C7DFB4800632CA3 /* MVKCmdTransfer.h in Headers */,
+ A987B668289AFB6100F933C8 /* MVKDevice.h in Headers */,
A966A5E023C535D000BBF9B4 /* MVKDescriptor.h in Headers */,
A94FB7C91C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */,
A94FB7D11C7DFB4800632CA3 /* MVKCommandBuffer.h in Headers */,
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index ffd7838..70d6030 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -219,8 +219,8 @@
* it may cause unexpected visual artifacts and unnecessary GPU load.
*
* This feature is incompatible with updating descriptors after binding. If any of the
- * *UpdateAfterBind feature flags of VkPhysicalDeviceDescriptorIndexingFeaturesEXT or
- * VkPhysicalDeviceInlineUniformBlockFeaturesEXT have been enabled, the value of this
+ * *UpdateAfterBind feature flags of VkPhysicalDeviceDescriptorIndexingFeatures or
+ * VkPhysicalDeviceInlineUniformBlockFeatures have been enabled, the value of this
* setting will be ignored and treated as if it is false.
*
* The value of this parameter may be changed at any time during application runtime,
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index c55398b..7ada59a 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -773,31 +773,17 @@
#pragma mark Properties directly accessible
/** The list of Vulkan extensions, indicating whether each has been enabled by the app for this device. */
- const MVKExtensionList _enabledExtensions;
+ MVKExtensionList _enabledExtensions;
/** Device features available and enabled. */
- const VkPhysicalDeviceFeatures _enabledFeatures;
- const VkPhysicalDevice16BitStorageFeatures _enabledStorage16Features;
- const VkPhysicalDevice8BitStorageFeaturesKHR _enabledStorage8Features;
- const VkPhysicalDeviceFloat16Int8FeaturesKHR _enabledF16I8Features;
- const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR _enabledUBOLayoutFeatures;
- const VkPhysicalDeviceVariablePointerFeatures _enabledVarPtrFeatures;
- const VkPhysicalDeviceDescriptorIndexingFeaturesEXT _enabledDescriptorIndexingFeatures;
- const VkPhysicalDeviceInlineUniformBlockFeaturesEXT _enabledInlineUniformBlockFeatures;
- const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT _enabledInterlockFeatures;
- const VkPhysicalDeviceHostQueryResetFeaturesEXT _enabledHostQryResetFeatures;
- const VkPhysicalDeviceSamplerYcbcrConversionFeatures _enabledSamplerYcbcrConversionFeatures;
- const VkPhysicalDevicePrivateDataFeaturesEXT _enabledPrivateDataFeatures;
- const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT _enabledScalarLayoutFeatures;
- const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT _enabledTexelBuffAlignFeatures;
- const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT _enabledVtxAttrDivFeatures;
- const VkPhysicalDevicePortabilitySubsetFeaturesKHR _enabledPortabilityFeatures;
- const VkPhysicalDeviceImagelessFramebufferFeaturesKHR _enabledImagelessFramebufferFeatures;
- const VkPhysicalDeviceDynamicRenderingFeatures _enabledDynamicRenderingFeatures;
- const VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures _enabledSeparateDepthStencilLayoutsFeatures;
- const VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR _enabledFragmentShaderBarycentricFeatures;
- const VkPhysicalDeviceBufferDeviceAddressFeatures _enabledBufferDeviceAddressFeatures;
- const VkPhysicalDeviceBufferDeviceAddressFeaturesEXT _enabledBufferDeviceAddressFeaturesEXT;
+ VkPhysicalDeviceFeatures _enabledFeatures;
+
+ // List of extended device feature enabling structures, as public member variables.
+#define MVK_DEVICE_FEATURE(structName, enumName, flagCount) \
+ VkPhysicalDevice##structName##Features _enabled##structName##Features;
+#define MVK_DEVICE_FEATURE_EXTN(structName, enumName, extnSfx, flagCount) \
+ VkPhysicalDevice##structName##Features##extnSfx _enabled##structName##Features;
+#include "MVKDeviceFeatureStructs.def"
/** Pointer to the Metal-specific features of the underlying physical device. */
const MVKPhysicalDeviceMetalFeatures* _pMetalFeatures;
@@ -852,7 +838,8 @@
void initQueues(const VkDeviceCreateInfo* pCreateInfo);
void reservePrivateData(const VkDeviceCreateInfo* pCreateInfo);
void enableFeatures(const VkDeviceCreateInfo* pCreateInfo);
- void enableFeatures(const VkBool32* pEnable, const VkBool32* pRequested, const VkBool32* pAvailable, uint32_t count);
+ void enableFeatures(VkBaseInStructure* pEnabled, const VkBaseInStructure* pRequested, const VkBaseInStructure* pAvailable, uint32_t count);
+ void enableFeatures(VkBool32* pEnabledBools, const VkBool32* pRequestedBools, const VkBool32* pAvailableBools, uint32_t count);
void enableExtensions(const VkDeviceCreateInfo* pCreateInfo);
const char* getActivityPerformanceDescription(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats);
void logActivityPerformance(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats, bool isInline = false);
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 539a569..30a49d5 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -97,6 +97,8 @@
features->features = _features;
for (auto* next = (VkBaseOutStructure*)features->pNext; next; next = next->pNext) {
switch ((uint32_t)next->sType) {
+
+ // For consistency and ease of admin, keep the following list in the same order as in MVKDeviceFeatureStructs.def
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
auto* storageFeatures = (VkPhysicalDevice16BitStorageFeatures*)next;
storageFeatures->storageBuffer16BitAccess = true;
@@ -105,64 +107,23 @@
storageFeatures->storageInputOutput16 = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
- auto* storageFeatures = (VkPhysicalDevice8BitStorageFeaturesKHR*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES: {
+ auto* storageFeatures = (VkPhysicalDevice8BitStorageFeatures*)next;
storageFeatures->storageBuffer8BitAccess = true;
storageFeatures->uniformAndStorageBuffer8BitAccess = true;
storageFeatures->storagePushConstant8 = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
- auto* f16Features = (VkPhysicalDeviceFloat16Int8FeaturesKHR*)next;
- f16Features->shaderFloat16 = true;
- f16Features->shaderInt8 = true;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: {
+ auto* bufferDeviceAddressFeatures = (VkPhysicalDeviceBufferDeviceAddressFeatures*)next;
+ bufferDeviceAddressFeatures->bufferDeviceAddress = mvkOSVersionIsAtLeast(12.05, 16.0);
+ bufferDeviceAddressFeatures->bufferDeviceAddressCaptureReplay = false;
+ bufferDeviceAddressFeatures->bufferDeviceAddressMultiDevice = false;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
- auto* multiviewFeatures = (VkPhysicalDeviceMultiviewFeatures*)next;
- multiviewFeatures->multiview = true;
- multiviewFeatures->multiviewGeometryShader = false;
- multiviewFeatures->multiviewTessellationShader = false; // FIXME
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
- auto* protectedMemFeatures = (VkPhysicalDeviceProtectedMemoryFeatures*)next;
- protectedMemFeatures->protectedMemory = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
- auto* samplerYcbcrConvFeatures = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)next;
- samplerYcbcrConvFeatures->samplerYcbcrConversion = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
- auto* shaderDrawParamsFeatures = (VkPhysicalDeviceShaderDrawParametersFeatures*)next;
- shaderDrawParamsFeatures->shaderDrawParameters = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES: {
- auto* shaderSGTypesFeatures = (VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures*)next;
- shaderSGTypesFeatures->shaderSubgroupExtendedTypes = _metalFeatures.simdPermute || _metalFeatures.quadPermute;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES: {
- auto* timelineSem4Features = (VkPhysicalDeviceTimelineSemaphoreFeatures*)next;
- timelineSem4Features->timelineSemaphore = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
- auto* uboLayoutFeatures = (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR*)next;
- uboLayoutFeatures->uniformBufferStandardLayout = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
- auto* varPtrFeatures = (VkPhysicalDeviceVariablePointerFeatures*)next;
- varPtrFeatures->variablePointersStorageBuffer = true;
- varPtrFeatures->variablePointers = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
- auto* pDescIdxFeatures = (VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES: {
+ auto* pDescIdxFeatures = (VkPhysicalDeviceDescriptorIndexingFeatures*)next;
pDescIdxFeatures->shaderInputAttachmentArrayDynamicIndexing = _metalFeatures.arrayOfTextures;
pDescIdxFeatures->shaderUniformTexelBufferArrayDynamicIndexing = _metalFeatures.arrayOfTextures;
pDescIdxFeatures->shaderStorageTexelBufferArrayDynamicIndexing = _metalFeatures.arrayOfTextures;
@@ -185,60 +146,110 @@
pDescIdxFeatures->runtimeDescriptorArray = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
- auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
- interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
- interlockFeatures->fragmentShaderPixelInterlock = _metalFeatures.rasterOrderGroups;
- interlockFeatures->fragmentShaderShadingRateInterlock = false; // Requires variable rate shading; not supported yet in Metal
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES: {
+ auto* dynamicRenderingFeatures = (VkPhysicalDeviceDynamicRenderingFeatures*)next;
+ dynamicRenderingFeatures->dynamicRendering = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
- auto* hostQueryResetFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES: {
+ auto* hostQueryResetFeatures = (VkPhysicalDeviceHostQueryResetFeatures*)next;
hostQueryResetFeatures->hostQueryReset = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT: {
- auto *imageRobustnessFeatures = (VkPhysicalDeviceImageRobustnessFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {
+ auto* imagelessFramebufferFeatures = (VkPhysicalDeviceImagelessFramebufferFeatures*)next;
+ imagelessFramebufferFeatures->imagelessFramebuffer = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES: {
+ auto *imageRobustnessFeatures = (VkPhysicalDeviceImageRobustnessFeatures*)next;
imageRobustnessFeatures->robustImageAccess = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
- auto* privateDataFeatures = (VkPhysicalDevicePrivateDataFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES: {
+ auto* inlineUniformBlockFeatures = (VkPhysicalDeviceInlineUniformBlockFeatures*)next;
+ inlineUniformBlockFeatures->inlineUniformBlock = true;
+ inlineUniformBlockFeatures->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
+ auto* multiviewFeatures = (VkPhysicalDeviceMultiviewFeatures*)next;
+ multiviewFeatures->multiview = true;
+ multiviewFeatures->multiviewGeometryShader = false;
+ multiviewFeatures->multiviewTessellationShader = false; // FIXME
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES: {
+ auto* privateDataFeatures = (VkPhysicalDevicePrivateDataFeatures*)next;
privateDataFeatures->privateData = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
- auto* robustness2Features = (VkPhysicalDeviceRobustness2FeaturesEXT*)next;
- robustness2Features->robustBufferAccess2 = false;
- robustness2Features->robustImageAccess2 = true;
- robustness2Features->nullDescriptor = false;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
+ auto* protectedMemFeatures = (VkPhysicalDeviceProtectedMemoryFeatures*)next;
+ protectedMemFeatures->protectedMemory = false;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
- auto* scalarLayoutFeatures = (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
+ auto* samplerYcbcrConvFeatures = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)next;
+ samplerYcbcrConvFeatures->samplerYcbcrConversion = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES: {
+ auto* scalarLayoutFeatures = (VkPhysicalDeviceScalarBlockLayoutFeatures*)next;
scalarLayoutFeatures->scalarBlockLayout = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT: {
- auto* subgroupSizeFeatures = (VkPhysicalDeviceSubgroupSizeControlFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES: {
+ auto* separateDepthStencilLayoutsFeatures = (VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures*)next;
+ separateDepthStencilLayoutsFeatures->separateDepthStencilLayouts = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
+ auto* shaderDrawParamsFeatures = (VkPhysicalDeviceShaderDrawParametersFeatures*)next;
+ shaderDrawParamsFeatures->shaderDrawParameters = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: {
+ auto* f16Features = (VkPhysicalDeviceShaderFloat16Int8Features*)next;
+ f16Features->shaderFloat16 = true;
+ f16Features->shaderInt8 = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES: {
+ auto* shaderSGTypesFeatures = (VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures*)next;
+ shaderSGTypesFeatures->shaderSubgroupExtendedTypes = _metalFeatures.simdPermute || _metalFeatures.quadPermute;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES: {
+ auto* subgroupSizeFeatures = (VkPhysicalDeviceSubgroupSizeControlFeatures*)next;
subgroupSizeFeatures->subgroupSizeControl = _metalFeatures.simdPermute || _metalFeatures.quadPermute;
subgroupSizeFeatures->computeFullSubgroups = _metalFeatures.simdPermute || _metalFeatures.quadPermute;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
- auto* texelBuffAlignFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next;
- texelBuffAlignFeatures->texelBufferAlignment = _metalFeatures.texelBuffers && [_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)];
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT: {
- auto* astcHDRFeatures = (VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT*)next;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES: {
+ auto* astcHDRFeatures = (VkPhysicalDeviceTextureCompressionASTCHDRFeatures*)next;
astcHDRFeatures->textureCompressionASTC_HDR = _metalFeatures.astcHDRTextures;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
- auto* divisorFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next;
- divisorFeatures->vertexAttributeInstanceRateDivisor = true;
- divisorFeatures->vertexAttributeInstanceRateZeroDivisor = true;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES: {
+ auto* timelineSem4Features = (VkPhysicalDeviceTimelineSemaphoreFeatures*)next;
+ timelineSem4Features->timelineSemaphore = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES: {
+ auto* uboLayoutFeatures = (VkPhysicalDeviceUniformBufferStandardLayoutFeatures*)next;
+ uboLayoutFeatures->uniformBufferStandardLayout = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
+ auto* varPtrFeatures = (VkPhysicalDeviceVariablePointerFeatures*)next;
+ varPtrFeatures->variablePointersStorageBuffer = true;
+ varPtrFeatures->variablePointers = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR: {
+ auto* barycentricFeatures = (VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR*)next;
+ barycentricFeatures->fragmentShaderBarycentric = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR: {
@@ -261,50 +272,36 @@
portabilityFeatures->vertexAttributeAccessBeyondStride = true; // Costs additional buffers. Should make configuration switch.
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
+ auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
+ interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
+ interlockFeatures->fragmentShaderPixelInterlock = _metalFeatures.rasterOrderGroups;
+ interlockFeatures->fragmentShaderShadingRateInterlock = false; // Requires variable rate shading; not supported yet in Metal
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
+ auto* robustness2Features = (VkPhysicalDeviceRobustness2FeaturesEXT*)next;
+ robustness2Features->robustBufferAccess2 = false;
+ robustness2Features->robustImageAccess2 = true;
+ robustness2Features->nullDescriptor = false;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
+ auto* texelBuffAlignFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next;
+ texelBuffAlignFeatures->texelBufferAlignment = _metalFeatures.texelBuffers && [_mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)];
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
+ auto* divisorFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next;
+ divisorFeatures->vertexAttributeInstanceRateDivisor = true;
+ divisorFeatures->vertexAttributeInstanceRateZeroDivisor = true;
+ break;
+ }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL: {
auto* shaderIntFuncsFeatures = (VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL*)next;
shaderIntFuncsFeatures->shaderIntegerFunctions2 = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
- auto* inlineUniformBlockFeatures = (VkPhysicalDeviceInlineUniformBlockFeaturesEXT*)next;
- inlineUniformBlockFeatures->inlineUniformBlock = true;
- inlineUniformBlockFeatures->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {
- auto* imagelessFramebufferFeatures = (VkPhysicalDeviceImagelessFramebufferFeaturesKHR*)next;
- imagelessFramebufferFeatures->imagelessFramebuffer = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES: {
- auto* dynamicRenderingFeatures = (VkPhysicalDeviceDynamicRenderingFeatures*)next;
- dynamicRenderingFeatures->dynamicRendering = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES: {
- auto* separateDepthStencilLayoutsFeatures = (VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures*)next;
- separateDepthStencilLayoutsFeatures->separateDepthStencilLayouts = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR: {
- auto* barycentricFeatures = (VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR*)next;
- barycentricFeatures->fragmentShaderBarycentric = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES: {
- auto* bufferDeviceAddressFeatures = (VkPhysicalDeviceBufferDeviceAddressFeatures*)next;
- bufferDeviceAddressFeatures->bufferDeviceAddress = mvkOSVersionIsAtLeast(12.05, 16.0);
- bufferDeviceAddressFeatures->bufferDeviceAddressCaptureReplay = false;
- bufferDeviceAddressFeatures->bufferDeviceAddressMultiDevice = false;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: {
- auto* bufferDeviceAddressFeatures = (VkPhysicalDeviceBufferDeviceAddressFeaturesEXT*)next;
- bufferDeviceAddressFeatures->bufferDeviceAddress = mvkOSVersionIsAtLeast(12.05, 16.0);
- bufferDeviceAddressFeatures->bufferDeviceAddressCaptureReplay = false;
- bufferDeviceAddressFeatures->bufferDeviceAddressMultiDevice = false;
- break;
- }
default:
break;
}
@@ -4134,30 +4131,7 @@
#pragma mark Construction
-MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo* pCreateInfo) :
- _enabledExtensions(this),
- _enabledFeatures(),
- _enabledStorage16Features(),
- _enabledStorage8Features(),
- _enabledF16I8Features(),
- _enabledUBOLayoutFeatures(),
- _enabledVarPtrFeatures(),
- _enabledDescriptorIndexingFeatures(),
- _enabledInlineUniformBlockFeatures(),
- _enabledInterlockFeatures(),
- _enabledHostQryResetFeatures(),
- _enabledSamplerYcbcrConversionFeatures(),
- _enabledPrivateDataFeatures(),
- _enabledScalarLayoutFeatures(),
- _enabledTexelBuffAlignFeatures(),
- _enabledVtxAttrDivFeatures(),
- _enabledPortabilityFeatures(),
- _enabledImagelessFramebufferFeatures(),
- _enabledDynamicRenderingFeatures(),
- _enabledSeparateDepthStencilLayoutsFeatures(),
- _enabledFragmentShaderBarycentricFeatures(),
- _enabledBufferDeviceAddressFeatures(),
- _enabledBufferDeviceAddressFeaturesEXT() {
+MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo* pCreateInfo) : _enabledExtensions(this) {
// If the physical device is lost, bail.
if (physicalDevice->getConfigurationResult() != VK_SUCCESS) {
@@ -4265,123 +4239,42 @@
}
void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
+ VkStructureType sType;
+ VkBaseInStructure* pPrevStruct = nullptr;
- // Start with all features disabled
+ // Clear and set the sType of each VkDevice enabled feature iVar (_enabledXXXFeatures),
+ // and create a chain of identical structs that will be sent to the MVKPhysicalDevice
+ // to query which features are supported.
+#define MVK_DEVICE_FEATURE(structName, enumName, flagCount) \
+ sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES; \
+ mvkClear(&_enabled##structName##Features); \
+ _enabled##structName##Features.sType = sType; \
+ VkPhysicalDevice##structName##Features pd##structName##Features; \
+ pd##structName##Features.sType = sType; \
+ pd##structName##Features.pNext = pPrevStruct; \
+ pPrevStruct = (VkBaseInStructure*)&pd##structName##Features;
+
+#define MVK_DEVICE_FEATURE_EXTN(structName, enumName, extnSfx, flagCount) \
+ sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES_##extnSfx; \
+ mvkClear(&_enabled##structName##Features); \
+ _enabled##structName##Features.sType = sType; \
+ VkPhysicalDevice##structName##Features##extnSfx pd##structName##Features; \
+ pd##structName##Features.sType = sType; \
+ pd##structName##Features.pNext = pPrevStruct; \
+ pPrevStruct = (VkBaseInStructure*)&pd##structName##Features;
+
+#include "MVKDeviceFeatureStructs.def"
+
+ sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
mvkClear(&_enabledFeatures);
- mvkClear(&_enabledStorage16Features);
- mvkClear(&_enabledStorage8Features);
- mvkClear(&_enabledF16I8Features);
- mvkClear(&_enabledUBOLayoutFeatures);
- mvkClear(&_enabledVarPtrFeatures);
- mvkClear(&_enabledDescriptorIndexingFeatures);
- mvkClear(&_enabledInlineUniformBlockFeatures);
- mvkClear(&_enabledInterlockFeatures);
- mvkClear(&_enabledHostQryResetFeatures);
- mvkClear(&_enabledSamplerYcbcrConversionFeatures);
- mvkClear(&_enabledPrivateDataFeatures);
- mvkClear(&_enabledScalarLayoutFeatures);
- mvkClear(&_enabledTexelBuffAlignFeatures);
- mvkClear(&_enabledVtxAttrDivFeatures);
- mvkClear(&_enabledPortabilityFeatures);
- mvkClear(&_enabledImagelessFramebufferFeatures);
- mvkClear(&_enabledDynamicRenderingFeatures);
- mvkClear(&_enabledSeparateDepthStencilLayoutsFeatures);
- mvkClear(&_enabledFragmentShaderBarycentricFeatures);
- mvkClear(&_enabledBufferDeviceAddressFeatures);
- mvkClear(&_enabledBufferDeviceAddressFeaturesEXT);
-
- VkPhysicalDeviceBufferDeviceAddressFeaturesEXT pdBufferDeviceAddressFeaturesEXT;
- pdBufferDeviceAddressFeaturesEXT.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT;
- pdBufferDeviceAddressFeaturesEXT.pNext = nullptr;
-
- VkPhysicalDeviceBufferDeviceAddressFeatures pdBufferDeviceAddressFeatures;
- pdBufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
- pdBufferDeviceAddressFeatures.pNext = &pdBufferDeviceAddressFeaturesEXT;
-
- VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR pdFragmentShaderBarycentricFeatures;
- pdFragmentShaderBarycentricFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR;
- pdFragmentShaderBarycentricFeatures.pNext = &pdBufferDeviceAddressFeatures;
-
- VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures pdSeparateDepthStencilLayoutsFeatures;
- pdSeparateDepthStencilLayoutsFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES;
- pdSeparateDepthStencilLayoutsFeatures.pNext = &pdFragmentShaderBarycentricFeatures;
-
- VkPhysicalDeviceDynamicRenderingFeatures pdDynamicRenderingFeatures;
- pdDynamicRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES;
- pdDynamicRenderingFeatures.pNext = &pdSeparateDepthStencilLayoutsFeatures;
-
- VkPhysicalDeviceImagelessFramebufferFeaturesKHR pdImagelessFramebufferFeatures;
- pdImagelessFramebufferFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES;
- pdImagelessFramebufferFeatures.pNext = &pdDynamicRenderingFeatures;
-
- // Fetch the available physical device features.
- VkPhysicalDevicePortabilitySubsetFeaturesKHR pdPortabilityFeatures;
- pdPortabilityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR;
- pdPortabilityFeatures.pNext = &pdImagelessFramebufferFeatures;
-
- VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT pdVtxAttrDivFeatures;
- pdVtxAttrDivFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
- pdVtxAttrDivFeatures.pNext = &pdPortabilityFeatures;
-
- VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT pdTexelBuffAlignFeatures;
- pdTexelBuffAlignFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT;
- pdTexelBuffAlignFeatures.pNext = &pdVtxAttrDivFeatures;
-
- VkPhysicalDeviceScalarBlockLayoutFeaturesEXT pdScalarLayoutFeatures;
- pdScalarLayoutFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
- pdScalarLayoutFeatures.pNext = &pdTexelBuffAlignFeatures;
-
- VkPhysicalDevicePrivateDataFeaturesEXT pdPrivateDataFeatures;
- pdPrivateDataFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT;
- pdPrivateDataFeatures.pNext = &pdScalarLayoutFeatures;
-
- VkPhysicalDeviceSamplerYcbcrConversionFeatures pdSamplerYcbcrConversionFeatures;
- pdSamplerYcbcrConversionFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
- pdSamplerYcbcrConversionFeatures.pNext = &pdPrivateDataFeatures;
-
- VkPhysicalDeviceHostQueryResetFeaturesEXT pdHostQryResetFeatures;
- pdHostQryResetFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
- pdHostQryResetFeatures.pNext = &pdSamplerYcbcrConversionFeatures;
-
- VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT pdInterlockFeatures;
- pdInterlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT;
- pdInterlockFeatures.pNext = &pdHostQryResetFeatures;
-
- VkPhysicalDeviceInlineUniformBlockFeaturesEXT pdInlnUnfmBlkFeatures;
- pdInlnUnfmBlkFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT;
- pdInlnUnfmBlkFeatures.pNext = &pdInterlockFeatures;
-
- VkPhysicalDeviceDescriptorIndexingFeaturesEXT pdDescIdxFeatures;
- pdDescIdxFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
- pdDescIdxFeatures.pNext = &pdInlnUnfmBlkFeatures;
-
- VkPhysicalDeviceVariablePointerFeatures pdVarPtrFeatures;
- pdVarPtrFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
- pdVarPtrFeatures.pNext = &pdDescIdxFeatures;
-
- VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR pdUBOLayoutFeatures;
- pdUBOLayoutFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
- pdUBOLayoutFeatures.pNext = &pdVarPtrFeatures;
-
- VkPhysicalDeviceFloat16Int8FeaturesKHR pdF16I8Features;
- pdF16I8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
- pdF16I8Features.pNext = &pdUBOLayoutFeatures;
-
- VkPhysicalDevice8BitStorageFeaturesKHR pdStorage8Features;
- pdStorage8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
- pdStorage8Features.pNext = &pdF16I8Features;
-
- VkPhysicalDevice16BitStorageFeatures pdStorage16Features;
- pdStorage16Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
- pdStorage16Features.pNext = &pdStorage8Features;
-
VkPhysicalDeviceFeatures2 pdFeats2;
- pdFeats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
- pdFeats2.pNext = &pdStorage16Features;
+ pdFeats2.sType = sType;
+ pdFeats2.pNext = pPrevStruct;
_physicalDevice->getFeatures(&pdFeats2);
- //Enable device features based on requested and available features
+ //Enable device features based on requested and available features,
+ // including extended features that are requested in the pNext chain.
if (pCreateInfo->pEnabledFeatures) {
enableFeatures(&_enabledFeatures.robustBufferAccess,
&pCreateInfo->pEnabledFeatures->robustBufferAccess,
@@ -4397,163 +4290,42 @@
&pdFeats2.features.robustBufferAccess, 55);
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDevice16BitStorageFeatures*)next;
- enableFeatures(&_enabledStorage16Features.storageBuffer16BitAccess,
- &requestedFeatures->storageBuffer16BitAccess,
- &pdStorage16Features.storageBuffer16BitAccess, 4);
- break;
+
+#define MVK_DEVICE_FEATURE(structName, enumName, flagCount) \
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES: { \
+ enableFeatures((VkBaseInStructure*)&_enabled##structName##Features, \
+ next, \
+ (VkBaseInStructure*)&pd##structName##Features, \
+ flagCount); \
+ break; \
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
- auto* requestedFeatures = (VkPhysicalDevice8BitStorageFeaturesKHR*)next;
- enableFeatures(&_enabledStorage8Features.storageBuffer8BitAccess,
- &requestedFeatures->storageBuffer8BitAccess,
- &pdStorage8Features.storageBuffer8BitAccess, 3);
- break;
+#define MVK_DEVICE_FEATURE_EXTN(structName, enumName, extnSfx, flagCount) \
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##enumName##_FEATURES_##extnSfx: { \
+ enableFeatures((VkBaseInStructure*)&_enabled##structName##Features, \
+ next, \
+ (VkBaseInStructure*)&pd##structName##Features, \
+ flagCount); \
+ break; \
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
- auto* requestedFeatures = (VkPhysicalDeviceFloat16Int8FeaturesKHR*)next;
- enableFeatures(&_enabledF16I8Features.shaderFloat16,
- &requestedFeatures->shaderFloat16,
- &pdF16I8Features.shaderFloat16, 2);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
- auto* requestedFeatures = (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR*)next;
- enableFeatures(&_enabledUBOLayoutFeatures.uniformBufferStandardLayout,
- &requestedFeatures->uniformBufferStandardLayout,
- &pdUBOLayoutFeatures.uniformBufferStandardLayout, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDeviceVariablePointerFeatures*)next;
- enableFeatures(&_enabledVarPtrFeatures.variablePointersStorageBuffer,
- &requestedFeatures->variablePointersStorageBuffer,
- &pdVarPtrFeatures.variablePointersStorageBuffer, 2);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)next;
- enableFeatures(&_enabledDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing,
- &requestedFeatures->shaderInputAttachmentArrayDynamicIndexing,
- &pdDescIdxFeatures.shaderInputAttachmentArrayDynamicIndexing, 20);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceInlineUniformBlockFeaturesEXT*)next;
- enableFeatures(&_enabledInlineUniformBlockFeatures.inlineUniformBlock,
- &requestedFeatures->inlineUniformBlock,
- &pdInlnUnfmBlkFeatures.inlineUniformBlock, 2);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
- enableFeatures(&_enabledInterlockFeatures.fragmentShaderSampleInterlock,
- &requestedFeatures->fragmentShaderSampleInterlock,
- &pdInterlockFeatures.fragmentShaderSampleInterlock, 3);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next;
- enableFeatures(&_enabledHostQryResetFeatures.hostQueryReset,
- &requestedFeatures->hostQueryReset,
- &pdHostQryResetFeatures.hostQueryReset, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)next;
- enableFeatures(&_enabledSamplerYcbcrConversionFeatures.samplerYcbcrConversion,
- &requestedFeatures->samplerYcbcrConversion,
- &pdSamplerYcbcrConversionFeatures.samplerYcbcrConversion, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDevicePrivateDataFeaturesEXT*)next;
- enableFeatures(&_enabledPrivateDataFeatures.privateData,
- &requestedFeatures->privateData,
- &pdPrivateDataFeatures.privateData, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT*)next;
- enableFeatures(&_enabledScalarLayoutFeatures.scalarBlockLayout,
- &requestedFeatures->scalarBlockLayout,
- &pdScalarLayoutFeatures.scalarBlockLayout, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT*)next;
- enableFeatures(&_enabledTexelBuffAlignFeatures.texelBufferAlignment,
- &requestedFeatures->texelBufferAlignment,
- &pdTexelBuffAlignFeatures.texelBufferAlignment, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT*)next;
- enableFeatures(&_enabledVtxAttrDivFeatures.vertexAttributeInstanceRateDivisor,
- &requestedFeatures->vertexAttributeInstanceRateDivisor,
- &pdVtxAttrDivFeatures.vertexAttributeInstanceRateDivisor, 2);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR: {
- auto* requestedFeatures = (VkPhysicalDevicePortabilitySubsetFeaturesKHR*)next;
- enableFeatures(&_enabledPortabilityFeatures.constantAlphaColorBlendFactors,
- &requestedFeatures->constantAlphaColorBlendFactors,
- &pdPortabilityFeatures.constantAlphaColorBlendFactors, 15);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDeviceImagelessFramebufferFeaturesKHR*)next;
- enableFeatures(&_enabledImagelessFramebufferFeatures.imagelessFramebuffer,
- &requestedFeatures->imagelessFramebuffer,
- &pdImagelessFramebufferFeatures.imagelessFramebuffer, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDeviceDynamicRenderingFeatures*)next;
- enableFeatures(&_enabledDynamicRenderingFeatures.dynamicRendering,
- &requestedFeatures->dynamicRendering,
- &pdDynamicRenderingFeatures.dynamicRendering, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures*)next;
- enableFeatures(&_enabledSeparateDepthStencilLayoutsFeatures.separateDepthStencilLayouts,
- &requestedFeatures->separateDepthStencilLayouts,
- &pdSeparateDepthStencilLayoutsFeatures.separateDepthStencilLayouts, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR: {
- auto* requestedFeatures = (VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR*)next;
- enableFeatures(&_enabledFragmentShaderBarycentricFeatures.fragmentShaderBarycentric,
- &requestedFeatures->fragmentShaderBarycentric,
- &pdFragmentShaderBarycentricFeatures.fragmentShaderBarycentric, 1);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES: {
- auto* requestedFeatures = (VkPhysicalDeviceBufferDeviceAddressFeatures*)next;
- enableFeatures(&_enabledBufferDeviceAddressFeatures.bufferDeviceAddress,
- &requestedFeatures->bufferDeviceAddress,
- &pdBufferDeviceAddressFeatures.bufferDeviceAddress, 3);
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: {
- auto* requestedFeatures = (VkPhysicalDeviceBufferDeviceAddressFeaturesEXT*)next;
- enableFeatures(&_enabledBufferDeviceAddressFeaturesEXT.bufferDeviceAddress,
- &requestedFeatures->bufferDeviceAddress,
- &pdBufferDeviceAddressFeaturesEXT.bufferDeviceAddress, 3);
- break;
- }
+#include "MVKDeviceFeatureStructs.def"
+
default:
break;
}
}
}
-void MVKDevice::enableFeatures(const VkBool32* pEnable, const VkBool32* pRequested, const VkBool32* pAvailable, uint32_t count) {
+void MVKDevice::enableFeatures(VkBaseInStructure* pEnabled, const VkBaseInStructure* pRequested, const VkBaseInStructure* pAvailable, uint32_t count) {
+ enableFeatures((VkBool32*)(&(pEnabled->pNext) + 1),
+ (VkBool32*)(&(pRequested->pNext) + 1),
+ (VkBool32*)(&(pAvailable->pNext) + 1),
+ count);
+}
+
+void MVKDevice::enableFeatures(VkBool32* pEnabledBools, const VkBool32* pRequestedBools, const VkBool32* pAvailableBools, uint32_t count) {
for (uint32_t i = 0; i < count; i++) {
- ((VkBool32*)pEnable)[i] = pRequested[i] && pAvailable[i];
- if (pRequested[i] && !pAvailable[i]) {
+ pEnabledBools[i] = pRequestedBools[i] && pAvailableBools[i];
+ if (pRequestedBools[i] && !pAvailableBools[i]) {
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateDevice(): Requested feature is not available on this device."));
}
}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def
new file mode 100644
index 0000000..dba229d
--- /dev/null
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def
@@ -0,0 +1,71 @@
+/*
+ * MVKDeviceFeatureStructs.def
+ *
+ * Copyright (c) 2015-2022 The Brenwill Workshop Ltd. (http://www.brenwill.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// To use this file, define the macro MVK_DEVICE_FEATURE and optionally
+// MVK_DEVICE_FEATURE_EXTN if needed, then #include this file.
+
+// To add a new device feature struct, simply add a line below.
+// The order is the typical approach of alphabetical but separated
+// into sections based on Vulkan extensions.
+
+#ifndef MVK_DEVICE_FEATURE
+#error MVK_DEVICE_FEATURE must be defined before including this file
+#endif
+#ifndef MVK_DEVICE_FEATURE_EXTN
+#define MVK_DEVICE_FEATURE_EXTN(structName, enumName, extnSfx, flagCount) MVK_DEVICE_FEATURE(structName, enumName, flagCount)
+#endif
+
+// INTEL is a common macro defined elsewhere in the system.
+// We need to temporarily undefine it so that it doesn't expand when used in a macro below.
+#pragma push_macro("INTEL")
+#undef INTEL
+
+MVK_DEVICE_FEATURE(16BitStorage, 16BIT_STORAGE, 4)
+MVK_DEVICE_FEATURE(8BitStorage, 8BIT_STORAGE, 3)
+MVK_DEVICE_FEATURE(BufferDeviceAddress, BUFFER_DEVICE_ADDRESS, 3)
+MVK_DEVICE_FEATURE(DescriptorIndexing, DESCRIPTOR_INDEXING, 20)
+MVK_DEVICE_FEATURE(DynamicRendering, DYNAMIC_RENDERING, 1)
+MVK_DEVICE_FEATURE(HostQueryReset, HOST_QUERY_RESET, 1)
+MVK_DEVICE_FEATURE(ImagelessFramebuffer, IMAGELESS_FRAMEBUFFER, 1)
+MVK_DEVICE_FEATURE(ImageRobustness, IMAGE_ROBUSTNESS, 1)
+MVK_DEVICE_FEATURE(InlineUniformBlock, INLINE_UNIFORM_BLOCK, 2)
+MVK_DEVICE_FEATURE(Multiview, MULTIVIEW, 3)
+MVK_DEVICE_FEATURE(PrivateData, PRIVATE_DATA, 1)
+MVK_DEVICE_FEATURE(ProtectedMemory, PROTECTED_MEMORY, 1)
+MVK_DEVICE_FEATURE(SamplerYcbcrConversion, SAMPLER_YCBCR_CONVERSION, 1)
+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(ShaderFloat16Int8, SHADER_FLOAT16_INT8, 2)
+MVK_DEVICE_FEATURE(ShaderSubgroupExtendedTypes, SHADER_SUBGROUP_EXTENDED_TYPES, 1)
+MVK_DEVICE_FEATURE(SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, 2)
+MVK_DEVICE_FEATURE(TextureCompressionASTCHDR, TEXTURE_COMPRESSION_ASTC_HDR, 1)
+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_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)
+MVK_DEVICE_FEATURE_EXTN(Robustness2, ROBUSTNESS_2, EXT, 3)
+MVK_DEVICE_FEATURE_EXTN(TexelBufferAlignment, TEXEL_BUFFER_ALIGNMENT, EXT, 1)
+MVK_DEVICE_FEATURE_EXTN(VertexAttributeDivisor, VERTEX_ATTRIBUTE_DIVISOR, EXT, 2)
+MVK_DEVICE_FEATURE_EXTN(ShaderIntegerFunctions2, SHADER_INTEGER_FUNCTIONS_2, INTEL, 1)
+
+#pragma pop_macro("INTEL")
+#undef MVK_DEVICE_FEATURE_EXTN
+#undef MVK_DEVICE_FEATURE