• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 
3 #include "SwapChainStateVk.h"
4 
5 #include "Standalone.h"
6 #include "vulkan/VulkanDispatch.h"
7 
8 class SwapChainStateVkTest : public ::testing::Test {
9    protected:
SetUpTestCase()10     static void SetUpTestCase() { k_vk = emugl::vkDispatch(false); }
11 
SetUp()12     void SetUp() override {
13         // skip the test when testing without a window
14         if (!emugl::shouldUseWindow()) {
15             GTEST_SKIP();
16         }
17         ASSERT_NE(k_vk, nullptr);
18 
19         createInstance();
20         createWindowAndSurface();
21         pickPhysicalDevice();
22         createLogicalDevice();
23     }
24 
TearDown()25     void TearDown() override {
26         if (emugl::shouldUseWindow()) {
27             k_vk->vkDestroyDevice(m_vkDevice, nullptr);
28             k_vk->vkDestroySurfaceKHR(m_vkInstance, m_vkSurface, nullptr);
29             k_vk->vkDestroyInstance(m_vkInstance, nullptr);
30         }
31     }
32 
33     static goldfish_vk::VulkanDispatch *k_vk;
34     static const uint32_t k_width = 0x100;
35     static const uint32_t k_height = 0x100;
36 
37     OSWindow *m_window;
38     VkInstance m_vkInstance = VK_NULL_HANDLE;
39     VkSurfaceKHR m_vkSurface = VK_NULL_HANDLE;
40     VkPhysicalDevice m_vkPhysicalDevice = VK_NULL_HANDLE;
41     uint32_t m_swapChainQueueFamilyIndex = 0;
42     VkDevice m_vkDevice = VK_NULL_HANDLE;
43 
44    private:
createInstance()45     void createInstance() {
46         VkApplicationInfo appInfo = {
47             .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
48             .pNext = nullptr,
49             .pApplicationName = "emulator SwapChainStateVk unittest",
50             .applicationVersion = VK_MAKE_VERSION(1, 0, 0),
51             .pEngineName = "No Engine",
52             .engineVersion = VK_MAKE_VERSION(1, 0, 0),
53             .apiVersion = VK_API_VERSION_1_1};
54         auto extensions = SwapChainStateVk::getRequiredInstanceExtensions();
55         VkInstanceCreateInfo instanceCi = {
56             .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
57             .pApplicationInfo = &appInfo,
58             .enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
59             .ppEnabledExtensionNames = extensions.data()};
60         ASSERT_EQ(k_vk->vkCreateInstance(&instanceCi, nullptr, &m_vkInstance),
61                   VK_SUCCESS);
62         ASSERT_TRUE(m_vkInstance != VK_NULL_HANDLE);
63     }
64 
createWindowAndSurface()65     void createWindowAndSurface() {
66         m_window = emugl::createOrGetTestWindow(0, 0, k_width, k_height);
67         ASSERT_NE(m_window, nullptr);
68         // TODO(kaiyili, b/179477624): add support for other platforms
69 #ifdef _WIN32
70         VkWin32SurfaceCreateInfoKHR surfaceCi = {
71             .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
72             .hinstance = GetModuleHandle(nullptr),
73             .hwnd = m_window->getNativeWindow()};
74         ASSERT_EQ(k_vk->vkCreateWin32SurfaceKHR(m_vkInstance, &surfaceCi,
75                                                 nullptr, &m_vkSurface),
76                   VK_SUCCESS);
77 #endif
78     }
79 
pickPhysicalDevice()80     void pickPhysicalDevice() {
81         uint32_t physicalDeviceCount = 0;
82         ASSERT_EQ(k_vk->vkEnumeratePhysicalDevices(
83                       m_vkInstance, &physicalDeviceCount, nullptr),
84                   VK_SUCCESS);
85         ASSERT_GT(physicalDeviceCount, 0);
86         std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
87         ASSERT_EQ(
88             k_vk->vkEnumeratePhysicalDevices(m_vkInstance, &physicalDeviceCount,
89                                              physicalDevices.data()),
90             VK_SUCCESS);
91         for (const auto &device : physicalDevices) {
92             uint32_t queueFamilyCount = 0;
93             k_vk->vkGetPhysicalDeviceQueueFamilyProperties(
94                 device, &queueFamilyCount, nullptr);
95             ASSERT_GT(queueFamilyCount, 0);
96             uint32_t queueFamilyIndex = 0;
97             for (; queueFamilyIndex < queueFamilyCount; queueFamilyIndex++) {
98                 if (!SwapChainStateVk::validateQueueFamilyProperties(
99                         *k_vk, device, m_vkSurface, queueFamilyIndex)) {
100                     continue;
101                 }
102                 if (!SwapChainStateVk::createSwapChainCi(*k_vk, m_vkSurface, device, k_width,
103                                                          k_height, {queueFamilyIndex})) {
104                     continue;
105                 }
106                 break;
107             }
108             if (queueFamilyIndex == queueFamilyCount) {
109                 continue;
110             }
111 
112             m_swapChainQueueFamilyIndex = queueFamilyIndex;
113             m_vkPhysicalDevice = device;
114             return;
115         }
116         FAIL() << "Can't find a suitable VkPhysicalDevice.";
117     }
118 
createLogicalDevice()119     void createLogicalDevice() {
120         const float queuePriority = 1.0f;
121         VkDeviceQueueCreateInfo queueCi = {
122             .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
123             .queueFamilyIndex = m_swapChainQueueFamilyIndex,
124             .queueCount = 1,
125             .pQueuePriorities = &queuePriority};
126         VkPhysicalDeviceFeatures features = {};
127         const std::vector<const char *> enabledDeviceExtensions =
128             SwapChainStateVk::getRequiredDeviceExtensions();
129         VkDeviceCreateInfo deviceCi = {
130             .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
131             .queueCreateInfoCount = 1,
132             .pQueueCreateInfos = &queueCi,
133             .enabledLayerCount = 0,
134             .enabledExtensionCount =
135                 static_cast<uint32_t>(enabledDeviceExtensions.size()),
136             .ppEnabledExtensionNames = enabledDeviceExtensions.data(),
137             .pEnabledFeatures = &features};
138         ASSERT_EQ(k_vk->vkCreateDevice(m_vkPhysicalDevice, &deviceCi, nullptr,
139                                        &m_vkDevice),
140                   VK_SUCCESS);
141         ASSERT_TRUE(m_vkDevice != VK_NULL_HANDLE);
142     }
143 };
144 
145 goldfish_vk::VulkanDispatch *SwapChainStateVkTest::k_vk = nullptr;
146 
TEST_F(SwapChainStateVkTest,init)147 TEST_F(SwapChainStateVkTest, init) {
148     auto swapChainCi = SwapChainStateVk::createSwapChainCi(
149         *k_vk, m_vkSurface, m_vkPhysicalDevice, k_width, k_height,
150         {m_swapChainQueueFamilyIndex});
151     ASSERT_NE(swapChainCi, std::nullopt);
152     SwapChainStateVk swapChainState(*k_vk, m_vkDevice, swapChainCi->mCreateInfo);
153 }