Skip to content

Commit 35a851d

Browse files
Support VK_GOOGLE_surfaceless_query
Requires bypassing the logic which dereferences VkSurfaceKHR in vkGetPhysicalDeviceSurfaceFormatsKHR and vkGetPhysicalDeviceSurfacePresentModesKHR. This should have been done closer to the release of VK_GOOGLE_surfaceless_query, but because that extension was meant for Android, which isn't supported by this loader, it was not done. That said, SwiftShader can support the extension, so support is now being added in this commit.
1 parent 35c1713 commit 35a851d

File tree

7 files changed

+165
-50
lines changed

7 files changed

+165
-50
lines changed

loader/extension_manual.c

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,16 +274,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2E
274274
"ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT");
275275
abort();
276276
}
277-
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
278-
if (NULL != icd_term->surface_list.list &&
279-
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
280-
icd_term->surface_list.list[icd_surface->surface_index]) {
281-
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
282-
surface_info_copy.sType = pSurfaceInfo->sType;
283-
surface_info_copy.pNext = pSurfaceInfo->pNext;
284-
surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
285-
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy,
286-
pPresentModeCount, pPresentModes);
277+
if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
278+
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
279+
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
280+
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
281+
icd_term->surface_list.list[icd_surface->surface_index]) {
282+
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
283+
surface_info_copy.sType = pSurfaceInfo->sType;
284+
surface_info_copy.pNext = pSurfaceInfo->pNext;
285+
surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
286+
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy,
287+
pPresentModeCount, pPresentModes);
288+
}
287289
}
288290
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, pSurfaceInfo, pPresentModeCount,
289291
pPresentModes);
@@ -321,16 +323,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(
321323
"[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter]");
322324
abort(); /* Intentionally fail so user can correct issue. */
323325
}
324-
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
325-
if (NULL != icd_term->surface_list.list &&
326-
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
327-
icd_term->surface_list.list[icd_surface->surface_index]) {
328-
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
329-
surface_info_copy.sType = pSurfaceInfo->sType;
330-
surface_info_copy.pNext = pSurfaceInfo->pNext;
331-
surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
332-
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy,
333-
pModes);
326+
if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
327+
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
328+
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
329+
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
330+
icd_term->surface_list.list[icd_surface->surface_index]) {
331+
VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy;
332+
surface_info_copy.sType = pSurfaceInfo->sType;
333+
surface_info_copy.pNext = pSurfaceInfo->pNext;
334+
surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index];
335+
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(
336+
device, &surface_info_copy, pModes);
337+
}
334338
}
335339
return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
336340
}

loader/loader.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
2-
// Copyright (c) 2014-2024 The Khronos Group Inc.
3-
// Copyright (c) 2014-2024 Valve Corporation
4-
// Copyright (c) 2014-2024 LunarG, Inc.
2+
// Copyright (c) 2014-2025 The Khronos Group Inc.
3+
// Copyright (c) 2014-2025 Valve Corporation
4+
// Copyright (c) 2014-2025 LunarG, Inc.
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
2525
#define VER_FILE_VERSION 1, 4, 304, 0
2626
#define VER_FILE_DESCRIPTION_STR "1.4.304.Dev Build"
2727
#define VER_FILE_VERSION_STR "Vulkan Loader - Dev Build"
28-
#define VER_COPYRIGHT_STR "Copyright (C) 2015-2024"
28+
#define VER_COPYRIGHT_STR "Copyright (C) 2015-2025"
2929

3030
VS_VERSION_INFO VERSIONINFO
3131
FILEVERSION VER_FILE_VERSION

loader/wsi.c

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -366,15 +366,16 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkP
366366
return VK_SUCCESS;
367367
}
368368

