diff --git a/include/vsg/vk/Instance.h b/include/vsg/vk/Instance.h index f92658a0e..c863a9992 100644 --- a/include/vsg/vk/Instance.h +++ b/include/vsg/vk/Instance.h @@ -41,6 +41,9 @@ namespace vsg /// return names of layers that are supported from the desired list. extern VSG_DECLSPEC Names validateInstanceLayerNames(const Names& names); + /// return true if the specified layer name exists in the list. + extern VSG_DECLSPEC bool containsInstanceLayerName(const Names& names, const char* layerName); + /// Instance encapsulates the VkInstance. class VSG_DECLSPEC Instance : public Inherit { diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index cac8dbd1a..2c25d4921 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -573,6 +573,47 @@ typedef enum VkRayTracingShaderGroupTypeKHR #endif + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Definitions not provided prior to 1.2.150 +// +#if VK_HEADER_VERSION < 150 + +#define VK_EXT_validation_features 1 +#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 4 +#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" + +typedef enum VkValidationFeatureEnableEXT { + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, + VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, + VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, + VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4, + VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureEnableEXT; + +typedef enum VkValidationFeatureDisableEXT { + VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0, + VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1, + VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2, + VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3, + VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, + VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, + VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, + VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureDisableEXT; +typedef struct VkValidationFeaturesEXT { + VkStructureType sType; + const void* pNext; + uint32_t enabledValidationFeatureCount; + const VkValidationFeatureEnableEXT* pEnabledValidationFeatures; + uint32_t disabledValidationFeatureCount; + const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; +} VkValidationFeaturesEXT; + +#endif + //////////////////////////////////////////////////////////////////////////////////////////////////// // // Definitions not provided prior to 1.2.162 diff --git a/src/vsg/vk/Instance.cpp b/src/vsg/vk/Instance.cpp index 86c88b30d..d34e3b929 100644 --- a/src/vsg/vk/Instance.cpp +++ b/src/vsg/vk/Instance.cpp @@ -91,6 +91,16 @@ Names vsg::validateInstanceLayerNames(const Names& names) return validatedNames; } +bool vsg::containsInstanceLayerName(const Names& names, const char* layerName) +{ + if (!layerName) return false; + + auto cmpFunc = [&](const char* name) { + return strcmp(name, layerName) == 0; + }; + return std::find_if(names.begin(), names.end(), cmpFunc) != names.end(); +} + static VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsMessengerCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT /*messageType*/, @@ -143,7 +153,29 @@ Instance::Instance(Names instanceExtensions, Names layers, uint32_t vulkanApiVer createInfo.enabledLayerCount = static_cast(layers.size()); createInfo.ppEnabledLayerNames = layers.empty() ? nullptr : layers.data(); - createInfo.pNext = nullptr; + std::vector enabledValidationFeatures; + std::vector disabledValidationFeatures; + + // syncronization validation requires VkValidationFeaturesEXT + if (containsInstanceLayerName(layers, "VK_LAYER_KHRONOS_synchronization2")) enabledValidationFeatures.push_back(VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT); + + // set up the VkValidationFeaturesEXT if required + VkValidationFeaturesEXT validationFeatures{}; + if (!enabledValidationFeatures.empty() || !disabledValidationFeatures.empty()) + { + validationFeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT; + validationFeatures.enabledValidationFeatureCount = static_cast(enabledValidationFeatures.size()); + validationFeatures.pEnabledValidationFeatures = enabledValidationFeatures.data(); + + validationFeatures.disabledValidationFeatureCount = static_cast(disabledValidationFeatures.size()); + validationFeatures.pDisabledValidationFeatures = disabledValidationFeatures.data(); + + createInfo.pNext = &validationFeatures; + } + else + { + createInfo.pNext = nullptr; + } VkInstance instance; VkResult result = vkCreateInstance(&createInfo, allocator, &instance);