1 /*
2 * Copyright (c) 2021-2022 The Khronos Group Inc.
3 * Copyright (c) 2021-2022 Valve Corporation
4 * Copyright (c) 2021-2022 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials are
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice(s) and this permission notice shall be included in
14 * all copies or substantial portions of the Materials.
15 *
16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS.
24 *
25 * Author: Charles Giessen <charles@lunarg.com>
26 */
27
28 #include "test_environment.h"
29
30 class WsiTests : public ::testing::Test {};
31
32 #if defined(VK_USE_PLATFORM_WIN32_KHR)
33
34 // When ICD doesn't support the extension, create instance should fail
TEST(WsiTests, CreateSurfaceWin32NoICDSupport)35 TEST(WsiTests, CreateSurfaceWin32NoICDSupport) {
36 FrameworkEnvironment env{};
37 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
38 auto& cur_icd = env.get_test_icd(0);
39 cur_icd.set_min_icd_interface_version(5);
40
41 InstWrapper inst{env.vulkan_functions};
42 inst.create_info.add_extensions({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
43 inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
44
45 InstWrapper inst2{env.vulkan_functions};
46 inst2.CheckCreate();
47
48 ASSERT_EQ(nullptr, env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkCreateWin32SurfaceKHR"));
49 }
50
51 // When ICD doesn't support the surface creation, the loader should handle it
TEST(WsiTests, CreateSurfaceWin32NoICDCreateSupport)52 TEST(WsiTests, CreateSurfaceWin32NoICDCreateSupport) {
53 FrameworkEnvironment env{};
54 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
55 auto& cur_icd = env.get_test_icd(0);
56 cur_icd.set_min_icd_interface_version(5);
57 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
58 cur_icd.add_instance_extension({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
59 cur_icd.enable_icd_wsi = false;
60
61 InstWrapper inst{env.vulkan_functions};
62 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
63 inst.CheckCreate();
64
65 VkSurfaceKHR surface{VK_NULL_HANDLE};
66 VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
67 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(inst, &surf_create_info, nullptr, &surface));
68 ASSERT_TRUE(surface != VK_NULL_HANDLE);
69
70 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
71 }
72
73 // When ICD does support the surface creation, the loader should delegat handle it to the ICD
TEST(WsiTests, CreateSurfaceWin32ICDSupport)74 TEST(WsiTests, CreateSurfaceWin32ICDSupport) {
75 FrameworkEnvironment env{};
76 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
77 auto& cur_icd = env.get_test_icd(0);
78 cur_icd.set_min_icd_interface_version(5);
79 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
80 cur_icd.add_instance_extension({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
81 cur_icd.enable_icd_wsi = true;
82
83 InstWrapper inst{env.vulkan_functions};
84 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
85 inst.CheckCreate();
86
87 VkSurfaceKHR surface{VK_NULL_HANDLE};
88 VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
89 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(inst, &surf_create_info, nullptr, &surface));
90 ASSERT_TRUE(surface != VK_NULL_HANDLE);
91
92 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
93 }
94
95 // Some drivers supporting vkCreateWin32SurfaceKHR, and at least one that doesn't
TEST(WsiTests, CreateSurfaceWin32MixedICDSupport)96 TEST(WsiTests, CreateSurfaceWin32MixedICDSupport) {
97 FrameworkEnvironment env{};
98 for (uint32_t icd = 0; icd < 3; ++icd) {
99 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
100 Extension second_ext{VK_KHR_WIN32_SURFACE_EXTENSION_NAME};
101 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
102 auto& cur_icd = env.get_test_icd(icd);
103 cur_icd.icd_api_version = VK_API_VERSION_1_0;
104 cur_icd.add_instance_extensions({first_ext, second_ext});
105 if (icd < 2) {
106 // Only enable ICD for first two
107 cur_icd.enable_icd_wsi = true;
108 }
109 }
110
111 InstWrapper instance(env.vulkan_functions);
112 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
113 instance.CheckCreate();
114
115 VkSurfaceKHR surface{VK_NULL_HANDLE};
116 VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
117 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(instance.inst, &surf_create_info, nullptr, &surface));
118 ASSERT_TRUE(surface != VK_NULL_HANDLE);
119
120 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
121 }
122
TEST(WsiTests, GetPhysicalDeviceWin32PresentNoICDSupport)123 TEST(WsiTests, GetPhysicalDeviceWin32PresentNoICDSupport) {
124 FrameworkEnvironment env{};
125 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
126 auto& cur_icd = env.get_test_icd(0);
127 cur_icd.set_min_icd_interface_version(5);
128 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
129 cur_icd.add_instance_extension({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
130 cur_icd.physical_devices.emplace_back("physical_device_0");
131 cur_icd.enable_icd_wsi = false;
132
133 InstWrapper inst{env.vulkan_functions};
134 inst.create_info.add_extensions(
135 {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME});
136 inst.CheckCreate();
137
138 uint32_t driver_count = 1;
139 VkPhysicalDevice physical_device;
140 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
141 ASSERT_EQ(driver_count, 1U);
142
143 DebugUtilsWrapper log{inst};
144 CreateDebugUtilsMessenger(log);
145 auto res = env.vulkan_functions.vkGetPhysicalDeviceWin32PresentationSupportKHR(physical_device, 0);
146 ASSERT_EQ(res, VK_FALSE);
147 ASSERT_TRUE(log.find("ICD for selected physical device does not export vkGetPhysicalDeviceWin32PresentationSupportKHR!"));
148 }
149
TEST(WsiTests, GetPhysicalDeviceWin32PresentICDSupport)150 TEST(WsiTests, GetPhysicalDeviceWin32PresentICDSupport) {
151 FrameworkEnvironment env{};
152 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
153 auto& cur_icd = env.get_test_icd(0);
154 cur_icd.set_min_icd_interface_version(5);
155 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
156 cur_icd.add_instance_extension({VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
157 cur_icd.physical_devices.emplace_back("physical_device_0");
158 cur_icd.enable_icd_wsi = true;
159
160 InstWrapper inst{env.vulkan_functions};
161 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
162 inst.CheckCreate();
163
164 uint32_t driver_count = 1;
165 VkPhysicalDevice physical_device;
166 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
167 ASSERT_EQ(driver_count, 1U);
168
169 ASSERT_EQ(VK_TRUE, env.vulkan_functions.vkGetPhysicalDeviceWin32PresentationSupportKHR(physical_device, 0));
170 }
171
TEST(WsiTests, Win32GetPhysicalDeviceSurfaceSupportKHR)172 TEST(WsiTests, Win32GetPhysicalDeviceSurfaceSupportKHR) {
173 FrameworkEnvironment env{};
174 const uint32_t max_device_count = 4;
175 for (uint32_t icd = 0; icd < max_device_count; ++icd) {
176 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
177 Extension second_ext{VK_KHR_WIN32_SURFACE_EXTENSION_NAME};
178 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
179 auto& cur_icd = env.get_test_icd(icd);
180 cur_icd.icd_api_version = VK_API_VERSION_1_0;
181 cur_icd.set_min_icd_interface_version(5);
182 cur_icd.add_instance_extensions({first_ext, second_ext});
183 std::string dev_name = "phys_dev_" + std::to_string(icd);
184 cur_icd.physical_devices.emplace_back(dev_name.c_str());
185 cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
186 cur_icd.enable_icd_wsi = true;
187 }
188
189 InstWrapper instance(env.vulkan_functions);
190 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME});
191 instance.CheckCreate();
192
193 VkSurfaceKHR surface{VK_NULL_HANDLE};
194 VkWin32SurfaceCreateInfoKHR surf_create_info{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR};
195 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWin32SurfaceKHR(instance.inst, &surf_create_info, nullptr, &surface));
196 ASSERT_TRUE(surface != VK_NULL_HANDLE);
197
198 uint32_t device_count = max_device_count;
199 std::array<VkPhysicalDevice, max_device_count> phys_devs;
200 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(instance.inst, &device_count, phys_devs.data()));
201 ASSERT_EQ(device_count, max_device_count);
202
203 for (uint32_t pd = 0; pd < max_device_count; ++pd) {
204 VkBool32 supported = VK_FALSE;
205 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
206 }
207
208 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
209 }
210 #endif
211
212 #if defined(VK_USE_PLATFORM_XCB_KHR)
213 // When ICD doesn't support the extension, create instance should fail
TEST(WsiTests, CreateSurfaceXCBNoICDSupport)214 TEST(WsiTests, CreateSurfaceXCBNoICDSupport) {
215 FrameworkEnvironment env{};
216 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
217 auto& cur_icd = env.get_test_icd(0);
218 cur_icd.set_min_icd_interface_version(5);
219 cur_icd.enable_icd_wsi = false;
220
221 InstWrapper inst{env.vulkan_functions};
222 inst.create_info.add_extensions({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
223 inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
224
225 InstWrapper inst2{env.vulkan_functions};
226 inst2.CheckCreate();
227
228 ASSERT_EQ(nullptr, env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkCreateXcbSurfaceKHR"));
229 }
230
231 // When ICD doesn't support the surface creation, the loader should handle it
TEST(WsiTests, CreateSurfaceXCBNoICDCreateSupport)232 TEST(WsiTests, CreateSurfaceXCBNoICDCreateSupport) {
233 FrameworkEnvironment env{};
234 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
235 auto& cur_icd = env.get_test_icd(0);
236 cur_icd.set_min_icd_interface_version(5);
237 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
238 cur_icd.add_instance_extension({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
239 cur_icd.enable_icd_wsi = false;
240
241 InstWrapper inst{env.vulkan_functions};
242 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME});
243 inst.CheckCreate();
244
245 VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
246
247 VkSurfaceKHR surface{VK_NULL_HANDLE};
248 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXcbSurfaceKHR(inst, &xcb_createInfo, nullptr, &surface));
249 ASSERT_TRUE(surface != VK_NULL_HANDLE);
250
251 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
252 }
253
254 // When ICD does support the surface creation, the loader should delegat handle it to the ICD
TEST(WsiTests, CreateSurfaceXCBICDSupport)255 TEST(WsiTests, CreateSurfaceXCBICDSupport) {
256 FrameworkEnvironment env{};
257 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
258 auto& cur_icd = env.get_test_icd(0);
259 cur_icd.set_min_icd_interface_version(5);
260 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
261 cur_icd.add_instance_extension({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
262 cur_icd.enable_icd_wsi = true;
263
264 InstWrapper inst{env.vulkan_functions};
265 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME});
266 inst.CheckCreate();
267
268 VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
269
270 VkSurfaceKHR surface{VK_NULL_HANDLE};
271 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXcbSurfaceKHR(inst, &xcb_createInfo, nullptr, &surface));
272 ASSERT_TRUE(surface != VK_NULL_HANDLE);
273
274 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
275 }
276
277 // Some drivers supporting vkCreateXcbSurfaceKHR, and at least one that doesn't
TEST(WsiTests, CreateSurfaceXCBMixedICDSupport)278 TEST(WsiTests, CreateSurfaceXCBMixedICDSupport) {
279 FrameworkEnvironment env{};
280 for (uint32_t icd = 0; icd < 3; ++icd) {
281 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
282 Extension second_ext{VK_KHR_XCB_SURFACE_EXTENSION_NAME};
283 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
284 auto& cur_icd = env.get_test_icd(icd);
285 cur_icd.icd_api_version = VK_API_VERSION_1_0;
286 cur_icd.add_instance_extensions({first_ext, second_ext});
287 if (icd < 2) {
288 // Only enable ICD for first two
289 cur_icd.enable_icd_wsi = true;
290 }
291 }
292
293 InstWrapper instance(env.vulkan_functions);
294 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME});
295 instance.CheckCreate();
296
297 VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
298
299 VkSurfaceKHR surface{VK_NULL_HANDLE};
300 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXcbSurfaceKHR(instance.inst, &xcb_createInfo, nullptr, &surface));
301 ASSERT_TRUE(surface != VK_NULL_HANDLE);
302
303 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
304 }
305
TEST(WsiTests, GetPhysicalDeviceXcbPresentNoICDSupport)306 TEST(WsiTests, GetPhysicalDeviceXcbPresentNoICDSupport) {
307 FrameworkEnvironment env{};
308 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
309 auto& cur_icd = env.get_test_icd(0);
310 cur_icd.set_min_icd_interface_version(5);
311 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
312 cur_icd.add_instance_extension({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
313 cur_icd.physical_devices.emplace_back("physical_device_0");
314 cur_icd.enable_icd_wsi = false;
315
316 InstWrapper inst{env.vulkan_functions};
317 inst.create_info.add_extensions(
318 {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME});
319 inst.CheckCreate();
320
321 uint32_t driver_count = 1;
322 VkPhysicalDevice physical_device;
323 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
324 ASSERT_EQ(driver_count, 1U);
325
326 DebugUtilsWrapper log{inst};
327 CreateDebugUtilsMessenger(log);
328 auto res = env.vulkan_functions.vkGetPhysicalDeviceXcbPresentationSupportKHR(physical_device, 0, nullptr, 0);
329 ASSERT_EQ(res, VK_FALSE);
330 ASSERT_TRUE(log.find("ICD for selected physical device does not export vkGetPhysicalDeviceXcbPresentationSupportKHR!"));
331 }
332
TEST(WsiTests, GetPhysicalDeviceXcbPresentICDSupport)333 TEST(WsiTests, GetPhysicalDeviceXcbPresentICDSupport) {
334 FrameworkEnvironment env{};
335 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
336 auto& cur_icd = env.get_test_icd(0);
337 cur_icd.set_min_icd_interface_version(5);
338 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
339 cur_icd.add_instance_extension({VK_KHR_XCB_SURFACE_EXTENSION_NAME});
340 cur_icd.physical_devices.emplace_back("physical_device_0");
341 cur_icd.enable_icd_wsi = true;
342
343 InstWrapper inst{env.vulkan_functions};
344 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME});
345 inst.CheckCreate();
346
347 uint32_t driver_count = 1;
348 VkPhysicalDevice physical_device;
349 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
350 ASSERT_EQ(driver_count, 1U);
351
352 ASSERT_EQ(VK_TRUE, env.vulkan_functions.vkGetPhysicalDeviceXcbPresentationSupportKHR(physical_device, 0, nullptr, 0));
353 }
354
TEST(WsiTests, XcbGetPhysicalDeviceSurfaceSupportKHR)355 TEST(WsiTests, XcbGetPhysicalDeviceSurfaceSupportKHR) {
356 FrameworkEnvironment env{};
357 const uint32_t max_device_count = 4;
358 for (uint32_t icd = 0; icd < max_device_count; ++icd) {
359 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
360 Extension second_ext{VK_KHR_XCB_SURFACE_EXTENSION_NAME};
361 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
362 auto& cur_icd = env.get_test_icd(icd);
363 cur_icd.icd_api_version = VK_API_VERSION_1_0;
364 cur_icd.set_min_icd_interface_version(5);
365 cur_icd.add_instance_extensions({first_ext, second_ext});
366 std::string dev_name = "phys_dev_" + std::to_string(icd);
367 cur_icd.physical_devices.emplace_back(dev_name.c_str());
368 cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
369 cur_icd.enable_icd_wsi = true;
370 }
371
372 InstWrapper instance(env.vulkan_functions);
373 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME});
374 instance.CheckCreate();
375
376 VkSurfaceKHR surface{VK_NULL_HANDLE};
377 VkXcbSurfaceCreateInfoKHR xcb_createInfo{VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR};
378 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXcbSurfaceKHR(instance.inst, &xcb_createInfo, nullptr, &surface));
379 ASSERT_TRUE(surface != VK_NULL_HANDLE);
380
381 uint32_t device_count = max_device_count;
382 std::array<VkPhysicalDevice, max_device_count> phys_devs;
383 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(instance.inst, &device_count, phys_devs.data()));
384 ASSERT_EQ(device_count, max_device_count);
385
386 for (uint32_t pd = 0; pd < max_device_count; ++pd) {
387 VkBool32 supported = VK_FALSE;
388 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
389 }
390
391 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
392 }
393 #endif
394
395 #if defined(VK_USE_PLATFORM_XLIB_KHR)
396 // When ICD doesn't support the extension, create instance should fail
TEST(WsiTests, CreateSurfaceXLIBNoICDSupport)397 TEST(WsiTests, CreateSurfaceXLIBNoICDSupport) {
398 FrameworkEnvironment env{};
399 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
400 auto& cur_icd = env.get_test_icd(0);
401 cur_icd.set_min_icd_interface_version(5);
402 cur_icd.enable_icd_wsi = false;
403
404 InstWrapper inst{env.vulkan_functions};
405 inst.create_info.add_extensions({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
406 inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
407
408 InstWrapper inst2{env.vulkan_functions};
409 inst2.CheckCreate();
410
411 ASSERT_EQ(nullptr, env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkCreateXlibSurfaceKHR"));
412 }
413
414 // When ICD doesn't support the surface creation, the loader should handle it
TEST(WsiTests, CreateSurfaceXLIBNoICDCreateSupport)415 TEST(WsiTests, CreateSurfaceXLIBNoICDCreateSupport) {
416 FrameworkEnvironment env{};
417 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
418 auto& cur_icd = env.get_test_icd(0);
419 cur_icd.set_min_icd_interface_version(5);
420 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
421 cur_icd.add_instance_extension({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
422 cur_icd.enable_icd_wsi = false;
423
424 InstWrapper inst{env.vulkan_functions};
425 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
426 inst.CheckCreate();
427
428 VkXlibSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
429
430 VkSurfaceKHR surface;
431 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXlibSurfaceKHR(inst, &createInfo, nullptr, &surface));
432 ASSERT_TRUE(surface != VK_NULL_HANDLE);
433
434 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
435 }
436
437 // When ICD does support the surface creation, the loader should delegat handle it to the ICD
TEST(WsiTests, CreateSurfaceXLIBICDSupport)438 TEST(WsiTests, CreateSurfaceXLIBICDSupport) {
439 FrameworkEnvironment env{};
440 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
441 auto& cur_icd = env.get_test_icd(0);
442 cur_icd.set_min_icd_interface_version(5);
443 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
444 cur_icd.add_instance_extension({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
445 cur_icd.enable_icd_wsi = true;
446
447 InstWrapper inst{env.vulkan_functions};
448 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
449 inst.CheckCreate();
450
451 VkXlibSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
452
453 VkSurfaceKHR surface;
454 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXlibSurfaceKHR(inst, &createInfo, nullptr, &surface));
455 ASSERT_TRUE(surface != VK_NULL_HANDLE);
456
457 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
458 }
459
460 // Some drivers supporting vkCreateXlibSurfaceKHR, and at least one that doesn't
TEST(WsiTests, CreateSurfaceXLIBMixedICDSupport)461 TEST(WsiTests, CreateSurfaceXLIBMixedICDSupport) {
462 FrameworkEnvironment env{};
463 for (uint32_t icd = 0; icd < 3; ++icd) {
464 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
465 Extension second_ext{VK_KHR_XLIB_SURFACE_EXTENSION_NAME};
466 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
467 auto& cur_icd = env.get_test_icd(icd);
468 cur_icd.icd_api_version = VK_API_VERSION_1_0;
469 cur_icd.add_instance_extensions({first_ext, second_ext});
470 if (icd < 2) {
471 // Only enable ICD for first two
472 cur_icd.enable_icd_wsi = true;
473 }
474 }
475
476 InstWrapper instance(env.vulkan_functions);
477 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
478 instance.CheckCreate();
479
480 VkXlibSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
481
482 VkSurfaceKHR surface;
483 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXlibSurfaceKHR(instance.inst, &createInfo, nullptr, &surface));
484 ASSERT_TRUE(surface != VK_NULL_HANDLE);
485
486 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
487 }
488
TEST(WsiTests, GetPhysicalDeviceXlibPresentNoICDSupport)489 TEST(WsiTests, GetPhysicalDeviceXlibPresentNoICDSupport) {
490 FrameworkEnvironment env{};
491 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
492 auto& cur_icd = env.get_test_icd(0);
493 cur_icd.set_min_icd_interface_version(5);
494 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
495 cur_icd.add_instance_extension({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
496 cur_icd.physical_devices.emplace_back("physical_device_0");
497 cur_icd.enable_icd_wsi = false;
498
499 InstWrapper inst{env.vulkan_functions};
500 inst.create_info.add_extensions(
501 {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME});
502 inst.CheckCreate();
503
504 uint32_t driver_count = 1;
505 VkPhysicalDevice physical_device;
506 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
507 ASSERT_EQ(driver_count, 1U);
508
509 DebugUtilsWrapper log{inst};
510 CreateDebugUtilsMessenger(log);
511 auto res = env.vulkan_functions.vkGetPhysicalDeviceXlibPresentationSupportKHR(physical_device, 0, nullptr, 0);
512 ASSERT_EQ(res, VK_FALSE);
513 ASSERT_TRUE(log.find("ICD for selected physical device does not export vkGetPhysicalDeviceXlibPresentationSupportKHR!"));
514 }
515
TEST(WsiTests, GetPhysicalDeviceXlibPresentICDSupport)516 TEST(WsiTests, GetPhysicalDeviceXlibPresentICDSupport) {
517 FrameworkEnvironment env{};
518 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
519 auto& cur_icd = env.get_test_icd(0);
520 cur_icd.set_min_icd_interface_version(5);
521 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
522 cur_icd.add_instance_extension({VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
523 cur_icd.physical_devices.emplace_back("physical_device_0");
524 cur_icd.enable_icd_wsi = true;
525
526 InstWrapper inst{env.vulkan_functions};
527 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
528 inst.CheckCreate();
529
530 uint32_t driver_count = 1;
531 VkPhysicalDevice physical_device;
532 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
533 ASSERT_EQ(driver_count, 1U);
534
535 ASSERT_EQ(VK_TRUE, env.vulkan_functions.vkGetPhysicalDeviceXlibPresentationSupportKHR(physical_device, 0, nullptr, 0));
536 }
537
TEST(WsiTests, XlibGetPhysicalDeviceSurfaceSupportKHR)538 TEST(WsiTests, XlibGetPhysicalDeviceSurfaceSupportKHR) {
539 FrameworkEnvironment env{};
540 const uint32_t max_device_count = 4;
541 for (uint32_t icd = 0; icd < max_device_count; ++icd) {
542 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
543 Extension second_ext{VK_KHR_XLIB_SURFACE_EXTENSION_NAME};
544 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
545 auto& cur_icd = env.get_test_icd(icd);
546 cur_icd.icd_api_version = VK_API_VERSION_1_0;
547 cur_icd.set_min_icd_interface_version(5);
548 cur_icd.add_instance_extensions({first_ext, second_ext});
549 std::string dev_name = "phys_dev_" + std::to_string(icd);
550 cur_icd.physical_devices.emplace_back(dev_name.c_str());
551 cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
552 cur_icd.enable_icd_wsi = true;
553 }
554
555 InstWrapper instance(env.vulkan_functions);
556 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME});
557 instance.CheckCreate();
558
559 VkSurfaceKHR surface{VK_NULL_HANDLE};
560 VkXlibSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
561 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateXlibSurfaceKHR(instance.inst, &createInfo, nullptr, &surface));
562 ASSERT_TRUE(surface != VK_NULL_HANDLE);
563
564 uint32_t device_count = max_device_count;
565 std::array<VkPhysicalDevice, max_device_count> phys_devs;
566 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(instance.inst, &device_count, phys_devs.data()));
567 ASSERT_EQ(device_count, max_device_count);
568
569 for (uint32_t pd = 0; pd < max_device_count; ++pd) {
570 VkBool32 supported = VK_FALSE;
571 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
572 }
573
574 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
575 }
576 #endif
577
578 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
579 // When ICD doesn't support the extension, create instance should fail
TEST(WsiTests, CreateSurfaceWaylandNoICDSupport)580 TEST(WsiTests, CreateSurfaceWaylandNoICDSupport) {
581 FrameworkEnvironment env{};
582 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
583 auto& cur_icd = env.get_test_icd(0);
584 cur_icd.set_min_icd_interface_version(5);
585 cur_icd.enable_icd_wsi = false;
586
587 InstWrapper inst{env.vulkan_functions};
588 inst.create_info.add_extensions({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
589 inst.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
590
591 InstWrapper inst2{env.vulkan_functions};
592 inst2.CheckCreate();
593
594 ASSERT_EQ(nullptr, env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkCreateWaylandSurfaceKHR"));
595 }
596
597 // When ICD doesn't support the surface creation, the loader should handle it
TEST(WsiTests, CreateSurfaceWaylandNoICDCreateSupport)598 TEST(WsiTests, CreateSurfaceWaylandNoICDCreateSupport) {
599 FrameworkEnvironment env{};
600 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
601 auto& cur_icd = env.get_test_icd(0);
602 cur_icd.set_min_icd_interface_version(5);
603 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
604 cur_icd.add_instance_extension({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
605 cur_icd.enable_icd_wsi = false;
606
607 InstWrapper inst{env.vulkan_functions};
608 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
609 inst.CheckCreate();
610
611 VkWaylandSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
612
613 VkSurfaceKHR surface;
614 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWaylandSurfaceKHR(inst, &createInfo, nullptr, &surface));
615 ASSERT_TRUE(surface != VK_NULL_HANDLE);
616
617 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
618 }
619
620 // When ICD does support the surface creation, the loader should delegat handle it to the ICD
TEST(WsiTests, CreateSurfaceWaylandICDSupport)621 TEST(WsiTests, CreateSurfaceWaylandICDSupport) {
622 FrameworkEnvironment env{};
623 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
624 auto& cur_icd = env.get_test_icd(0);
625 cur_icd.set_min_icd_interface_version(5);
626 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
627 cur_icd.add_instance_extension({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
628 cur_icd.enable_icd_wsi = true;
629
630 InstWrapper inst{env.vulkan_functions};
631 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
632 inst.CheckCreate();
633
634 VkWaylandSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
635
636 VkSurfaceKHR surface;
637 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWaylandSurfaceKHR(inst, &createInfo, nullptr, &surface));
638 ASSERT_TRUE(surface != VK_NULL_HANDLE);
639
640 env.vulkan_functions.vkDestroySurfaceKHR(inst, surface, nullptr);
641 }
642
643 // Some drivers supporting vkCreateWaylandSurfaceKHR, and at least one that doesn't
TEST(WsiTests, CreateSurfaceWaylandMixedICDSupport)644 TEST(WsiTests, CreateSurfaceWaylandMixedICDSupport) {
645 FrameworkEnvironment env{};
646 for (uint32_t icd = 0; icd < 3; ++icd) {
647 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
648 Extension second_ext{VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME};
649 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
650 auto& cur_icd = env.get_test_icd(icd);
651 cur_icd.icd_api_version = VK_API_VERSION_1_0;
652 cur_icd.add_instance_extensions({first_ext, second_ext});
653 if (icd < 2) {
654 // Only enable ICD for first two
655 cur_icd.enable_icd_wsi = true;
656 }
657 }
658
659 InstWrapper instance(env.vulkan_functions);
660 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
661 instance.CheckCreate();
662
663 VkWaylandSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
664
665 VkSurfaceKHR surface;
666 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWaylandSurfaceKHR(instance.inst, &createInfo, nullptr, &surface));
667 ASSERT_TRUE(surface != VK_NULL_HANDLE);
668
669 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
670 }
671
TEST(WsiTests, GetPhysicalDeviceWaylandPresentNoICDSupport)672 TEST(WsiTests, GetPhysicalDeviceWaylandPresentNoICDSupport) {
673 FrameworkEnvironment env{};
674 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
675 auto& cur_icd = env.get_test_icd(0);
676 cur_icd.set_min_icd_interface_version(5);
677 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
678 cur_icd.add_instance_extension({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
679 cur_icd.physical_devices.emplace_back("physical_device_0");
680 cur_icd.enable_icd_wsi = false;
681
682 InstWrapper inst{env.vulkan_functions};
683 inst.create_info.add_extensions(
684 {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME});
685 inst.CheckCreate();
686
687 uint32_t driver_count = 1;
688 VkPhysicalDevice physical_device;
689 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
690 ASSERT_EQ(driver_count, 1U);
691
692 DebugUtilsWrapper log{inst};
693 CreateDebugUtilsMessenger(log);
694 auto res = env.vulkan_functions.vkGetPhysicalDeviceWaylandPresentationSupportKHR(physical_device, 0, nullptr);
695 ASSERT_EQ(res, VK_FALSE);
696 ASSERT_TRUE(log.find("ICD for selected physical device does not export vkGetPhysicalDeviceWaylandPresentationSupportKHR!"));
697 }
698
TEST(WsiTests, GetPhysicalDeviceWaylandPresentICDSupport)699 TEST(WsiTests, GetPhysicalDeviceWaylandPresentICDSupport) {
700 FrameworkEnvironment env{};
701 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
702 auto& cur_icd = env.get_test_icd(0);
703 cur_icd.set_min_icd_interface_version(5);
704 cur_icd.add_instance_extension({VK_KHR_SURFACE_EXTENSION_NAME});
705 cur_icd.add_instance_extension({VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
706 cur_icd.physical_devices.emplace_back("physical_device_0");
707 cur_icd.enable_icd_wsi = true;
708
709 InstWrapper inst{env.vulkan_functions};
710 inst.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
711 inst.CheckCreate();
712
713 uint32_t driver_count = 1;
714 VkPhysicalDevice physical_device;
715 ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &driver_count, &physical_device));
716 ASSERT_EQ(driver_count, 1U);
717
718 ASSERT_EQ(VK_TRUE, env.vulkan_functions.vkGetPhysicalDeviceWaylandPresentationSupportKHR(physical_device, 0, nullptr));
719 }
720
TEST(WsiTests, WaylandGetPhysicalDeviceSurfaceSupportKHR)721 TEST(WsiTests, WaylandGetPhysicalDeviceSurfaceSupportKHR) {
722 FrameworkEnvironment env{};
723 const uint32_t max_device_count = 4;
724 for (uint32_t icd = 0; icd < max_device_count; ++icd) {
725 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME};
726 Extension second_ext{VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME};
727 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
728 auto& cur_icd = env.get_test_icd(icd);
729 cur_icd.icd_api_version = VK_API_VERSION_1_0;
730 cur_icd.set_min_icd_interface_version(5);
731 cur_icd.add_instance_extensions({first_ext, second_ext});
732 std::string dev_name = "phys_dev_" + std::to_string(icd);
733 cur_icd.physical_devices.emplace_back(dev_name.c_str());
734 cur_icd.physical_devices.back().add_queue_family_properties({{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true});
735 cur_icd.enable_icd_wsi = true;
736 }
737
738 InstWrapper instance(env.vulkan_functions);
739 instance.create_info.add_extensions({VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME});
740 instance.CheckCreate();
741
742 VkSurfaceKHR surface{VK_NULL_HANDLE};
743 VkWaylandSurfaceCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
744 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateWaylandSurfaceKHR(instance.inst, &createInfo, nullptr, &surface));
745 ASSERT_TRUE(surface != VK_NULL_HANDLE);
746
747 uint32_t device_count = max_device_count;
748 std::array<VkPhysicalDevice, max_device_count> phys_devs;
749 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(instance.inst, &device_count, phys_devs.data()));
750 ASSERT_EQ(device_count, max_device_count);
751
752 for (uint32_t pd = 0; pd < max_device_count; ++pd) {
753 VkBool32 supported = VK_FALSE;
754 ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(phys_devs[pd], 0, surface, &supported));
755 }
756
757 env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr);
758 }
759 #endif
760
TEST(WsiTests, ForgetEnableSurfaceExtensions)761 TEST(WsiTests, ForgetEnableSurfaceExtensions) {
762 FrameworkEnvironment env{};
763 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
764 .setup_WSI()
765 .add_physical_device(PhysicalDevice{}.add_extension("VK_KHR_swapchain").finish());
766
767 InstWrapper inst{env.vulkan_functions};
768 inst.create_info.add_extension("VK_KHR_surface");
769 ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
770
771 VkSurfaceKHR surface{};
772 ASSERT_EQ(VK_ERROR_EXTENSION_NOT_PRESENT, create_surface(inst, surface));
773 }
774
TEST(WsiTests, SwapchainFunctional)775 TEST(WsiTests, SwapchainFunctional) {
776 FrameworkEnvironment env{};
777 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
778 .setup_WSI()
779 .add_physical_device(PhysicalDevice{}.add_extension("VK_KHR_swapchain").finish());
780
781 InstWrapper inst{env.vulkan_functions};
782 inst.create_info.setup_WSI();
783 inst.CheckCreate();
784 VkSurfaceKHR surface{};
785 ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
786 VkPhysicalDevice phys_dev = inst.GetPhysDev();
787
788 { // Use GDPA to get functions
789 DeviceWrapper dev{inst};
790 dev.create_info.add_extension("VK_KHR_swapchain");
791
792 ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
793
794 VkSwapchainKHR swapchain{};
795 VkSwapchainCreateInfoKHR swap_create_info{};
796 swap_create_info.surface = surface;
797 DeviceFunctions funcs{*inst.functions, dev};
798 ASSERT_EQ(VK_SUCCESS, funcs.vkCreateSwapchainKHR(dev, &swap_create_info, nullptr, &swapchain));
799 uint32_t count = 0;
800 ASSERT_EQ(VK_SUCCESS, funcs.vkGetSwapchainImagesKHR(dev, swapchain, &count, nullptr));
801 ASSERT_GT(count, 0U);
802 std::array<VkImage, 16> images;
803 ASSERT_EQ(VK_SUCCESS, funcs.vkGetSwapchainImagesKHR(dev, swapchain, &count, images.data()));
804 funcs.vkDestroySwapchainKHR(dev, swapchain, nullptr);
805 }
806 { // Use GIPA gotten functions
807 DeviceWrapper dev{inst};
808 dev.create_info.add_extension("VK_KHR_swapchain");
809
810 ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
811
812 PFN_vkCreateSwapchainKHR inst_CreateSwapchainKHR = inst.load("vkCreateSwapchainKHR");
813 PFN_vkGetSwapchainImagesKHR inst_GetSwapchainImagesKHR = inst.load("vkGetSwapchainImagesKHR");
814 PFN_vkDestroySwapchainKHR inst_DestroySwapchainKHR = inst.load("vkDestroySwapchainKHR");
815 ASSERT_TRUE(nullptr != inst_CreateSwapchainKHR);
816 ASSERT_TRUE(nullptr != inst_GetSwapchainImagesKHR);
817 ASSERT_TRUE(nullptr != inst_DestroySwapchainKHR);
818
819 VkSwapchainKHR swapchain{};
820 VkSwapchainCreateInfoKHR swap_create_info{};
821 swap_create_info.surface = surface;
822
823 ASSERT_EQ(VK_SUCCESS, inst_CreateSwapchainKHR(dev, &swap_create_info, nullptr, &swapchain));
824 uint32_t count = 0;
825 ASSERT_EQ(VK_SUCCESS, inst_GetSwapchainImagesKHR(dev, swapchain, &count, nullptr));
826 ASSERT_GT(count, 0U);
827 std::array<VkImage, 16> images;
828 ASSERT_EQ(VK_SUCCESS, inst_GetSwapchainImagesKHR(dev, swapchain, &count, images.data()));
829 inst_DestroySwapchainKHR(dev, swapchain, nullptr);
830 }
831 { // forget to enable the extension
832 DeviceWrapper dev{inst};
833 ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
834
835 DeviceFunctions funcs{*inst.functions, dev};
836 ASSERT_EQ(funcs.vkCreateSwapchainKHR, nullptr);
837 ASSERT_EQ(funcs.vkGetSwapchainImagesKHR, nullptr);
838 ASSERT_EQ(funcs.vkDestroySwapchainKHR, nullptr);
839 }
840 { // forget to set the surface
841 DeviceWrapper dev{inst};
842 dev.create_info.add_extension("VK_KHR_swapchain");
843
844 dev.CheckCreate(phys_dev);
845
846 VkSwapchainKHR swapchain{};
847 VkSwapchainCreateInfoKHR swap_create_info{};
848 DeviceFunctions funcs{*inst.functions, dev};
849 ASSERT_DEATH(funcs.vkCreateSwapchainKHR(dev, &swap_create_info, nullptr, &swapchain), "");
850 }
851 env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr);
852 }
853