• 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(
103                         *k_vk, m_vkSurface, device, k_width, k_height,
104                         {queueFamilyIndex}) == nullptr) {
105                     continue;
106                 }
107                 break;
108             }
109             if (queueFamilyIndex == queueFamilyCount) {
110                 continue;
111             }
112 
113             m_swapChainQueueFamilyIndex = queueFamilyIndex;
114             m_vkPhysicalDevice = device;
115             return;
116         }
117         FAIL() << "Can't find a suitable VkPhysicalDevice.";
118     }
119 
createLogicalDevice()120     void createLogicalDevice() {
121         const float queuePriority = 1.0f;
122         VkDeviceQueueCreateInfo queueCi = {
123             .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
124             .queueFamilyIndex = m_swapChainQueueFamilyIndex,
125             .queueCount = 1,
126             .pQueuePriorities = &queuePriority};
127         VkPhysicalDeviceFeatures features = {};
128         const std::vector<const char *> enabledDeviceExtensions =
129             SwapChainStateVk::getRequiredDeviceExtensions();
130         VkDeviceCreateInfo deviceCi = {
131             .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
132             .queueCreateInfoCount = 1,
133             .pQueueCreateInfos = &queueCi,
134             .enabledLayerCount = 0,
135             .enabledExtensionCount =
136                 static_cast<uint32_t>(enabledDeviceExtensions.size()),
137             .ppEnabledExtensionNames = enabledDeviceExtensions.data(),
138             .pEnabledFeatures = &features};
139         ASSERT_EQ(k_vk->vkCreateDevice(m_vkPhysicalDevice, &deviceCi, nullptr,
140                                        &m_vkDevice),
141                   VK_SUCCESS);
142         ASSERT_TRUE(m_vkDevice != VK_NULL_HANDLE);
143     }
144 };
145 
146 goldfish_vk::VulkanDispatch *SwapChainStateVkTest::k_vk = nullptr;
147 
TEST_F(SwapChainStateVkTest,init)148 TEST_F(SwapChainStateVkTest, init) {
149     auto swapChainCi = SwapChainStateVk::createSwapChainCi(
150         *k_vk, m_vkSurface, m_vkPhysicalDevice, k_width, k_height,
151         {m_swapChainQueueFamilyIndex});
152     ASSERT_NE(swapChainCi, nullptr);
153     SwapChainStateVk swapChainState(*k_vk, m_vkDevice, *swapChainCi);
154 }