From df5c5b5bf38d01c2a5df209e4c46437ee24bdd1f Mon Sep 17 00:00:00 2001 From: spencer-lunarg Date: Mon, 28 Oct 2024 13:53:27 -0400 Subject: [PATCH] layers: Add Extension Checks for Layer Extensions --- layers/stateless/sl_instance_device.cpp | 33 ++++++++++++++++++---- scripts/vk_validation_stats.py | 1 + tests/framework/layer_validation_tests.cpp | 4 +++ tests/framework/render.cpp | 1 + tests/unit/best_practices.cpp | 6 ++-- tests/unit/instanceless.cpp | 15 ---------- tests/unit/portability_subset.cpp | 13 +++++---- 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/layers/stateless/sl_instance_device.cpp b/layers/stateless/sl_instance_device.cpp index e63409a3e10..3b6af30f3da 100644 --- a/layers/stateless/sl_instance_device.cpp +++ b/layers/stateless/sl_instance_device.cpp @@ -185,18 +185,18 @@ bool StatelessValidation::manual_PreCallValidateCreateInstance(const VkInstanceC } } - const auto *debug_report_callback = vku::FindStructInPNextChain(pCreateInfo->pNext); - if (debug_report_callback && !local_instance_extensions.vk_ext_debug_report) { + if (!local_instance_extensions.vk_ext_debug_report && + vku::FindStructInPNextChain(pCreateInfo->pNext)) { skip |= LogError("VUID-VkInstanceCreateInfo-pNext-04925", instance, create_info_loc.dot(Field::ppEnabledExtensionNames), "does not include VK_EXT_debug_report, but the pNext chain includes VkDebugReportCallbackCreateInfoEXT."); } - const auto *debug_utils_messenger = vku::FindStructInPNextChain(pCreateInfo->pNext); - if (debug_utils_messenger && !local_instance_extensions.vk_ext_debug_utils) { + if (!local_instance_extensions.vk_ext_debug_utils && + vku::FindStructInPNextChain(pCreateInfo->pNext)) { skip |= LogError("VUID-VkInstanceCreateInfo-pNext-04926", instance, create_info_loc.dot(Field::ppEnabledExtensionNames), "does not include VK_EXT_debug_utils, but the pNext chain includes VkDebugUtilsMessengerCreateInfoEXT."); } - const auto *direct_driver_loading_list = vku::FindStructInPNextChain(pCreateInfo->pNext); - if (direct_driver_loading_list && !local_instance_extensions.vk_lunarg_direct_driver_loading) { + if (!local_instance_extensions.vk_lunarg_direct_driver_loading && + vku::FindStructInPNextChain(pCreateInfo->pNext)) { skip |= LogError( "VUID-VkInstanceCreateInfo-pNext-09400", instance, create_info_loc.dot(Field::ppEnabledExtensionNames), "does not include VK_LUNARG_direct_driver_loading, but the pNext chain includes VkDirectDriverLoadingListLUNARG."); @@ -218,6 +218,27 @@ bool StatelessValidation::manual_PreCallValidateCreateInstance(const VkInstanceC } #endif // VK_USE_PLATFORM_METAL_EXT + // These are extensions/structs implemented in the Validation Layers itself, in theory, the extension string is not needed, but + // good to have for completeness + if (!local_instance_extensions.vk_ext_layer_settings && + vku::FindStructInPNextChain(pCreateInfo->pNext)) { + skip |= LogWarning("VUID-VkInstanceCreateInfo-pNext-10242", instance, create_info_loc.dot(Field::ppEnabledExtensionNames), + "does not include VK_EXT_layer_settings, but the pNext chain includes VkLayerSettingsCreateInfoEXT. " + "(Most layers, including Validation, will still work regardless of the extension included)"); + } + if (!local_instance_extensions.vk_ext_validation_features && + vku::FindStructInPNextChain(pCreateInfo->pNext)) { + skip |= LogWarning("VUID-VkInstanceCreateInfo-pNext-10243", instance, create_info_loc.dot(Field::ppEnabledExtensionNames), + "does not include VK_EXT_validation_features, but the pNext chain includes VkValidationFeaturesEXT. " + "(Most layers, including Validation, will still work regardless of the extension included)"); + } + if (!local_instance_extensions.vk_ext_validation_flags && + vku::FindStructInPNextChain(pCreateInfo->pNext)) { + skip |= LogWarning("VUID-VkInstanceCreateInfo-pNext-10244", instance, create_info_loc.dot(Field::ppEnabledExtensionNames), + "does not include VK_EXT_validation_flags, but the pNext chain includes VkValidationFlagsEXT. (Most " + "layers, including Validation, will still work regardless of the extension included)"); + } + return skip; } diff --git a/scripts/vk_validation_stats.py b/scripts/vk_validation_stats.py index 334a3643cf1..a43bc12948f 100755 --- a/scripts/vk_validation_stats.py +++ b/scripts/vk_validation_stats.py @@ -479,6 +479,7 @@ def main(argv): layer_source_files = [repo_relative(path) for path in [ 'layers/error_message/unimplementable_validation.h', 'layers/state_tracker/video_session_state.cpp', + 'layers/layer_options.cpp', f'layers/{args.api}/generated/stateless_validation_helper.cpp', f'layers/{args.api}/generated/object_tracker.cpp', f'layers/{args.api}/generated/spirv_validation_helper.cpp', diff --git a/tests/framework/layer_validation_tests.cpp b/tests/framework/layer_validation_tests.cpp index 5c27b552a45..34a0b1cc7d1 100644 --- a/tests/framework/layer_validation_tests.cpp +++ b/tests/framework/layer_validation_tests.cpp @@ -325,6 +325,10 @@ void VkLayerTest::Init(VkPhysicalDeviceFeatures *features, VkPhysicalDeviceFeatu } VkLayerTest::VkLayerTest() { + // These are extensions enabled by the layer, they can always be on because we know for a fact the Validation Layers will have + // them enabled always + m_instance_extension_names.push_back(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME); + m_instance_extension_names.push_back(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME); #if !defined(VK_USE_PLATFORM_ANDROID_KHR) m_instance_extension_names.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); #else diff --git a/tests/framework/render.cpp b/tests/framework/render.cpp index 2166432168d..f1b98841df3 100644 --- a/tests/framework/render.cpp +++ b/tests/framework/render.cpp @@ -99,6 +99,7 @@ bool VkRenderFramework::InstanceExtensionSupported(const char *const extension_n if (0 == strncmp(extension_name, VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE)) return true; if (0 == strncmp(extension_name, VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE)) return true; if (0 == strncmp(extension_name, VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE)) return true; + if (0 == strncmp(extension_name, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE)) return true; if (available_extensions_.empty()) { available_extensions_ = vkt::GetGlobalExtensions(); diff --git a/tests/unit/best_practices.cpp b/tests/unit/best_practices.cpp index 3f3462c2ec0..2939de6f364 100644 --- a/tests/unit/best_practices.cpp +++ b/tests/unit/best_practices.cpp @@ -103,8 +103,10 @@ TEST_F(VkBestPracticesLayerTest, UseDeprecatedInstanceExtensions) { // Extra error if VK_EXT_debug_report is used on Android still m_errorMonitor->SetDesiredWarning("BestPractices-deprecated-extension"); } - m_errorMonitor->SetDesiredWarning("BestPractices-deprecated-extension"); - m_errorMonitor->SetDesiredWarning("BestPractices-specialuse-extension"); + m_errorMonitor->SetDesiredWarning("BestPractices-deprecated-extension"); // VK_EXT_validation_features + m_errorMonitor->SetDesiredWarning("BestPractices-deprecated-extension"); // VK_KHR_get_physical_device_properties2, + m_errorMonitor->SetDesiredWarning("BestPractices-specialuse-extension"); // VK_EXT_validation_features + m_errorMonitor->SetDesiredWarning("BestPractices-specialuse-extension"); // VK_EXT_debug_utils VkInstance dummy; auto features = features_; auto ici = GetInstanceCreateInfo(); diff --git a/tests/unit/instanceless.cpp b/tests/unit/instanceless.cpp index e4078bab0e2..410c3ac9749 100644 --- a/tests/unit/instanceless.cpp +++ b/tests/unit/instanceless.cpp @@ -337,21 +337,6 @@ TEST_F(NegativeInstanceless, ExtensionStructsWithoutExtensions) { m_errorMonitor->SetDesiredError("VUID-VkInstanceCreateInfo-pNext-09400"); vk::CreateInstance(&ici, nullptr, &instance); m_errorMonitor->VerifyFound(); - - VkDebugUtilsMessengerCreateInfoEXT debug_utils_messenger = vku::InitStructHelper(); - debug_utils_messenger.pNext = m_errorMonitor->GetDebugCreateInfo(); - debug_utils_messenger.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - debug_utils_messenger.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; - debug_utils_messenger.pfnUserCallback = utils_callback; - ici.pNext = &debug_utils_messenger; - // Ignore the first extension which is VK_EXT_debug_utils - ici.enabledExtensionCount = size32(m_instance_extension_names) - 1; - if (ici.enabledExtensionCount > 0) { - ici.ppEnabledExtensionNames = &m_instance_extension_names[1]; - } - m_errorMonitor->SetDesiredError("VUID-VkInstanceCreateInfo-pNext-04926"); - vk::CreateInstance(&ici, nullptr, &instance); - m_errorMonitor->VerifyFound(); } #endif diff --git a/tests/unit/portability_subset.cpp b/tests/unit/portability_subset.cpp index bd0755b590f..2432c795ad3 100644 --- a/tests/unit/portability_subset.cpp +++ b/tests/unit/portability_subset.cpp @@ -608,10 +608,17 @@ TEST_F(VkPortabilitySubsetTest, PortabilitySubsetColorBlendFactor) { TEST_F(VkPortabilitySubsetTest, InstanceCreateEnumerate) { TEST_DESCRIPTION("Validate creating instances with VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR."); + std::vector enabled_extensions = {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, + VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME}; + +#ifdef VK_USE_PLATFORM_ANDROID_KHR + GTEST_SKIP() << "Android doesn't support Debug Utils"; +#endif auto ici = GetInstanceCreateInfo(); ici.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; ici.enabledExtensionCount = 1; + ici.ppEnabledExtensionNames = enabled_extensions.data(); VkInstance local_instance; @@ -620,11 +627,7 @@ TEST_F(VkPortabilitySubsetTest, InstanceCreateEnumerate) { m_errorMonitor->VerifyFound(); if (InstanceExtensionSupported(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) { - std::vector enabled_extensions = {VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, - VK_EXT_DEBUG_UTILS_EXTENSION_NAME}; - ici.enabledExtensionCount = static_cast(enabled_extensions.size()); - ici.ppEnabledExtensionNames = enabled_extensions.data(); - + ici.enabledExtensionCount = 2; ASSERT_EQ(VK_SUCCESS, vk::CreateInstance(&ici, nullptr, &local_instance)); vk::DestroyInstance(local_instance, nullptr); }