369-
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
370-
if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
371-
phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
372-
phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
373-
return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(
374-
phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index],
375-
pSurfaceFormatCount, pSurfaceFormats);
369+
if (VK_NULL_HANDLE != surface) {
370+
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
371+
if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
372+
phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
373+
phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
374+
return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(
375+
phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index],
376+
pSurfaceFormatCount, pSurfaceFormats);
377+
}
376378
}
377-
378379
return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
379380
pSurfaceFormats);
380381
}
@@ -424,16 +425,17 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKH
424425
"ICD for selected physical device does not export vkGetPhysicalDeviceSurfacePresentModesKHR!");
425426
return VK_SUCCESS;
426427
}
428+
if (VK_NULL_HANDLE != surface) {
429+
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
427430

428-
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
429-
if (NULL != phys_dev_term->this_icd_term->surface_list.list &&
430-
phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
431-
phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
432-
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
433-
phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index], pPresentModeCount,
434-
pPresentModes);
431+
if (icd_surface != NULL && NULL != phys_dev_term->this_icd_term->surface_list.list &&
432+
phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
433+
phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) {
434+
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
435+
phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index],
436+
pPresentModeCount, pPresentModes);
437+
}
435438
}
436-
437439
return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount,
438440
pPresentModes);
439441
}
@@ -2501,7 +2503,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K
25012503
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
25022504
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
25032505
struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2504-
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
2506+
VkIcdSurface *icd_surface = NULL;
2507+
if (pSurfaceInfo->surface) {
2508+
icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
2509+
}
25052510

25062511
if (!loader_inst->wsi_surface_enabled) {
25072512
loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
@@ -2526,7 +2531,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K
25262531
VkResult res = VK_SUCCESS;
25272532

25282533
// Pass the call to the driver, possibly unwrapping the ICD surface
2529-
if (NULL != icd_term->surface_list.list &&
2534+
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
25302535
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
25312536
icd_term->surface_list.list[icd_surface->surface_index]) {
25322537
VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
@@ -2553,8 +2558,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K
25532558
icd_term->scanned_icd->lib_name);
25542559

25552560
// Write to the VkSurfaceCapabilities2KHR struct
2556-
VkSurfaceKHR surface = pSurfaceInfo->surface;
2557-
if (NULL != icd_term->surface_list.list &&
2561+
VkSurfaceKHR surface = VK_NULL_HANDLE;
2562+
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
25582563
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
25592564
icd_term->surface_list.list[icd_surface->surface_index]) {
25602565
surface = icd_term->surface_list.list[icd_surface->surface_index];
@@ -2604,11 +2609,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk
26042609
return VK_SUCCESS;
26052610
}
26062611

2607-
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2612+
VkIcdSurface *icd_surface = NULL;
2613+
if (VK_NULL_HANDLE != pSurfaceInfo->surface) {
2614+
icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2615+
}
26082616

26092617
if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
26102618
// Pass the call to the driver, possibly unwrapping the ICD surface
2611-
if (NULL != icd_term->surface_list.list &&
2619+
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
26122620
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
26132621
icd_term->surface_list.list[icd_surface->surface_index]) {
26142622
VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
@@ -2632,7 +2640,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk
26322640
}
26332641

26342642
VkSurfaceKHR surface = pSurfaceInfo->surface;
2635-
if (NULL != icd_term->surface_list.list &&
2643+
if (NULL != icd_surface && NULL != icd_term->surface_list.list &&
26362644
icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) &&
26372645
icd_term->surface_list.list[icd_surface->surface_index]) {
26382646
surface = icd_term->surface_list.list[icd_surface->surface_index];

scripts/loader_extension_generator.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,8 +1277,11 @@ def CreateTrampTermFuncs(self):
12771277
funcs += ' }\n'
12781278

12791279
if has_surface == 1:
1280-
funcs += f' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)({surface_var_name});\n'
1281-
funcs += ' if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list[icd_surface->surface_index]) {\n'
1280+
funcs += ' VkIcdSurface *icd_surface = NULL;\n'
1281+
funcs += f' if (NULL != {surface_var_name}) {{\n'
1282+
funcs += f' icd_surface = (VkIcdSurface *)(uintptr_t)({surface_var_name});\n'
1283+
funcs += ' }\n'
1284+
funcs += ' if (NULL != icd_surface && NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list[icd_surface->surface_index]) {\n'
12821285

12831286
# If there's a structure with a surface, we need to update its internals with the correct surface for the ICD
12841287
if update_structure_surface == 1:

tests/framework/icd/test_icd.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,11 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysi
838838
assert(false && "Surface not found during GetPhysicalDeviceSurfaceFormatsKHR query!");
839839
return VK_ERROR_UNKNOWN;
840840
}
841+
} else {
842+
if (!IsInstanceExtensionEnabled(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) {
843+
assert(false && "Surface is NULL but VK_GOOGLE_surfaceless_query was not enabled!");
844+
return VK_ERROR_UNKNOWN;
845+
}
841846
}
842847
FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_formats, pSurfaceFormatCount, pSurfaceFormats);
843848
return VK_SUCCESS;
@@ -852,11 +857,39 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModesKHR(Vk
852857
assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
853858
return VK_ERROR_UNKNOWN;
854859
}
860+
} else {
861+
if (!IsInstanceExtensionEnabled(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) {
862+
assert(false && "Surface is NULL but VK_GOOGLE_surfaceless_query was not enabled!");
863+
return VK_ERROR_UNKNOWN;
864+
}
855865
}
856866
FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
857867
return VK_SUCCESS;
858868
}
859869

