diff options
Diffstat (limited to 'tools/Vulkan-Tools/tests')
| -rw-r--r-- | tools/Vulkan-Tools/tests/CMakeLists.txt | 71 | ||||
| -rw-r--r-- | tools/Vulkan-Tools/tests/README.md | 34 | ||||
| -rw-r--r-- | tools/Vulkan-Tools/tests/icd/mock_icd_tests.cpp | 1199 | ||||
| -rw-r--r-- | tools/Vulkan-Tools/tests/main.cpp | 34 | ||||
| -rw-r--r-- | tools/Vulkan-Tools/tests/test_common.h | 34 |
5 files changed, 1372 insertions, 0 deletions
diff --git a/tools/Vulkan-Tools/tests/CMakeLists.txt b/tools/Vulkan-Tools/tests/CMakeLists.txt new file mode 100644 index 00000000..a1b7250f --- /dev/null +++ b/tools/Vulkan-Tools/tests/CMakeLists.txt @@ -0,0 +1,71 @@ +# ~~~ +# Copyright (c) 2023 Valve Corporation +# Copyright (c) 2023 LunarG, Inc. +# +# 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. +# ~~~ + +if (ANDROID) + + # Ensure ANativeActivity_onCreate is being exported from vkcube + find_program(GNU_NM NAMES nm) + if (GNU_NM) + add_test(NAME ANativeActivity_onCreate COMMAND ${GNU_NM} --dynamic $<TARGET_FILE:vkcube>) + set_tests_properties(ANativeActivity_onCreate + PROPERTIES PASS_REGULAR_EXPRESSION "T ANativeActivity_onCreate" + ) + endif() + + return() +endif() + +# Testing isn't supported with mingw +if (MINGW) + return() +endif() + +find_package(VulkanLoader CONFIG) + +find_package(GTest REQUIRED CONFIG QUIET) + +add_executable(vulkan_tools_tests) +target_sources(vulkan_tools_tests PRIVATE + main.cpp + test_common.h + icd/mock_icd_tests.cpp +) +get_target_property(TEST_SOURCES vulkan_tools_tests SOURCES) +source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${TEST_SOURCES}) + +target_include_directories(vulkan_tools_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(vulkan_tools_tests GTest::gtest Vulkan::Headers Vulkan::Loader) +if (WIN32) + target_compile_definitions(vulkan_tools_tests PUBLIC -DVK_USE_PLATFORM_WIN32_KHR -DWIN32_LEAN_AND_MEAN -DNOMINMAX) +endif() +set_target_properties(vulkan_tools_tests PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL") + +# Set the exact path to Mock JSON ICD +target_compile_definitions(vulkan_tools_tests PRIVATE MOCK_ICD_JSON_MANIFEST_PATH="$<TARGET_FILE_DIR:VkICD_mock_icd>") + +if (DEFINED GIT_BRANCH_NAME AND DEFINED GIT_TAG_INFO) + target_compile_definitions(vulkan_tools_tests PRIVATE GIT_BRANCH_NAME="${GIT_BRANCH_NAME}" GIT_TAG_INFO="${GIT_TAG_INFO}") +endif() + +if (WIN32) + # Copy the loader shared lib (if built) to the test application directory so the test app finds it. + add_custom_command(TARGET vulkan_tools_tests POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:Vulkan::Loader> $<TARGET_FILE_DIR:vulkan_tools_tests>) +endif() + +include(GoogleTest) +gtest_discover_tests(vulkan_tools_tests DISCOVERY_TIMEOUT 100) diff --git a/tools/Vulkan-Tools/tests/README.md b/tools/Vulkan-Tools/tests/README.md new file mode 100644 index 00000000..0e0798e7 --- /dev/null +++ b/tools/Vulkan-Tools/tests/README.md @@ -0,0 +1,34 @@ +## Android + +### Running vkcube on Android + +```sh +cd Vulkan-Tools + +cd build-android + +# Optional +adb uninstall com.example.VkCube + +adb install -r -g --no-incremental bin/VkCube.apk + +adb shell am start com.example.VkCube/android.app.NativeActivity +``` + +### vulkaninfo on Android + +Unlike `vkcube`, `vulkaninfo` doesn't require the extra step of creating an `APK`. + +So the following should be enough. + +```sh +cd Vulkan-Tools + +scripts/android.py --config Release --app-abi arm64-v8a --app-stl c++_static --clean + +adb push build-android/cmake/arm64-v8a/vulkaninfo/vulkaninfo /data/local/tmp + +adb shell /data/local/tmp/vulkaninfo --json --output /data/local/tmp/foobar.json + +adb pull /data/local/tmp/foobar.json +``` diff --git a/tools/Vulkan-Tools/tests/icd/mock_icd_tests.cpp b/tools/Vulkan-Tools/tests/icd/mock_icd_tests.cpp new file mode 100644 index 00000000..06fc124f --- /dev/null +++ b/tools/Vulkan-Tools/tests/icd/mock_icd_tests.cpp @@ -0,0 +1,1199 @@ +/* + * Copyright (c) 2023 The Khronos Group Inc. + * Copyright (c) 2023 Valve Corporation + * Copyright (c) 2023 LunarG, Inc. + * + * 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. + * + */ + +#include "test_common.h" + +void setup_mock_icd_env_vars() { + // Necessary to point the loader at the mock driver + set_environment_var("VK_DRIVER_FILES", MOCK_ICD_JSON_MANIFEST_PATH); + // Prevents layers from being loaded at all + set_environment_var("VK_LOADER_LAYERS_DISABLE", "~all~"); +} + +// Defines a simple context for tests to use. +// Creates an instance, physical_device, device, and queue + +class MockICD : public ::testing::Test { + protected: + void SetUp() override { + setup_mock_icd_env_vars(); + + // Create an instance with the latest version & necessary surface extensions + VkResult res = VK_SUCCESS; + VkApplicationInfo app_info{}; + app_info.apiVersion = VK_HEADER_VERSION_COMPLETE; + VkInstanceCreateInfo instance_create_info{}; + instance_create_info.pApplicationInfo = &app_info; + std::array<const char*, 2> extension_to_enable = {"VK_KHR_surface", "VK_KHR_display"}; + instance_create_info.enabledExtensionCount = static_cast<uint32_t>(extension_to_enable.size()); + instance_create_info.ppEnabledExtensionNames = extension_to_enable.data(); + res = vkCreateInstance(&instance_create_info, nullptr, &instance); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(instance, nullptr); + + uint32_t count = 1; + res = vkEnumeratePhysicalDevices(instance, &count, &physical_device); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + ASSERT_NE(physical_device, nullptr); + + VkDeviceCreateInfo device_create_info{}; + std::array<const char*, 1> device_extension_to_enable = {"VK_KHR_swapchain"}; + device_create_info.enabledExtensionCount = static_cast<uint32_t>(device_extension_to_enable.size()); + device_create_info.ppEnabledExtensionNames = device_extension_to_enable.data(); + res = vkCreateDevice(physical_device, &device_create_info, nullptr, &device); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(device, nullptr); + + vkGetDeviceQueue(device, 0, 0, &queue); + ASSERT_NE(queue, nullptr); + } + + void TearDown() override { + vkDestroyDevice(device, nullptr); + vkDestroyInstance(instance, nullptr); + } + + VkInstance instance{}; + VkPhysicalDevice physical_device{}; + VkDevice device{}; + VkQueue queue{}; +}; + +/* + * Exercises the following commands: + * vkEnumerateInstanceExtensionProperties + * vkEnumerateInstanceLayerProperties + * vkEnumerateInstanceVersion + * vkCreateInstance + * vkEnumeratePhysicalDevices + * vkEnumeratePhysicalDeviceGroups + * vkEnumerateDeviceExtensionProperties + * vkGetPhysicalDeviceQueueFamilyProperties + * vkGetPhysicalDeviceQueueFamilyProperties2 + * vkCreateDevice + * vkDestroyDevice + * vkDestroyInstance + * vkGetDeviceQueue + * vkGetDeviceQueue2 + */ +TEST_F(MockICD, InitializationFunctions) { + setup_mock_icd_env_vars(); + VkResult res = VK_SUCCESS; + uint32_t count = 0; + res = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_GT(count, 0); + std::vector<VkExtensionProperties> inst_ext_props{count, VkExtensionProperties{}}; + res = vkEnumerateInstanceExtensionProperties(nullptr, &count, inst_ext_props.data()); + ASSERT_EQ(res, VK_SUCCESS); + + // Since we disabled layers, count should stay zero + count = 0; + res = vkEnumerateInstanceLayerProperties(&count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 0); + + uint32_t api_version; + res = vkEnumerateInstanceVersion(&api_version); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_GE(api_version, VK_API_VERSION_1_0); + + VkInstanceCreateInfo inst_create_info{}; + VkInstance instance{}; + res = vkCreateInstance(&inst_create_info, nullptr, &instance); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(instance, nullptr); + + count = 0; + VkPhysicalDevice physical_device; + res = vkEnumeratePhysicalDevices(instance, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + + res = vkEnumeratePhysicalDevices(instance, &count, &physical_device); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + ASSERT_NE(physical_device, nullptr); + + count = 0; + res = vkEnumeratePhysicalDeviceGroups(instance, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_GT(count, 0); + + VkPhysicalDeviceGroupProperties physical_device_groups; + count = 1; + res = vkEnumeratePhysicalDeviceGroups(instance, &count, &physical_device_groups); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + + count = 0; + res = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_GT(count, 0); + std::vector<VkExtensionProperties> device_ext_props{count, VkExtensionProperties{}}; + res = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &count, device_ext_props.data()); + ASSERT_EQ(res, VK_SUCCESS); + + // Device layers are deprecated, should return number of active layers, which is zero + count = 0; + res = vkEnumerateDeviceLayerProperties(physical_device, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 0); + count = 0; + + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, nullptr); + ASSERT_EQ(count, 3); + VkQueueFamilyProperties queue_family_properties[3] = {}; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, queue_family_properties); + ASSERT_EQ(count, 3); + ASSERT_EQ(queue_family_properties[0].queueFlags, 1 | 2 | 4 | 8 | 16); + ASSERT_EQ(queue_family_properties[1].queueFlags, 4 | 16 | 32); + ASSERT_EQ(queue_family_properties[2].queueFlags, 4 | 16 | 64); + for (uint32_t i = 0; i < count; ++i) { + ASSERT_EQ(queue_family_properties[i].queueCount, 1); + ASSERT_EQ(queue_family_properties[i].timestampValidBits, 16); + ASSERT_EQ(queue_family_properties[i].minImageTransferGranularity.width, 1); + ASSERT_EQ(queue_family_properties[i].minImageTransferGranularity.height, 1); + ASSERT_EQ(queue_family_properties[i].minImageTransferGranularity.depth, 1); + } + + vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &count, nullptr); + ASSERT_EQ(count, 3); + VkQueueFamilyProperties2 queue_family_properties2[3] = {}; + for (uint32_t i = 0; i < count; ++i) { + queue_family_properties2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; + } + vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &count, queue_family_properties2); + ASSERT_EQ(count, 3); + ASSERT_EQ(queue_family_properties2[0].queueFamilyProperties.queueFlags, 1 | 2 | 4 | 8 | 16); + ASSERT_EQ(queue_family_properties2[1].queueFamilyProperties.queueFlags, 4 | 16 | 32); + ASSERT_EQ(queue_family_properties2[2].queueFamilyProperties.queueFlags, 4 | 16 | 64); + for (uint32_t i = 0; i < count; ++i) { + ASSERT_EQ(queue_family_properties2[i].queueFamilyProperties.queueCount, 1); + ASSERT_EQ(queue_family_properties2[i].queueFamilyProperties.timestampValidBits, 16); + ASSERT_EQ(queue_family_properties2[i].queueFamilyProperties.minImageTransferGranularity.width, 1); + ASSERT_EQ(queue_family_properties2[i].queueFamilyProperties.minImageTransferGranularity.height, 1); + ASSERT_EQ(queue_family_properties2[i].queueFamilyProperties.minImageTransferGranularity.depth, 1); + } + + VkDeviceCreateInfo dev_create_info{}; + VkDevice device{}; + res = vkCreateDevice(physical_device, &dev_create_info, nullptr, &device); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(device, nullptr); + + VkQueue queue{}; + vkGetDeviceQueue(device, 0, 0, &queue); + ASSERT_NE(queue, nullptr); + + VkDeviceQueueInfo2 queue_info{}; + vkGetDeviceQueue2(device, &queue_info, &queue); + ASSERT_NE(queue, nullptr); + + vkDestroyDevice(device, nullptr); + vkDestroyInstance(instance, nullptr); +} + +/* + * Exercises the following commands: + * vkCreateCommandPool + * vkAllocateCommandBuffers + * vkFreeCommandBuffers + * vkDestroyCommandPool + */ +TEST_F(MockICD, CommandBufferOperations) { + VkResult res = VK_SUCCESS; + VkCommandPoolCreateInfo command_pool_create_info{}; + VkCommandPool command_pool; + res = vkCreateCommandPool(device, &command_pool_create_info, nullptr, &command_pool); + ASSERT_EQ(VK_SUCCESS, res); + + VkCommandBufferAllocateInfo command_buffer_allocate_info{}; + command_buffer_allocate_info.commandBufferCount = 5; + std::array<VkCommandBuffer, 5> command_buffers; + res = vkAllocateCommandBuffers(device, &command_buffer_allocate_info, command_buffers.data()); + ASSERT_EQ(VK_SUCCESS, res); + for (const auto& command_buffer : command_buffers) { + ASSERT_NE(nullptr, command_buffer); + } + + vkFreeCommandBuffers(device, command_pool, 5, command_buffers.data()); + + vkDestroyCommandPool(device, command_pool, nullptr); +} + +VkResult create_surface(VkInstance instance, VkSurfaceKHR& surface) { + VkDisplaySurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR}; + return vkCreateDisplayPlaneSurfaceKHR(instance, &surf_create_info, nullptr, &surface); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSurfacePresentModesKHR) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + uint32_t count = 0; + std::array<VkPresentModeKHR, 6> present_modes{}; + res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, present_modes.size()); + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &count, present_modes.data()); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(present_modes[0], VK_PRESENT_MODE_IMMEDIATE_KHR); + ASSERT_EQ(present_modes[1], VK_PRESENT_MODE_MAILBOX_KHR); + ASSERT_EQ(present_modes[2], VK_PRESENT_MODE_FIFO_KHR); + ASSERT_EQ(present_modes[3], VK_PRESENT_MODE_FIFO_RELAXED_KHR); + ASSERT_EQ(present_modes[4], VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR); + ASSERT_EQ(present_modes[5], VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSurfaceFormatsKHR) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + uint32_t count = 0; + std::array<VkSurfaceFormatKHR, 2> surface_formats{}; + res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, surface_formats.size()); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &count, surface_formats.data()); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(surface_formats[0].format, VK_FORMAT_B8G8R8A8_UNORM); + ASSERT_EQ(surface_formats[0].colorSpace, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR); + ASSERT_EQ(surface_formats[1].format, VK_FORMAT_R8G8B8A8_UNORM); + ASSERT_EQ(surface_formats[1].colorSpace, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSurfaceFormats2KHR) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + uint32_t count = 0; + std::array<VkSurfaceFormat2KHR, 2> surface_formats2{}; + VkPhysicalDeviceSurfaceInfo2KHR surface_info{}; + surface_info.surface = surface; + res = vkGetPhysicalDeviceSurfaceFormats2KHR(physical_device, &surface_info, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, surface_formats2.size()); + vkGetPhysicalDeviceSurfaceFormats2KHR(physical_device, &surface_info, &count, surface_formats2.data()); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(surface_formats2[0].pNext, nullptr); + ASSERT_EQ(surface_formats2[0].surfaceFormat.format, VK_FORMAT_B8G8R8A8_UNORM); + ASSERT_EQ(surface_formats2[0].surfaceFormat.colorSpace, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR); + ASSERT_EQ(surface_formats2[1].pNext, nullptr); + ASSERT_EQ(surface_formats2[1].surfaceFormat.format, VK_FORMAT_R8G8B8A8_UNORM); + ASSERT_EQ(surface_formats2[1].surfaceFormat.colorSpace, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSurfaceSupportKHR) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + VkBool32 supported = false; + res = vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, 0, surface, &supported); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(supported, true); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSurfaceCapabilitiesKHR) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + VkSurfaceCapabilitiesKHR surface_capabilities{}; + res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_capabilities); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(surface_capabilities.minImageCount, 1); + ASSERT_EQ(surface_capabilities.currentExtent.width, std::numeric_limits<uint32_t>::max()); + ASSERT_EQ(surface_capabilities.currentExtent.height, std::numeric_limits<uint32_t>::max()); + ASSERT_EQ(surface_capabilities.minImageExtent.width, 1); + ASSERT_EQ(surface_capabilities.minImageExtent.height, 1); + ASSERT_EQ(surface_capabilities.maxImageArrayLayers, 128); + ASSERT_EQ(surface_capabilities.currentTransform, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSurfaceCapabilities2KHR) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + VkSurfaceCapabilities2KHR surface_capabilities2{}; + VkPhysicalDeviceSurfaceInfo2KHR surface_info{}; + surface_info.surface = surface; + res = vkGetPhysicalDeviceSurfaceCapabilities2KHR(physical_device, &surface_info, &surface_capabilities2); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.minImageCount, 1); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.currentExtent.width, std::numeric_limits<uint32_t>::max()); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.currentExtent.height, std::numeric_limits<uint32_t>::max()); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.minImageExtent.width, 1); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.minImageExtent.height, 1); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.maxImageArrayLayers, 128); + ASSERT_EQ(surface_capabilities2.surfaceCapabilities.currentTransform, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceMemoryProperties) { + VkPhysicalDeviceMemoryProperties memory_properties{}; + vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); + ASSERT_EQ(memory_properties.memoryTypeCount, 6); + ASSERT_EQ(memory_properties.memoryTypes[0].propertyFlags, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + ASSERT_EQ(memory_properties.memoryTypes[0].heapIndex, 0); + ASSERT_EQ(memory_properties.memoryTypes[5].propertyFlags, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + ASSERT_EQ(memory_properties.memoryTypes[5].heapIndex, 1); + ASSERT_EQ(memory_properties.memoryHeapCount, 2); + ASSERT_EQ(memory_properties.memoryHeaps[0].flags, VK_MEMORY_HEAP_MULTI_INSTANCE_BIT); + ASSERT_EQ(memory_properties.memoryHeaps[0].size, 8000000000); + ASSERT_EQ(memory_properties.memoryHeaps[1].flags, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT); + ASSERT_EQ(memory_properties.memoryHeaps[1].size, 8000000000); +} + +TEST_F(MockICD, vkGetPhysicalDeviceMemoryProperties2) { + VkPhysicalDeviceMemoryProperties2 memory_properties2{}; + vkGetPhysicalDeviceMemoryProperties2(physical_device, &memory_properties2); + ASSERT_EQ(memory_properties2.memoryProperties.memoryTypeCount, 6); + ASSERT_EQ(memory_properties2.memoryProperties.memoryTypes[0].propertyFlags, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + ASSERT_EQ(memory_properties2.memoryProperties.memoryTypes[0].heapIndex, 0); + ASSERT_EQ(memory_properties2.memoryProperties.memoryTypes[5].propertyFlags, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + ASSERT_EQ(memory_properties2.memoryProperties.memoryTypes[5].heapIndex, 1); + ASSERT_EQ(memory_properties2.memoryProperties.memoryHeapCount, 2); + ASSERT_EQ(memory_properties2.memoryProperties.memoryHeaps[0].flags, VK_MEMORY_HEAP_MULTI_INSTANCE_BIT); + ASSERT_EQ(memory_properties2.memoryProperties.memoryHeaps[0].size, 8000000000); + ASSERT_EQ(memory_properties2.memoryProperties.memoryHeaps[1].flags, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT); + ASSERT_EQ(memory_properties2.memoryProperties.memoryHeaps[1].size, 8000000000); +} + +TEST_F(MockICD, vkGetPhysicalDeviceFeatures) { + VkPhysicalDeviceFeatures features{}; + vkGetPhysicalDeviceFeatures(physical_device, &features); + // Make sure the first and last elements are set to true + ASSERT_EQ(features.robustBufferAccess, true); + ASSERT_EQ(features.inheritedQueries, true); +} + +TEST_F(MockICD, vkGetPhysicalDeviceFeatures2) { + VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features{}; + descriptor_indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; + + VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT blending_operation_advanced_features{}; + blending_operation_advanced_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT; + blending_operation_advanced_features.pNext = static_cast<void*>(&descriptor_indexing_features); + + VkPhysicalDeviceFeatures2 features2{}; + features2.pNext = static_cast<void*>(&blending_operation_advanced_features); + vkGetPhysicalDeviceFeatures2(physical_device, &features2); + // Make sure the first and last elements are set to true + ASSERT_EQ(features2.features.robustBufferAccess, true); + ASSERT_EQ(features2.features.inheritedQueries, true); + ASSERT_EQ(descriptor_indexing_features.shaderInputAttachmentArrayDynamicIndexing, true); + ASSERT_EQ(descriptor_indexing_features.runtimeDescriptorArray, true); + ASSERT_EQ(blending_operation_advanced_features.advancedBlendCoherentOperations, true); +} + +TEST_F(MockICD, vkGetPhysicalDeviceFormatProperties) { + VkFormatProperties format_properties{}; + vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R8G8B8A8_SRGB, &format_properties); + ASSERT_EQ(format_properties.bufferFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties.linearTilingFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties.optimalTilingFeatures, 0x00FFFDFF); +} + +TEST_F(MockICD, vkGetPhysicalDeviceFormatProperties2) { + VkFormatProperties3 format_properties3{}; + format_properties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3; + VkFormatProperties2 format_properties2{}; + format_properties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + format_properties2.pNext = static_cast<void*>(&format_properties3); + vkGetPhysicalDeviceFormatProperties2(physical_device, VK_FORMAT_R8G8B8A8_SRGB, &format_properties2); + ASSERT_EQ(format_properties2.formatProperties.bufferFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties2.formatProperties.linearTilingFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties2.formatProperties.optimalTilingFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties3.bufferFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties3.linearTilingFeatures, 0x00FFFDFF); + ASSERT_EQ(format_properties3.optimalTilingFeatures, 0x400000FFFDFF); +} + +TEST_F(MockICD, vkGetPhysicalDeviceImageFormatProperties) { + VkImageFormatProperties image_format_properties{}; + vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &image_format_properties); + ASSERT_EQ(image_format_properties.maxExtent.width, 4096); + ASSERT_EQ(image_format_properties.maxExtent.height, 4096); + ASSERT_EQ(image_format_properties.maxExtent.depth, 256); + ASSERT_EQ(image_format_properties.maxMipLevels, 1); + ASSERT_EQ(image_format_properties.maxArrayLayers, 1); + ASSERT_EQ(image_format_properties.sampleCounts, VK_SAMPLE_COUNT_1_BIT); + ASSERT_EQ(image_format_properties.maxResourceSize, 4294967296 /* this is max of uint32_t + 1*/); +} + +TEST_F(MockICD, vkGetPhysicalDeviceImageFormatProperties2) { + VkImageFormatProperties2 image_format_properties2{}; + VkPhysicalDeviceImageFormatInfo2 image_format_info2{}; + image_format_info2.format = VK_FORMAT_R8G8B8A8_SRGB; + image_format_info2.type = VK_IMAGE_TYPE_2D; + image_format_info2.tiling = VK_IMAGE_TILING_OPTIMAL; + image_format_info2.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + image_format_info2.flags = 0; + vkGetPhysicalDeviceImageFormatProperties2(physical_device, &image_format_info2, &image_format_properties2); + ASSERT_EQ(image_format_properties2.imageFormatProperties.maxExtent.width, 4096); + ASSERT_EQ(image_format_properties2.imageFormatProperties.maxExtent.height, 4096); + ASSERT_EQ(image_format_properties2.imageFormatProperties.maxExtent.depth, 256); + ASSERT_EQ(image_format_properties2.imageFormatProperties.maxMipLevels, 12); + ASSERT_EQ(image_format_properties2.imageFormatProperties.maxArrayLayers, 256); + ASSERT_EQ(image_format_properties2.imageFormatProperties.sampleCounts, 0x7F & ~VK_SAMPLE_COUNT_64_BIT); + ASSERT_EQ(image_format_properties2.imageFormatProperties.maxResourceSize, 4294967296 /* this is max of uint32_t + 1*/); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSparseImageFormatProperties) { + uint32_t count = 0; + VkSparseImageFormatProperties sparse_image_format_properties{}; + vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TYPE_2D, + VK_SAMPLE_COUNT_64_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL, &count, nullptr); + ASSERT_EQ(count, 1); + vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TYPE_2D, + VK_SAMPLE_COUNT_64_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL, &count, &sparse_image_format_properties); + ASSERT_EQ(sparse_image_format_properties.aspectMask, VK_IMAGE_ASPECT_COLOR_BIT); + ASSERT_EQ(sparse_image_format_properties.imageGranularity.width, 4); + ASSERT_EQ(sparse_image_format_properties.imageGranularity.height, 4); + ASSERT_EQ(sparse_image_format_properties.imageGranularity.depth, 4); + ASSERT_EQ(sparse_image_format_properties.flags, VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT); +} + +TEST_F(MockICD, vkGetPhysicalDeviceSparseImageFormatProperties2) { + uint32_t count = 0; + VkSparseImageFormatProperties2 sparse_image_format_properties2{}; + VkPhysicalDeviceSparseImageFormatInfo2 sparse_image_format_info2{}; + sparse_image_format_info2.format = VK_FORMAT_R8G8B8A8_SRGB; + sparse_image_format_info2.type = VK_IMAGE_TYPE_2D; + sparse_image_format_info2.samples = VK_SAMPLE_COUNT_64_BIT; + sparse_image_format_info2.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + sparse_image_format_info2.tiling = VK_IMAGE_TILING_OPTIMAL; + vkGetPhysicalDeviceSparseImageFormatProperties2(physical_device, &sparse_image_format_info2, &count, nullptr); + ASSERT_EQ(count, 1); + vkGetPhysicalDeviceSparseImageFormatProperties2(physical_device, &sparse_image_format_info2, &count, + &sparse_image_format_properties2); + ASSERT_EQ(sparse_image_format_properties2.properties.aspectMask, VK_IMAGE_ASPECT_COLOR_BIT); + ASSERT_EQ(sparse_image_format_properties2.properties.imageGranularity.width, 4); + ASSERT_EQ(sparse_image_format_properties2.properties.imageGranularity.height, 4); + ASSERT_EQ(sparse_image_format_properties2.properties.imageGranularity.depth, 4); + ASSERT_EQ(sparse_image_format_properties2.properties.flags, VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT); +} + +TEST_F(MockICD, vkGetPhysicalDeviceProperties) { + VkPhysicalDeviceProperties physical_device_properties{}; + vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties); + ASSERT_EQ(physical_device_properties.apiVersion, VK_HEADER_VERSION_COMPLETE); + ASSERT_EQ(physical_device_properties.driverVersion, 1); + ASSERT_EQ(physical_device_properties.vendorID, 0xba5eba11); + ASSERT_EQ(physical_device_properties.deviceID, 0xf005ba11); + ASSERT_EQ(physical_device_properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU); + ASSERT_STREQ(&physical_device_properties.deviceName[0], "Vulkan Mock Device"); + ASSERT_EQ(physical_device_properties.pipelineCacheUUID[0], 18); + ASSERT_EQ(physical_device_properties.limits.maxImageDimension1D, 4096); + ASSERT_EQ(physical_device_properties.limits.nonCoherentAtomSize, 256); + ASSERT_EQ(physical_device_properties.sparseProperties.residencyAlignedMipSize, VK_TRUE); + ASSERT_EQ(physical_device_properties.sparseProperties.residencyNonResidentStrict, VK_TRUE); + ASSERT_EQ(physical_device_properties.sparseProperties.residencyStandard2DBlockShape, VK_TRUE); + ASSERT_EQ(physical_device_properties.sparseProperties.residencyStandard2DMultisampleBlockShape, VK_TRUE); + ASSERT_EQ(physical_device_properties.sparseProperties.residencyStandard3DBlockShape, VK_TRUE); +} + +TEST_F(MockICD, vkGetPhysicalDeviceProperties2) { + VkPhysicalDeviceVulkan11Properties properties11{}; + properties11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES; + + VkPhysicalDeviceVulkan12Properties properties12{}; + properties12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; + properties12.pNext = static_cast<void*>(&properties11); + + VkPhysicalDeviceVulkan13Properties properties13{}; + properties13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES; + properties13.pNext = static_cast<void*>(&properties12); + + VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties{}; + protected_memory_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES; + protected_memory_properties.pNext = static_cast<void*>(&properties13); + + VkPhysicalDeviceFloatControlsProperties float_controls_properties{}; + float_controls_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES; + float_controls_properties.pNext = static_cast<void*>(&protected_memory_properties); + + VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_rasterization_properties{}; + conservative_rasterization_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT; + conservative_rasterization_properties.pNext = static_cast<void*>(&float_controls_properties); + + VkPhysicalDeviceRayTracingPipelinePropertiesKHR raytracing_pipeline_properties{}; + raytracing_pipeline_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR; + raytracing_pipeline_properties.pNext = static_cast<void*>(&conservative_rasterization_properties); + + VkPhysicalDeviceRayTracingPropertiesNV ray_tracing_properties{}; + ray_tracing_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV; + ray_tracing_properties.pNext = static_cast<void*>(&raytracing_pipeline_properties); + + VkPhysicalDeviceTexelBufferAlignmentProperties texel_buffer_alignment_properties{}; + texel_buffer_alignment_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES; + texel_buffer_alignment_properties.pNext = static_cast<void*>(&ray_tracing_properties); + + VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer_properties{}; + descriptor_buffer_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT; + descriptor_buffer_properties.pNext = static_cast<void*>(&texel_buffer_alignment_properties); + + VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties{}; + mesh_shader_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT; + mesh_shader_properties.pNext = static_cast<void*>(&descriptor_buffer_properties); + + VkPhysicalDeviceFragmentDensityMap2PropertiesEXT fragment_density_map2_properties{}; + fragment_density_map2_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT; + fragment_density_map2_properties.pNext = static_cast<void*>(&mesh_shader_properties); + + VkPhysicalDeviceDriverProperties driver_properties{}; + driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; + driver_properties.pNext = static_cast<void*>(&fragment_density_map2_properties); + + VkPhysicalDeviceProperties2 properties2{}; + properties2.pNext = static_cast<void*>(&driver_properties); + vkGetPhysicalDeviceProperties2(physical_device, &properties2); + ASSERT_EQ(properties2.properties.apiVersion, VK_HEADER_VERSION_COMPLETE); + ASSERT_EQ(properties2.properties.driverVersion, 1); + ASSERT_EQ(properties2.properties.vendorID, 0xba5eba11); + ASSERT_EQ(properties2.properties.deviceID, 0xf005ba11); + ASSERT_EQ(properties2.properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU); + ASSERT_STREQ(&properties2.properties.deviceName[0], "Vulkan Mock Device"); + ASSERT_EQ(properties2.properties.pipelineCacheUUID[0], 18); + ASSERT_EQ(properties2.properties.limits.maxImageDimension1D, 4096); + ASSERT_EQ(properties2.properties.limits.nonCoherentAtomSize, 256); + ASSERT_EQ(properties2.properties.sparseProperties.residencyAlignedMipSize, VK_TRUE); + ASSERT_EQ(properties2.properties.sparseProperties.residencyNonResidentStrict, VK_TRUE); + ASSERT_EQ(properties2.properties.sparseProperties.residencyStandard2DBlockShape, VK_TRUE); + ASSERT_EQ(properties2.properties.sparseProperties.residencyStandard2DMultisampleBlockShape, VK_TRUE); + ASSERT_EQ(properties2.properties.sparseProperties.residencyStandard3DBlockShape, VK_TRUE); + + ASSERT_EQ(properties11.protectedNoFault, VK_FALSE); + ASSERT_EQ(properties12.denormBehaviorIndependence, VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL); + ASSERT_EQ(properties12.roundingModeIndependence, VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL); + ASSERT_EQ(properties13.storageTexelBufferOffsetSingleTexelAlignment, VK_TRUE); + ASSERT_EQ(properties13.uniformTexelBufferOffsetSingleTexelAlignment, VK_TRUE); + ASSERT_EQ(properties13.storageTexelBufferOffsetAlignmentBytes, 16); + ASSERT_EQ(properties13.uniformTexelBufferOffsetAlignmentBytes, 16); + ASSERT_EQ(protected_memory_properties.protectedNoFault, VK_FALSE); + ASSERT_EQ(float_controls_properties.denormBehaviorIndependence, VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL); + ASSERT_EQ(float_controls_properties.roundingModeIndependence, VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL); + ASSERT_EQ(conservative_rasterization_properties.primitiveOverestimationSize, 0.00195313f); + ASSERT_EQ(conservative_rasterization_properties.conservativePointAndLineRasterization, VK_TRUE); + ASSERT_EQ(conservative_rasterization_properties.degenerateTrianglesRasterized, VK_TRUE); + ASSERT_EQ(conservative_rasterization_properties.degenerateLinesRasterized, VK_TRUE); + ASSERT_EQ(raytracing_pipeline_properties.shaderGroupHandleSize, 32); + ASSERT_EQ(raytracing_pipeline_properties.shaderGroupBaseAlignment, 64); + ASSERT_EQ(raytracing_pipeline_properties.shaderGroupHandleCaptureReplaySize, 32); + ASSERT_EQ(ray_tracing_properties.shaderGroupHandleSize, 32); + ASSERT_EQ(ray_tracing_properties.shaderGroupBaseAlignment, 64); + ASSERT_EQ(texel_buffer_alignment_properties.storageTexelBufferOffsetSingleTexelAlignment, VK_TRUE); + ASSERT_EQ(texel_buffer_alignment_properties.uniformTexelBufferOffsetSingleTexelAlignment, VK_TRUE); + ASSERT_EQ(texel_buffer_alignment_properties.storageTexelBufferOffsetAlignmentBytes, 16); + ASSERT_EQ(texel_buffer_alignment_properties.uniformTexelBufferOffsetAlignmentBytes, 16); + ASSERT_EQ(descriptor_buffer_properties.combinedImageSamplerDescriptorSingleArray, VK_TRUE); + ASSERT_EQ(descriptor_buffer_properties.bufferlessPushDescriptors, VK_TRUE); + ASSERT_EQ(descriptor_buffer_properties.allowSamplerImageViewPostSubmitCreation, VK_TRUE); + ASSERT_EQ(descriptor_buffer_properties.descriptorBufferOffsetAlignment, 4); + ASSERT_EQ(mesh_shader_properties.meshOutputPerVertexGranularity, 32); + ASSERT_EQ(mesh_shader_properties.meshOutputPerPrimitiveGranularity, 32); + ASSERT_EQ(mesh_shader_properties.prefersLocalInvocationVertexOutput, VK_TRUE); + ASSERT_EQ(mesh_shader_properties.prefersLocalInvocationPrimitiveOutput, VK_TRUE); + ASSERT_EQ(mesh_shader_properties.prefersCompactVertexOutput, VK_TRUE); + ASSERT_EQ(mesh_shader_properties.prefersCompactPrimitiveOutput, VK_TRUE); + ASSERT_EQ(fragment_density_map2_properties.subsampledLoads, VK_FALSE); + ASSERT_EQ(fragment_density_map2_properties.subsampledCoarseReconstructionEarlyAccess, VK_FALSE); + ASSERT_EQ(fragment_density_map2_properties.maxSubsampledArrayLayers, 2); + ASSERT_EQ(fragment_density_map2_properties.maxDescriptorSetSubsampledSamplers, 1); + ASSERT_EQ(std::string(driver_properties.driverName), "Vulkan Mock Device"); + ASSERT_EQ(std::string(driver_properties.driverInfo), "Branch: " GIT_BRANCH_NAME " Tag Info: " GIT_TAG_INFO); +} + +TEST_F(MockICD, vkGetPhysicalDeviceExternalSemaphoreProperties) { + VkPhysicalDeviceExternalSemaphoreInfo external_semaphore_info{}; + VkExternalSemaphoreProperties external_semaphore_properties{}; + vkGetPhysicalDeviceExternalSemaphoreProperties(physical_device, &external_semaphore_info, &external_semaphore_properties); + ASSERT_EQ(external_semaphore_properties.exportFromImportedHandleTypes, 0x1F); + ASSERT_EQ(external_semaphore_properties.compatibleHandleTypes, 0x1F); + ASSERT_EQ(external_semaphore_properties.externalSemaphoreFeatures, 0x3); +} + +TEST_F(MockICD, vkGetPhysicalDeviceExternalFenceProperties) { + VkPhysicalDeviceExternalFenceInfo external_fence_info{}; + VkExternalFenceProperties external_fence_properties{}; + vkGetPhysicalDeviceExternalFenceProperties(physical_device, &external_fence_info, &external_fence_properties); + ASSERT_EQ(external_fence_properties.exportFromImportedHandleTypes, 0xF); + ASSERT_EQ(external_fence_properties.compatibleHandleTypes, 0xF); + ASSERT_EQ(external_fence_properties.externalFenceFeatures, 0x3); +} +TEST_F(MockICD, vkGetPhysicalDeviceExternalBufferProperties) { + VkPhysicalDeviceExternalBufferInfo external_buffer_info{}; + external_buffer_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; + VkExternalBufferProperties external_buffer_properties{}; + vkGetPhysicalDeviceExternalBufferProperties(physical_device, &external_buffer_info, &external_buffer_properties); + ASSERT_EQ(external_buffer_properties.externalMemoryProperties.externalMemoryFeatures, 0x7); + ASSERT_EQ(external_buffer_properties.externalMemoryProperties.exportFromImportedHandleTypes, 0x1FF); + ASSERT_EQ(external_buffer_properties.externalMemoryProperties.compatibleHandleTypes, 0x1FF); + + external_buffer_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX; + vkGetPhysicalDeviceExternalBufferProperties(physical_device, &external_buffer_info, &external_buffer_properties); + ASSERT_EQ(external_buffer_properties.externalMemoryProperties.externalMemoryFeatures, 0); + ASSERT_EQ(external_buffer_properties.externalMemoryProperties.exportFromImportedHandleTypes, 0); + ASSERT_EQ(external_buffer_properties.externalMemoryProperties.compatibleHandleTypes, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX); +} + +/* + * Exercises the following commands: + * vkCreateBuffer + * vkGetBufferMemoryRequirements + * vkGetBufferMemoryRequirements2 + * vkGetDeviceBufferMemoryRequirements + * vkAllocateMemory + * vkMapMemory + * vkUnmapMemory + * vkGetBufferDeviceAddress + * vkGetBufferDeviceAddressKHR + * vkGetBufferDeviceAddressEXT + * vkDestroyBuffer + * vkFreeMemory + */ +TEST_F(MockICD, BufferOperations) { + VkResult res = VK_SUCCESS; + + VkBufferCreateInfo buffer_create_info{}; + buffer_create_info.size = 128; + VkBuffer buffer{}; + res = vkCreateBuffer(device, &buffer_create_info, nullptr, &buffer); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(buffer, VK_NULL_HANDLE); + + VkMemoryRequirements memory_requirements{}; + vkGetBufferMemoryRequirements(device, buffer, &memory_requirements); + ASSERT_EQ(memory_requirements.size, 4096); + ASSERT_EQ(memory_requirements.alignment, 1); + ASSERT_EQ(memory_requirements.memoryTypeBits, 0xFFFF); + + VkBufferMemoryRequirementsInfo2 memory_requirements_info2{}; + VkMemoryRequirements2 memory_requirements2{}; + vkGetBufferMemoryRequirements2(device, &memory_requirements_info2, &memory_requirements2); + ASSERT_EQ(memory_requirements2.memoryRequirements.size, 4096); + ASSERT_EQ(memory_requirements2.memoryRequirements.alignment, 1); + ASSERT_EQ(memory_requirements2.memoryRequirements.memoryTypeBits, 0xFFFF); + + VkDeviceBufferMemoryRequirements buffer_memory_requirements{}; + buffer_memory_requirements.pCreateInfo = &buffer_create_info; + vkGetDeviceBufferMemoryRequirements(device, &buffer_memory_requirements, &memory_requirements2); + ASSERT_EQ(memory_requirements2.memoryRequirements.size, 4096); + ASSERT_EQ(memory_requirements2.memoryRequirements.alignment, 1); + ASSERT_EQ(memory_requirements2.memoryRequirements.memoryTypeBits, 0xFFFF); + + VkMemoryAllocateInfo allocate_info{}; + allocate_info.allocationSize = memory_requirements.size; + VkDeviceMemory memory{}; + res = vkAllocateMemory(device, &allocate_info, nullptr, &memory); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(memory, VK_NULL_HANDLE); + + std::array<uint32_t, 32> source_data; + void* data = nullptr; + res = vkMapMemory(device, memory, 0, memory_requirements.size, 0, &data); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(data, nullptr); + memcpy(data, source_data.data(), source_data.size()); + vkUnmapMemory(device, memory); + + VkBufferDeviceAddressInfo buffer_device_address_info{}; + buffer_device_address_info.buffer = buffer; + VkDeviceAddress device_address = vkGetBufferDeviceAddress(device, &buffer_device_address_info); + ASSERT_NE(device_address, 0); + + auto vkGetBufferDeviceAddressEXT = + reinterpret_cast<PFN_vkGetBufferDeviceAddressEXT>(vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressEXT")); + ASSERT_NE(vkGetBufferDeviceAddressEXT, nullptr); + device_address = vkGetBufferDeviceAddressEXT(device, &buffer_device_address_info); + ASSERT_NE(device_address, 0); + + auto vkGetBufferDeviceAddressKHR = + reinterpret_cast<PFN_vkGetBufferDeviceAddressKHR>(vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR")); + ASSERT_NE(vkGetBufferDeviceAddressKHR, nullptr); + device_address = vkGetBufferDeviceAddressKHR(device, &buffer_device_address_info); + ASSERT_NE(device_address, 0); + + vkDestroyBuffer(device, buffer, nullptr); + vkFreeMemory(device, memory, nullptr); +} + +/* + * Exercises the following commands: + * vkCreateImage + * vkGetImageSubresourceLayout + * vkGetImageMemoryRequirements + * vkGetImageMemoryRequirements2 + * vkGetDeviceImageMemoryRequirements + * vkGetImageSparseMemoryRequirements + * vkGetImageSparseMemoryRequirements2 + * vkAllocateMemory + * vkMapMemory2KHR + * vkUnmapMemory2KHR + * vkDestroyImage + * vkFreeMemory + */ +TEST_F(MockICD, ImageOperations) { + VkResult res = VK_SUCCESS; + + VkImageCreateInfo image_create_info{}; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.format = VK_FORMAT_R8G8B8A8_SRGB; + image_create_info.extent = {8, 8, 8}; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.queueFamilyIndexCount = 0; + image_create_info.pQueueFamilyIndices = nullptr; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkImage image{}; + res = vkCreateImage(device, &image_create_info, nullptr, &image); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(image, VK_NULL_HANDLE); + + VkImageSubresource image_subresource{}; + VkSubresourceLayout subresource_layout{}; + vkGetImageSubresourceLayout(device, image, &image_subresource, &subresource_layout); + ASSERT_EQ(subresource_layout.arrayPitch, 0); + ASSERT_EQ(subresource_layout.depthPitch, 0); + ASSERT_EQ(subresource_layout.offset, 0); + ASSERT_EQ(subresource_layout.rowPitch, 0); + ASSERT_EQ(subresource_layout.size, 0); + + VkMemoryRequirements memory_requirements{}; + vkGetImageMemoryRequirements(device, image, &memory_requirements); + ASSERT_EQ(memory_requirements.size, 8 * 8 * 8 * 32 /*refer to GetImageSizeFromCreateInfo for size calc*/); + ASSERT_EQ(memory_requirements.alignment, 1); + ASSERT_EQ(memory_requirements.memoryTypeBits, 0xFFFF & ~(0x1 << 3)); + + VkImageMemoryRequirementsInfo2 memory_requirements_info2{}; + VkMemoryRequirements2 memory_requirements2{}; + vkGetImageMemoryRequirements2(device, &memory_requirements_info2, &memory_requirements2); + ASSERT_EQ(memory_requirements2.memoryRequirements.size, 0); + ASSERT_EQ(memory_requirements2.memoryRequirements.alignment, 1); + ASSERT_EQ(memory_requirements2.memoryRequirements.memoryTypeBits, 0xFFFF & ~(0x1 << 3)); + + VkDeviceImageMemoryRequirements image_memory_requirements{}; + image_memory_requirements.pCreateInfo = &image_create_info; + vkGetDeviceImageMemoryRequirements(device, &image_memory_requirements, &memory_requirements2); + ASSERT_EQ(memory_requirements2.memoryRequirements.size, 8 * 8 * 8 * 32 /*refer to GetImageSizeFromCreateInfo for size calc*/); + ASSERT_EQ(memory_requirements2.memoryRequirements.alignment, 1); + ASSERT_EQ(memory_requirements2.memoryRequirements.memoryTypeBits, 0xFFFF & ~(0x1 << 3)); + + uint32_t count = 0; + vkGetImageSparseMemoryRequirements(device, image, &count, nullptr); + ASSERT_EQ(count, 1); + VkSparseImageMemoryRequirements sparse_image_memory_requirements{}; + vkGetImageSparseMemoryRequirements(device, image, &count, &sparse_image_memory_requirements); + ASSERT_EQ(count, 1); + ASSERT_EQ(sparse_image_memory_requirements.imageMipTailFirstLod, 0); + ASSERT_EQ(sparse_image_memory_requirements.imageMipTailSize, 8); + ASSERT_EQ(sparse_image_memory_requirements.imageMipTailOffset, 0); + ASSERT_EQ(sparse_image_memory_requirements.imageMipTailStride, 4); + ASSERT_EQ(sparse_image_memory_requirements.formatProperties.imageGranularity.width, 4); + ASSERT_EQ(sparse_image_memory_requirements.formatProperties.imageGranularity.height, 4); + ASSERT_EQ(sparse_image_memory_requirements.formatProperties.imageGranularity.depth, 4); + ASSERT_EQ(sparse_image_memory_requirements.formatProperties.flags, VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT); + ASSERT_EQ(sparse_image_memory_requirements.formatProperties.aspectMask, 1 | 2 | 4 | 8); + + count = 0; + VkImageSparseMemoryRequirementsInfo2 sparse_memory_requirement_info2{}; + sparse_memory_requirement_info2.image = image; + vkGetImageSparseMemoryRequirements2(device, &sparse_memory_requirement_info2, &count, nullptr); + ASSERT_EQ(count, 1); + VkSparseImageMemoryRequirements2 sparse_image_memory_reqs2{}; + vkGetImageSparseMemoryRequirements2(device, &sparse_memory_requirement_info2, &count, &sparse_image_memory_reqs2); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.imageMipTailFirstLod, 0); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.imageMipTailSize, 8); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.imageMipTailOffset, 0); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.imageMipTailStride, 4); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.formatProperties.imageGranularity.width, 4); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.formatProperties.imageGranularity.height, 4); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.formatProperties.imageGranularity.depth, 4); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.formatProperties.flags, VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT); + ASSERT_EQ(sparse_image_memory_reqs2.memoryRequirements.formatProperties.aspectMask, 1 | 2 | 4 | 8); + + VkMemoryAllocateInfo allocate_info{}; + allocate_info.allocationSize = memory_requirements.size; + VkDeviceMemory memory{}; + res = vkAllocateMemory(device, &allocate_info, nullptr, &memory); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(memory, VK_NULL_HANDLE); + + auto vkMapMemory2KHR = reinterpret_cast<PFN_vkMapMemory2KHR>(vkGetDeviceProcAddr(device, "vkMapMemory2KHR")); + auto vkUnmapMemory2KHR = reinterpret_cast<PFN_vkUnmapMemory2KHR>(vkGetDeviceProcAddr(device, "vkUnmapMemory2KHR")); + ASSERT_NE(vkMapMemory2KHR, nullptr); + ASSERT_NE(vkUnmapMemory2KHR, nullptr); + + std::array<uint32_t, 32> source_data; + void* data = nullptr; + VkMemoryMapInfoKHR memory_map_info{}; + memory_map_info.memory = memory; + memory_map_info.size = memory_requirements.size; + res = vkMapMemory2KHR(device, &memory_map_info, &data); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(data, nullptr); + memcpy(data, source_data.data(), source_data.size()); + VkMemoryUnmapInfoKHR memory_unmap_info{}; + memory_unmap_info.memory = memory; + vkUnmapMemory2KHR(device, &memory_unmap_info); + + vkDestroyImage(device, image, nullptr); + vkFreeMemory(device, memory, nullptr); +} + +/* + * Exercises the following commands: + * vkCreateSwapchainKHR + * vkGetSwapchainImagesKHR + * vkDestroySwapchainKHR + * vkAcquireNextImageKHR + * vkAcquireNextImage2KHR + */ +TEST_F(MockICD, SwapchainLifeCycle) { + VkResult res = VK_SUCCESS; + VkSurfaceKHR surface{}; + res = create_surface(instance, surface); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(surface, VK_NULL_HANDLE); + + VkSwapchainCreateInfoKHR swapchain_create_info{}; + swapchain_create_info.surface = surface; + swapchain_create_info.minImageCount = 1; + VkSwapchainKHR swapchain{}; + res = vkCreateSwapchainKHR(device, &swapchain_create_info, nullptr, &swapchain); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(swapchain, VK_NULL_HANDLE); + + uint32_t count = 0; + res = vkGetSwapchainImagesKHR(device, swapchain, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + std::array<VkImage, 1> swapchain_images; + res = vkGetSwapchainImagesKHR(device, swapchain, &count, swapchain_images.data()); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_NE(swapchain_images[0], VK_NULL_HANDLE); + + uint32_t image_index = 10; // arbitrary non zero value + res = vkAcquireNextImageKHR(device, swapchain, 0, VK_NULL_HANDLE, VK_NULL_HANDLE, &image_index); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(image_index, 0); + + VkAcquireNextImageInfoKHR acquire_info{}; + acquire_info.swapchain = swapchain; + res = vkAcquireNextImage2KHR(device, &acquire_info, &image_index); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(image_index, 0); + + vkDestroySwapchainKHR(device, swapchain, nullptr); + vkDestroySurfaceKHR(instance, surface, nullptr); +} + +TEST_F(MockICD, vkGetPhysicalDeviceMultisamplePropertiesEXT) { + auto vkGetPhysicalDeviceMultisamplePropertiesEXT = reinterpret_cast<PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT>( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMultisamplePropertiesEXT")); + ASSERT_NE(vkGetPhysicalDeviceMultisamplePropertiesEXT, nullptr); + VkMultisamplePropertiesEXT multisample_properties{}; + vkGetPhysicalDeviceMultisamplePropertiesEXT(physical_device, VK_SAMPLE_COUNT_16_BIT, &multisample_properties); + ASSERT_EQ(multisample_properties.maxSampleLocationGridSize.width, 32); + ASSERT_EQ(multisample_properties.maxSampleLocationGridSize.height, 32); +} + +TEST_F(MockICD, vkGetPhysicalDeviceFragmentShadingRatesKHR) { + auto vkGetPhysicalDeviceFragmentShadingRatesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR>( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFragmentShadingRatesKHR")); + ASSERT_NE(vkGetPhysicalDeviceFragmentShadingRatesKHR, nullptr); + + VkResult res = VK_SUCCESS; + uint32_t count = 0; + res = vkGetPhysicalDeviceFragmentShadingRatesKHR(physical_device, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + + VkPhysicalDeviceFragmentShadingRateKHR fragment_shading_rates{}; + res = vkGetPhysicalDeviceFragmentShadingRatesKHR(physical_device, &count, &fragment_shading_rates); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + ASSERT_EQ(fragment_shading_rates.sampleCounts, VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT); + ASSERT_EQ(fragment_shading_rates.fragmentSize.width, 8); + ASSERT_EQ(fragment_shading_rates.fragmentSize.height, 8); +} + +TEST_F(MockICD, vkGetPhysicalDeviceCalibrateableTimeDomainsEXT) { + auto vkGetPhysicalDeviceCalibrateableTimeDomainsEXT = reinterpret_cast<PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT>( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")); + ASSERT_NE(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, nullptr); + + VkResult res = VK_SUCCESS; + uint32_t count = 0; + res = vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(physical_device, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + + VkTimeDomainEXT time_domain{}; + res = vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(physical_device, &count, &time_domain); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + ASSERT_EQ(time_domain, VK_TIME_DOMAIN_DEVICE_EXT); +} + +#if defined(WIN32) +TEST_F(MockICD, vkGetFenceWin32HandleKHR) { + auto vkGetFenceWin32HandleKHR = + reinterpret_cast<PFN_vkGetFenceWin32HandleKHR>(vkGetDeviceProcAddr(device, "vkGetFenceWin32HandleKHR")); + ASSERT_NE(vkGetFenceWin32HandleKHR, nullptr); + VkFenceGetWin32HandleInfoKHR get_win32_handle_info{}; + HANDLE handle{}; + VkResult res = vkGetFenceWin32HandleKHR(device, &get_win32_handle_info, &handle); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(handle, (HANDLE)0x12345678); +} +#endif // defined(WIN32) + +TEST_F(MockICD, vkGetFenceFdKHR) { + auto vkGetFenceFdKHR = reinterpret_cast<PFN_vkGetFenceFdKHR>(vkGetDeviceProcAddr(device, "vkGetFenceFdKHR")); + ASSERT_NE(vkGetFenceFdKHR, nullptr); + VkFenceGetFdInfoKHR get_win32_handle_info{}; + int handle{}; + VkResult res = vkGetFenceFdKHR(device, &get_win32_handle_info, &handle); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(handle, 0x42); +} + +TEST_F(MockICD, vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR) { + auto vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = + reinterpret_cast<PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR>( + vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR")); + ASSERT_NE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR, nullptr); + + VkResult res = VK_SUCCESS; + uint32_t count = 0; + res = vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(physical_device, 0, &count, nullptr, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 3); + + std::array<VkPerformanceCounterKHR, 3> counters{}; + std::array<VkPerformanceCounterDescriptionKHR, 3> counter_descriptions{}; + res = vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(physical_device, 0, &count, counters.data(), + counter_descriptions.data()); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 3); + ASSERT_EQ(counters[0].unit, VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR); + ASSERT_EQ(counters[0].scope, VK_QUERY_SCOPE_COMMAND_BUFFER_KHR); + ASSERT_EQ(counters[0].storage, VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR); + ASSERT_EQ(counters[0].uuid[0], 0x01); + ASSERT_EQ(counters[1].unit, VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR); + ASSERT_EQ(counters[1].scope, VK_QUERY_SCOPE_RENDER_PASS_KHR); + ASSERT_EQ(counters[1].storage, VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR); + ASSERT_EQ(counters[1].uuid[0], 0x02); + ASSERT_EQ(counters[2].unit, VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR); + ASSERT_EQ(counters[2].scope, VK_QUERY_SCOPE_COMMAND_KHR); + ASSERT_EQ(counters[2].storage, VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR); + ASSERT_EQ(counters[2].uuid[0], 0x03); +} + +TEST_F(MockICD, vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR) { + auto vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = + reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR>( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR")); + ASSERT_NE(vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR, nullptr); + VkQueryPoolPerformanceCreateInfoKHR performance_query_create_info{}; + uint32_t num_passes = 0; + vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(physical_device, &performance_query_create_info, &num_passes); + ASSERT_EQ(num_passes, 1); +} + +TEST_F(MockICD, vkGetShaderModuleIdentifierEXT) { + auto vkGetShaderModuleIdentifierEXT = + reinterpret_cast<PFN_vkGetShaderModuleIdentifierEXT>(vkGetDeviceProcAddr(device, "vkGetShaderModuleIdentifierEXT")); + ASSERT_NE(vkGetShaderModuleIdentifierEXT, nullptr); + VkShaderModule shader_module{}; + VkShaderModuleIdentifierEXT identifier{}; + vkGetShaderModuleIdentifierEXT(device, shader_module, &identifier); + ASSERT_EQ(identifier.identifierSize, 1); + ASSERT_EQ(identifier.identifier[0], 0x01); +} + +TEST_F(MockICD, vkGetDescriptorSetLayoutSizeEXT) { + auto vkGetDescriptorSetLayoutSizeEXT = + reinterpret_cast<PFN_vkGetDescriptorSetLayoutSizeEXT>(vkGetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSizeEXT")); + ASSERT_NE(vkGetDescriptorSetLayoutSizeEXT, nullptr); + + VkDescriptorSetLayout layout{}; + VkDeviceSize layout_size_in_bytes = 0; + vkGetDescriptorSetLayoutSizeEXT(device, layout, &layout_size_in_bytes); + ASSERT_EQ(layout_size_in_bytes, 4); +} + +TEST_F(MockICD, vkGetAccelerationStructureBuildSizesKHR) { + auto vkGetAccelerationStructureBuildSizesKHR = reinterpret_cast<PFN_vkGetAccelerationStructureBuildSizesKHR>( + vkGetDeviceProcAddr(device, "vkGetAccelerationStructureBuildSizesKHR")); + ASSERT_NE(vkGetAccelerationStructureBuildSizesKHR, nullptr); + + VkAccelerationStructureBuildGeometryInfoKHR build_info{}; + uint32_t max_primitive_count = 0; + VkAccelerationStructureBuildSizesInfoKHR size_info{}; + vkGetAccelerationStructureBuildSizesKHR(device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &build_info, + &max_primitive_count, &size_info); + ASSERT_EQ(size_info.accelerationStructureSize, 4); + ASSERT_EQ(size_info.updateScratchSize, 4); + ASSERT_EQ(size_info.buildScratchSize, 4); +} + +TEST_F(MockICD, vkGetAccelerationStructureMemoryRequirementsNV) { + auto vkGetAccelerationStructureMemoryRequirementsNV = reinterpret_cast<PFN_vkGetAccelerationStructureMemoryRequirementsNV>( + vkGetDeviceProcAddr(device, "vkGetAccelerationStructureMemoryRequirementsNV")); + ASSERT_NE(vkGetAccelerationStructureMemoryRequirementsNV, nullptr); + + VkAccelerationStructureMemoryRequirementsInfoNV acceleration_structure_memory_requirements_info{}; + VkMemoryRequirements2KHR memory_requirements{}; + vkGetAccelerationStructureMemoryRequirementsNV(device, &acceleration_structure_memory_requirements_info, &memory_requirements); + ASSERT_EQ(memory_requirements.memoryRequirements.size, 4096); + ASSERT_EQ(memory_requirements.memoryRequirements.alignment, 1); + ASSERT_EQ(memory_requirements.memoryRequirements.memoryTypeBits, 0xFFFF); +} + +TEST_F(MockICD, vkGetVideoSessionMemoryRequirementsKHR) { + auto vkGetVideoSessionMemoryRequirementsKHR = reinterpret_cast<PFN_vkGetVideoSessionMemoryRequirementsKHR>( + vkGetDeviceProcAddr(device, "vkGetVideoSessionMemoryRequirementsKHR")); + ASSERT_NE(vkGetVideoSessionMemoryRequirementsKHR, nullptr); + + VkVideoSessionKHR video_session{}; + uint32_t count = 0; + VkResult res = vkGetVideoSessionMemoryRequirementsKHR(device, video_session, &count, nullptr); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + VkVideoSessionMemoryRequirementsKHR memory_requirements{}; + res = vkGetVideoSessionMemoryRequirementsKHR(device, video_session, &count, &memory_requirements); + ASSERT_EQ(res, VK_SUCCESS); + ASSERT_EQ(count, 1); + ASSERT_EQ(memory_requirements.memoryBindIndex, 0); + ASSERT_EQ(memory_requirements.memoryRequirements.size, 4096); + ASSERT_EQ(memory_requirements.memoryRequirements.alignment, 1); + ASSERT_EQ(memory_requirements.memoryRequirements.memoryTypeBits, 0xFFFF); +} + +TEST_F(MockICD, vkGetPhysicalDeviceVideoFormatPropertiesKHR) { + auto vkGetPhysicalDeviceVideoFormatPropertiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR>( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR")); + ASSERT_NE(vkGetPhysicalDeviceVideoFormatPropertiesKHR, nullptr); + + VkVideoDecodeH264ProfileInfoKHR decode_h264_profile_info{}; + decode_h264_profile_info.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR; + decode_h264_profile_info.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + decode_h264_profile_info.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR; + VkVideoProfileInfoKHR video_profile_info{}; + video_profile_info.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR; + video_profile_info.pNext = &decode_h264_profile_info; + video_profile_info.videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR; + video_profile_info.chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR; + video_profile_info.lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR; + video_profile_info.chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR; + VkVideoProfileListInfoKHR video_profile_list{}; + video_profile_list.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR; + video_profile_list.profileCount = 1; + video_profile_list.pProfiles = &video_profile_info; + VkPhysicalDeviceVideoFormatInfoKHR video_format_info{}; + video_format_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR; + video_format_info.pNext = &video_profile_list; + uint32_t count = 0; + VkResult res = vkGetPhysicalDeviceVideoFormatPropertiesKHR(physical_device, &video_format_info, &count, nullptr); + ASSERT_EQ(res, VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR); +} + +TEST_F(MockICD, vkGetPhysicalDeviceVideoCapabilitiesKHR) { + auto vkGetPhysicalDeviceVideoCapabilitiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR>( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR")); + ASSERT_NE(vkGetPhysicalDeviceVideoCapabilitiesKHR, nullptr); + + VkVideoDecodeH264ProfileInfoKHR decode_h264_profile_info{}; + decode_h264_profile_info.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR; + decode_h264_profile_info.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + decode_h264_profile_info.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR; + VkVideoProfileInfoKHR video_profile_info{}; + video_profile_info.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR; + video_profile_info.pNext = &decode_h264_profile_info; + video_profile_info.videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR; + video_profile_info.chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR; + video_profile_info.lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR; + video_profile_info.chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR; + VkVideoDecodeH264CapabilitiesKHR decode_h264_capabilities{}; + decode_h264_capabilities.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR; + VkVideoDecodeCapabilitiesKHR decode_capabilities{}; + decode_capabilities.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR; + decode_capabilities.pNext = &decode_h264_capabilities; + VkVideoCapabilitiesKHR video_capabilities{}; + video_capabilities.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR; + video_capabilities.pNext = &decode_capabilities; + VkResult res = vkGetPhysicalDeviceVideoCapabilitiesKHR(physical_device, &video_profile_info, &video_capabilities); + ASSERT_EQ(res, VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR); +} + +TEST_F(MockICD, vkGetDescriptorSetLayoutSupport) { + VkDescriptorSetLayoutCreateInfo create_info{}; + VkDescriptorSetLayoutSupport support{}; + vkGetDescriptorSetLayoutSupport(device, &create_info, &support); + ASSERT_EQ(support.supported, VK_TRUE); +} + +TEST_F(MockICD, vkGetDescriptorSetLayoutSupportKHR) { + auto vkGetDescriptorSetLayoutSupportKHR = + reinterpret_cast<PFN_vkGetDescriptorSetLayoutSupportKHR>(vkGetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupportKHR")); + ASSERT_NE(vkGetDescriptorSetLayoutSupportKHR, nullptr); + + VkDescriptorSetLayoutCreateInfo create_info{}; + VkDescriptorSetLayoutSupport support{}; + vkGetDescriptorSetLayoutSupportKHR(device, &create_info, &support); + ASSERT_EQ(support.supported, VK_TRUE); +} + +TEST_F(MockICD, vkGetRenderAreaGranularity) { + VkRenderPass render_pass{}; + VkExtent2D granularity{}; + vkGetRenderAreaGranularity(device, render_pass, &granularity); + ASSERT_EQ(granularity.width, 1); + ASSERT_EQ(granularity.height, 1); +} diff --git a/tools/Vulkan-Tools/tests/main.cpp b/tools/Vulkan-Tools/tests/main.cpp new file mode 100644 index 00000000..31131426 --- /dev/null +++ b/tools/Vulkan-Tools/tests/main.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 The Khronos Group Inc. + * Copyright (c) 2023 Valve Corporation + * Copyright (c) 2023 LunarG, Inc. + * + * 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. + * + */ + +#if defined(_WIN32) && !defined(NDEBUG) +#include <crtdbg.h> +#endif + +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + int result; + + ::testing::InitGoogleTest(&argc, argv); + + result = RUN_ALL_TESTS(); + + return result; +} diff --git a/tools/Vulkan-Tools/tests/test_common.h b/tools/Vulkan-Tools/tests/test_common.h new file mode 100644 index 00000000..72df9067 --- /dev/null +++ b/tools/Vulkan-Tools/tests/test_common.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 The Khronos Group Inc. + * Copyright (c) 2023 Valve Corporation + * Copyright (c) 2023 LunarG, Inc. + * + * 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. + * + */ + +#include <stdlib.h> + +#include <array> +#include <iostream> +#include <vector> + +#include "gtest/gtest.h" +#include "vulkan/vulkan.h" + +#if defined(WIN32) +#include <windows.h> +inline int set_environment_var(const char* name, const char* value) { return SetEnvironmentVariable(name, value); } +#else +inline int set_environment_var(const char* name, const char* value) { return setenv(name, value, 1); } +#endif |
