// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// 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.
// Vulkan unit tests that provide coverage for functionality not tested by
// the dEQP test suite. Also used as a smoke test.
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <vulkan/vulkan.h>
#include <vulkan/vk_icd.h>
#include <cstring>
typedef PFN_vkVoidFunction(__stdcall *vk_icdGetInstanceProcAddrPtr)(VkInstance, const char*);
#if defined(_WIN32)
#include <Windows.h>
#endif
class SwiftShaderVulkanTest : public testing::Test
{
protected:
void SetUp() override
{
HMODULE libVulkan = nullptr;
const char* libVulkanName = nullptr;
#if defined(_WIN64)
#if defined(NDEBUG)
libVulkanName = "../../out/Release_x64/vk_swiftshader.dll";
#else
libVulkanName = "../../out/Debug_x64/vk_swiftshader.dll";
#endif
#else
#error Unimplemented platform
#endif
#if defined(_WIN32)
libVulkan = LoadLibraryA(libVulkanName);
EXPECT_NE((HMODULE)NULL, libVulkan);
vk_icdGetInstanceProcAddr = (vk_icdGetInstanceProcAddrPtr)GetProcAddress(libVulkan, "vk_icdGetInstanceProcAddr");
EXPECT_NE((vk_icdGetInstanceProcAddrPtr)nullptr, vk_icdGetInstanceProcAddr);
#endif
}
vk_icdGetInstanceProcAddrPtr vk_icdGetInstanceProcAddr = nullptr;
};
TEST_F(SwiftShaderVulkanTest, ICD_Check)
{
if(vk_icdGetInstanceProcAddr)
{
auto createInstance = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance");
EXPECT_NE(createInstance, nullptr);
auto enumerateInstanceExtensionProperties = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
EXPECT_NE(enumerateInstanceExtensionProperties, nullptr);
auto enumerateInstanceLayerProperties = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceLayerProperties");
EXPECT_NE(enumerateInstanceLayerProperties, nullptr);
auto enumerateInstanceVersion = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion");
EXPECT_NE(enumerateInstanceVersion, nullptr);
auto bad_function = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "bad_function");
EXPECT_EQ(bad_function, nullptr);
}
}
TEST_F(SwiftShaderVulkanTest, Version)
{
uint32_t apiVersion = 0;
VkResult result = vkEnumerateInstanceVersion(&apiVersion);
EXPECT_EQ(apiVersion, VK_API_VERSION_1_1);
const VkInstanceCreateInfo createInfo =
{
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
nullptr, // pApplicationInfo
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames
};
VkInstance instance = VK_NULL_HANDLE;
result = vkCreateInstance(&createInfo, nullptr, &instance);
EXPECT_EQ(result, VK_SUCCESS);
uint32_t pPhysicalDeviceCount = 0;
result = vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, nullptr);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_EQ(pPhysicalDeviceCount, 1);
VkPhysicalDevice pPhysicalDevice = VK_NULL_HANDLE;
result = vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, &pPhysicalDevice);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(pPhysicalDevice, (VkPhysicalDevice)VK_NULL_HANDLE);
VkPhysicalDeviceProperties physicalDeviceProperties;
vkGetPhysicalDeviceProperties(pPhysicalDevice, &physicalDeviceProperties);
EXPECT_EQ(physicalDeviceProperties.apiVersion, VK_API_VERSION_1_1);
EXPECT_EQ(physicalDeviceProperties.deviceID, 0xC0DE);
EXPECT_EQ(physicalDeviceProperties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
EXPECT_EQ(strncmp(physicalDeviceProperties.deviceName, "SwiftShader Device", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE), 0);
}