870+
#if defined(WIN32)
871+
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModes2EXT(VkPhysicalDevice physicalDevice,
872+
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
873+
uint32_t* pPresentModeCount,
874+
VkPresentModeKHR* pPresentModes) {
875+
if (pSurfaceInfo->surface != VK_NULL_HANDLE) {
876+
uint64_t fake_surf_handle = (uint64_t)(pSurfaceInfo->surface);
877+
auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
878+
if (found_iter == icd.surface_handles.end()) {
879+
assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
880+
return VK_ERROR_UNKNOWN;
881+
}
882+
} else {
883+
if (!IsInstanceExtensionEnabled(VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME)) {
884+
assert(false && "Surface is NULL but VK_GOOGLE_surfaceless_query was not enabled!");
885+
return VK_ERROR_UNKNOWN;
886+
}
887+
}
888+
FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
889+
return VK_SUCCESS;
890+
}
891+
#endif
892+
860893
// VK_KHR_display
861894
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
862895
uint32_t* pPropertyCount,
@@ -1310,6 +1343,12 @@ PFN_vkVoidFunction get_physical_device_func_wsi([[maybe_unused]] VkInstance inst
13101343
if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModesKHR"))
13111344
return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModesKHR);
13121345
}
1346+
#if defined(WIN32)
1347+
if (IsPhysicalDeviceExtensionAvailable("VK_EXT_full_screen_exclusive")) {
1348+
if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModes2EXT"))
1349+
return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModes2EXT);
1350+
}
1351+
#endif
13131352
if (IsInstanceExtensionEnabled("VK_KHR_get_surface_capabilities2")) {
13141353
if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"))
13151354
return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilities2KHR);

tests/framework/test_environment.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ void init_vulkan_functions(VulkanFunctions& funcs) {
140140
funcs.vkCreateWin32SurfaceKHR = GPA(vkCreateWin32SurfaceKHR);
141141
funcs.vkGetPhysicalDeviceWin32PresentationSupportKHR = GPA(vkGetPhysicalDeviceWin32PresentationSupportKHR);
142142
#endif // VK_USE_PLATFORM_WIN32_KHR
143-
144143
funcs.vkDestroyDevice = GPA(vkDestroyDevice);
145144
funcs.vkGetDeviceQueue = GPA(vkGetDeviceQueue);
146145
#undef GPA

0 commit comments

Comments
 (0)