Added support to run the CTS with Vulkan validation layers (#2246)

Fixes #2116 according to task description.

As approved 25Mar25
This commit is contained in:
Marcin Hajder
2025-03-25 16:43:28 +01:00
committed by GitHub
parent 81f33190e2
commit 1cbb548e27
9 changed files with 180 additions and 36 deletions

View File

@@ -48,16 +48,38 @@ VK_WINDOWS_FUNC_LIST
#define CHECK_VK(call) \
if (call != VK_SUCCESS) return call;
static VKAPI_ATTR VkBool32 VKAPI_CALL logCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
{
switch (messageSeverity)
{
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
log_error("Vulkan validation layer: %s\n", pCallbackData->pMessage);
break;
default:
log_info("Vulkan validation layer: %s\n", pCallbackData->pMessage);
break;
}
return VK_FALSE;
}
///////////////////////////////////
// VulkanInstance implementation //
///////////////////////////////////
VulkanInstance::VulkanInstance(const VulkanInstance &instance)
: m_vkInstance(instance.m_vkInstance),
m_physicalDeviceList(instance.m_physicalDeviceList)
m_physicalDeviceList(instance.m_physicalDeviceList),
m_useValidationLayers(instance.m_useValidationLayers),
m_validationLayers(instance.m_validationLayers)
{}
VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
VulkanInstance::VulkanInstance(bool useValidationLayers)
: m_vkInstance(VK_NULL_HANDLE), m_useValidationLayers(useValidationLayers)
{
#if defined(__linux__) && !defined(__ANDROID__)
char *glibcVersion = strdup(gnu_get_libc_version());
@@ -130,6 +152,35 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
VK_GET_NULL_INSTANCE_PROC_ADDR(vkCreateInstance);
#undef VK_GET_NULL_INSTANCE_PROC_ADDR
if (m_useValidationLayers)
{
uint32_t layerCount = 0;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
std::vector<VkLayerProperties> layers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, layers.data());
for (auto it = m_validationLayers.begin();
it != m_validationLayers.end();)
{
bool found = false;
for (const auto &layerProps : layers)
if (strcmp(*it, layerProps.layerName) == 0)
{
found = true;
break;
}
if (!found)
{
log_info("Vulkan layer not found: %s\n", *it);
it = m_validationLayers.erase(it);
}
else
++it;
}
m_useValidationLayers = !m_validationLayers.empty();
}
VkApplicationInfo vkApplicationInfo = {};
vkApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
vkApplicationInfo.pNext = NULL;
@@ -147,6 +198,9 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
enabledExtensionNameList.push_back(
VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
if (m_useValidationLayers)
enabledExtensionNameList.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
std::vector<VkExtensionProperties> vkExtensionPropertiesList(
instanceExtensionPropertiesCount);
vkEnumerateInstanceExtensionProperties(NULL,
@@ -174,18 +228,51 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
VkInstanceCreateInfo vkInstanceCreateInfo = {};
vkInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
vkInstanceCreateInfo.pNext = NULL;
vkInstanceCreateInfo.flags = 0;
vkInstanceCreateInfo.pApplicationInfo = &vkApplicationInfo;
vkInstanceCreateInfo.enabledLayerCount = 0;
vkInstanceCreateInfo.ppEnabledLayerNames = NULL;
vkInstanceCreateInfo.enabledExtensionCount =
(uint32_t)enabledExtensionNameList.size();
vkInstanceCreateInfo.ppEnabledExtensionNames =
enabledExtensionNameList.data();
vkInstanceCreateInfo.enabledLayerCount = 0;
vkInstanceCreateInfo.pNext = NULL;
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
if (m_useValidationLayers)
{
vkInstanceCreateInfo.enabledLayerCount =
static_cast<uint32_t>(m_validationLayers.size());
vkInstanceCreateInfo.ppEnabledLayerNames = m_validationLayers.data();
debugCreateInfo.messageType =
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
debugCreateInfo.sType =
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
debugCreateInfo.messageSeverity =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
debugCreateInfo.pfnUserCallback = logCallback;
vkInstanceCreateInfo.pNext =
(VkDebugUtilsMessengerCreateInfoEXT *)&debugCreateInfo;
}
vkCreateInstance(&vkInstanceCreateInfo, NULL, &m_vkInstance);
if (m_useValidationLayers)
{
_vkCreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
m_vkInstance, "vkCreateDebugUtilsMessengerEXT");
if (_vkCreateDebugUtilsMessengerEXT != nullptr)
vkCreateDebugUtilsMessengerEXT(m_vkInstance, &debugCreateInfo,
nullptr, &m_debugMessenger);
}
#define VK_FUNC_DECL(name) \
_##name = (PFN_##name)vkGetInstanceProcAddr(m_vkInstance, #name); \
// ASSERT_NEQ((unsigned long long)name, 0ULL) << "Couldn't obtain address
@@ -228,6 +315,17 @@ VulkanInstance::~VulkanInstance()
m_physicalDeviceList[pdIdx];
delete &physicalDevice;
}
_vkDestroyDebugUtilsMessengerEXT =
(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
m_vkInstance, "vkDestroyDebugUtilsMessengerEXT");
if (_vkDestroyDebugUtilsMessengerEXT != nullptr)
{
vkDestroyDebugUtilsMessengerEXT(m_vkInstance, m_debugMessenger,
nullptr);
}
if (m_vkInstance)
{
vkDestroyInstance(m_vkInstance, NULL);