diff --git a/test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.cpp b/test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.cpp index ded1e709..36b94d9e 100644 --- a/test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.cpp +++ b/test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.cpp @@ -1191,6 +1191,10 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType( { switch (vkExternalMemoryHandleType) { + default: + case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: + log_error("Unexpected external memory handle type\n"); + return 0; case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD: return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR; case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT: @@ -1198,7 +1202,6 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType( case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT: case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_KMT: return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR; - case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: return 0; } return 0; } diff --git a/test_conformance/common/vulkan_wrapper/vulkan_api_list.hpp b/test_conformance/common/vulkan_wrapper/vulkan_api_list.hpp index f5e7437a..a474102d 100644 --- a/test_conformance/common/vulkan_wrapper/vulkan_api_list.hpp +++ b/test_conformance/common/vulkan_wrapper/vulkan_api_list.hpp @@ -102,6 +102,8 @@ VK_FUNC_DECL(vkImportSemaphoreFdKHR) \ VK_FUNC_DECL(vkGetPhysicalDeviceExternalSemaphorePropertiesKHR) \ VK_FUNC_DECL(vkGetImageSubresourceLayout) \ + VK_FUNC_DECL(vkCreateDebugUtilsMessengerEXT) \ + VK_FUNC_DECL(vkDestroyDebugUtilsMessengerEXT) \ VK_FUNC_DECL(vkGetPhysicalDeviceExternalBufferProperties) #define VK_WINDOWS_FUNC_LIST \ VK_FUNC_DECL(vkGetMemoryWin32HandleKHR) \ @@ -203,6 +205,8 @@ #define vkGetSemaphoreWin32HandleKHR _vkGetSemaphoreWin32HandleKHR #define vkImportSemaphoreWin32HandleKHR _vkImportSemaphoreWin32HandleKHR #define vkGetImageSubresourceLayout _vkGetImageSubresourceLayout +#define vkCreateDebugUtilsMessengerEXT _vkCreateDebugUtilsMessengerEXT +#define vkDestroyDebugUtilsMessengerEXT _vkDestroyDebugUtilsMessengerEXT #define vkGetPhysicalDeviceExternalBufferProperties \ _vkGetPhysicalDeviceExternalBufferProperties diff --git a/test_conformance/common/vulkan_wrapper/vulkan_utility.cpp b/test_conformance/common/vulkan_wrapper/vulkan_utility.cpp index 6391d36b..75aa536d 100644 --- a/test_conformance/common/vulkan_wrapper/vulkan_utility.cpp +++ b/test_conformance/common/vulkan_wrapper/vulkan_utility.cpp @@ -32,13 +32,13 @@ #define BUFFERSIZE 3000 -const VulkanInstance &getVulkanInstance() +const VulkanInstance &getVulkanInstance(bool useValidationLayers) { - static VulkanInstance instance; + static VulkanInstance instance(useValidationLayers); return instance; } -const VulkanPhysicalDevice &getVulkanPhysicalDevice() +const VulkanPhysicalDevice &getVulkanPhysicalDevice(bool useValidationLayers) { size_t pdIdx = 0; cl_int errNum = 0; @@ -47,7 +47,7 @@ const VulkanPhysicalDevice &getVulkanPhysicalDevice() cl_uint num_devices = 0; cl_uint device_no = 0; const size_t bufsize = BUFFERSIZE; - const VulkanInstance &instance = getVulkanInstance(); + const VulkanInstance &instance = getVulkanInstance(useValidationLayers); const VulkanPhysicalDeviceList &physicalDeviceList = instance.getPhysicalDeviceList(); @@ -112,12 +112,13 @@ const VulkanPhysicalDevice &getVulkanPhysicalDevice() } const VulkanPhysicalDevice & -getAssociatedVulkanPhysicalDevice(cl_device_id deviceId) +getAssociatedVulkanPhysicalDevice(cl_device_id deviceId, + bool useValidationLayers) { size_t pdIdx; cl_int errNum = 0; cl_uchar uuid[CL_UUID_SIZE_KHR]; - const VulkanInstance &instance = getVulkanInstance(); + const VulkanInstance &instance = getVulkanInstance(useValidationLayers); const VulkanPhysicalDeviceList &physicalDeviceList = instance.getPhysicalDeviceList(); @@ -188,10 +189,10 @@ getVulkanMemoryType(const VulkanDevice &device, return memoryTypeList[mtIdx]; } -bool checkVkSupport() +bool checkVkSupport(bool useValidationLayers) { bool result = true; - const VulkanInstance &instance = getVulkanInstance(); + const VulkanInstance &instance = getVulkanInstance(useValidationLayers); const VulkanPhysicalDeviceList &physicalDeviceList = instance.getPhysicalDeviceList(); if (physicalDeviceList() == NULL) @@ -711,6 +712,7 @@ operator<<(std::ostream &os, { switch (externalMemoryHandleType) { + default: case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: return os << "None"; case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD: return os << "Opaque file descriptor"; @@ -731,6 +733,7 @@ operator<<(std::ostream &os, { switch (externalSemaphoreHandleType) { + default: case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NONE: return os << "None"; case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD: return os << "Opaque file descriptor"; diff --git a/test_conformance/common/vulkan_wrapper/vulkan_utility.hpp b/test_conformance/common/vulkan_wrapper/vulkan_utility.hpp index 85028662..cd9bf4ee 100644 --- a/test_conformance/common/vulkan_wrapper/vulkan_utility.hpp +++ b/test_conformance/common/vulkan_wrapper/vulkan_utility.hpp @@ -30,10 +30,12 @@ #define ROUND_UP(n, multiple) \ (((n) + (multiple)-1) - ((((n) + (multiple)-1)) % (multiple))) -const VulkanInstance& getVulkanInstance(); -const VulkanPhysicalDevice& getVulkanPhysicalDevice(); +const VulkanInstance& getVulkanInstance(bool useValidationLayers = false); const VulkanPhysicalDevice& -getAssociatedVulkanPhysicalDevice(cl_device_id deviceId); +getVulkanPhysicalDevice(bool useValidationLayers = false); +const VulkanPhysicalDevice& +getAssociatedVulkanPhysicalDevice(cl_device_id deviceId, + bool useValidationLayers = false); const VulkanQueueFamily& getVulkanQueueFamily( const VulkanPhysicalDevice& physicalDevice = getVulkanPhysicalDevice(), uint32_t queueFlags = VULKAN_QUEUE_FLAG_GRAPHICS @@ -41,7 +43,7 @@ const VulkanQueueFamily& getVulkanQueueFamily( const VulkanMemoryType& getVulkanMemoryType(const VulkanDevice& device, VulkanMemoryTypeProperty memoryTypeProperty); -bool checkVkSupport(); +bool checkVkSupport(bool useValidationLayers = false); const VulkanQueueFamilyList& getEmptyVulkanQueueFamilyList(); const VulkanDescriptorSetLayoutList& getEmptyVulkanDescriptorSetLayoutList(); const VulkanQueueFamilyToQueueCountMap& diff --git a/test_conformance/common/vulkan_wrapper/vulkan_wrapper.cpp b/test_conformance/common/vulkan_wrapper/vulkan_wrapper.cpp index 6c31a35d..f41e196d 100644 --- a/test_conformance/common/vulkan_wrapper/vulkan_wrapper.cpp +++ b/test_conformance/common/vulkan_wrapper/vulkan_wrapper.cpp @@ -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 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 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(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); diff --git a/test_conformance/common/vulkan_wrapper/vulkan_wrapper.hpp b/test_conformance/common/vulkan_wrapper/vulkan_wrapper.hpp index a536d140..04d74c57 100644 --- a/test_conformance/common/vulkan_wrapper/vulkan_wrapper.hpp +++ b/test_conformance/common/vulkan_wrapper/vulkan_wrapper.hpp @@ -25,14 +25,21 @@ #include class VulkanInstance { - friend const VulkanInstance &getVulkanInstance(); + friend const VulkanInstance &getVulkanInstance(bool useValidationLayers); protected: VkInstance m_vkInstance; VulkanPhysicalDeviceList m_physicalDeviceList; + VkDebugUtilsMessengerEXT m_debugMessenger; + bool m_useValidationLayers; + std::vector m_validationLayers = { + "VK_LAYER_KHRONOS_validation", + }; - VulkanInstance(); VulkanInstance(const VulkanInstance &); + +public: + VulkanInstance(bool useValidationLayers = false); virtual ~VulkanInstance(); public: diff --git a/test_conformance/vulkan/main.cpp b/test_conformance/vulkan/main.cpp index d2d278da..fdc1e8fc 100644 --- a/test_conformance/vulkan/main.cpp +++ b/test_conformance/vulkan/main.cpp @@ -31,6 +31,7 @@ #endif #include "harness/testHarness.h" +#include "harness/parseParameters.h" unsigned int numCQ; bool multiImport; @@ -38,6 +39,7 @@ bool multiCtx; bool debug_trace = false; bool useSingleImageKernel = false; bool useDeviceLocal = false; +bool useValidationLayers = false; bool disableNTHandleType = false; bool enableOffset = false; @@ -55,7 +57,15 @@ static void printUsage(const char *execName) log_info("\n"); log_info("Options:\n"); log_info("\t--debug_trace - Enables additional debug info logging\n"); - log_info("\t--non_dedicated - Choose dedicated Vs. non_dedicated \n"); + log_info("\t--useSingleImageKernel - Use the same image " + "(image_single_queue and image_multiple_queue tests)\n"); + log_info("\t--useDeviceLocal - Skip tests that use images with local " + "memory type\n"); + log_info("\t--disableNTHandleType - Skip tests that use win32 external " + "memory handle\n"); + log_info("\t--useValidationLayers - Enables Vulkan validation layer " + "diagnostic output\n"); + log_info("\t-h - Print test usage\n"); } bool isDeviceSelection(const char *arg) @@ -70,35 +80,47 @@ bool isDeviceSelection(const char *arg) || strcmp(arg, "CL_DEVICE_TYPE_DEFAULT") == 0; } -size_t parseParams(int argc, const char *argv[], const char **argList) +void parseParams(int &argc, const char *argv[]) { - size_t argCount = 1; - for (int i = 1; i < argc; i++) + argc = parseCustomParam(argc, argv); + + for (int i = 0; i < argc; ++i) { + int argsRemoveNum = 0; + if (argv[i] == NULL) break; if (argv[i][0] == '-') { if (!strcmp(argv[i], "--debug_trace")) { debug_trace = true; + argsRemoveNum = 1; } if (!strcmp(argv[i], "--useSingleImageKernel")) { useSingleImageKernel = true; + argsRemoveNum = 1; } if (!strcmp(argv[i], "--useDeviceLocal")) { useDeviceLocal = true; + argsRemoveNum = 1; + } + if (!strcmp(argv[i], "--useValidationLayers")) + { + useValidationLayers = true; + argsRemoveNum = 1; } if (!strcmp(argv[i], "--disableNTHandleType")) { disableNTHandleType = true; + argsRemoveNum = 1; } if (strcmp(argv[i], "-h") == 0) { printUsage(argv[0]); - argCount = 0; // Returning argCount=0 to assert error in main() - break; + argc = 0; // Returning argCount=0 to assert error in main() + return; } } else if (isDeviceSelection(argv[i])) @@ -108,16 +130,20 @@ size_t parseParams(int argc, const char *argv[], const char **argList) && strcmp(argv[i], "CL_DEVICE_TYPE_DEFAULT") != 0) { log_info("Vulkan tests can only run on a GPU device.\n"); - return 0; + argc = 0; + return; } } - else + + if (argsRemoveNum > 0) { - argList[argCount] = argv[i]; - argCount++; + for (int j = i; j < (argc - argsRemoveNum); ++j) + argv[j] = argv[j + argsRemoveNum]; + + argc -= argsRemoveNum; + --i; } } - return argCount; } int main(int argc, const char *argv[]) @@ -147,9 +173,9 @@ int main(int argc, const char *argv[]) return 0; } - const char **argList = (const char **)calloc(argc, sizeof(char *)); - size_t argCount = parseParams(argc, argv, argList); - if (argCount == 0) return 0; + parseParams(argc, argv); + + if (argc == 0) return 0; return runTestHarness(argc, argv, test_registry::getInstance().num_tests(), test_registry::getInstance().definitions(), false, 0); diff --git a/test_conformance/vulkan/vulkan_interop_common.hpp b/test_conformance/vulkan/vulkan_interop_common.hpp index 6f4d9155..4e285335 100644 --- a/test_conformance/vulkan/vulkan_interop_common.hpp +++ b/test_conformance/vulkan/vulkan_interop_common.hpp @@ -42,6 +42,7 @@ extern bool debug_trace; extern bool useSingleImageKernel; extern bool useDeviceLocal; +extern bool useValidationLayers; extern bool disableNTHandleType; #endif // _vulkan_interop_common_hpp_ diff --git a/test_conformance/vulkan/vulkan_test_base.h b/test_conformance/vulkan/vulkan_test_base.h index 82b8e639..8c7b07cc 100644 --- a/test_conformance/vulkan/vulkan_test_base.h +++ b/test_conformance/vulkan/vulkan_test_base.h @@ -40,8 +40,8 @@ struct VulkanTestBase cl_command_queue queue, cl_int nelems) : device(device), context(context), num_elems(nelems) { - vkDevice.reset( - new VulkanDevice(getAssociatedVulkanPhysicalDevice(device))); + vkDevice.reset(new VulkanDevice( + getAssociatedVulkanPhysicalDevice(device, useValidationLayers))); cl_platform_id platform; cl_int error = clGetDeviceInfo(device, CL_DEVICE_PLATFORM, @@ -101,7 +101,7 @@ int MakeAndRunTest(cl_device_id device, cl_context context, return TEST_SKIPPED_ITSELF; } - if (!checkVkSupport()) + if (!checkVkSupport(useValidationLayers)) { log_info("Vulkan supported GPU not found \n"); log_info("TEST SKIPPED \n");