I have this weird issue where calling vkGetPhysicalDeviceSurfaceSupportKHR
causes XCloseDisplay
to segfault but it has some caveats:
- the physical device passed to
vkGetPhysicalDeviceSurfaceSupportKHR
is my nvidia gpu, I also have an intel hd graphics which does not trigger the crash - it only happens if
XCloseDisplay
is called aftervkDestroyInstance
Here’s an example of something similar to what I’m doing that also triggers the crash
#include <stdio.h>
#define VK_USE_PLATFORM_XLIB_KHR
#include <vulkan/vulkan.h>
int main(void) {
Display* display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "failed to connect to the X server\n");
return -1;
}
Window window =XCreateWindow(
display,
DefaultRootWindow(display),
0, 0,
1280, 720,
0,
CopyFromParent,
InputOutput,
CopyFromParent,
CWEventMask,
&(XSetWindowAttributes) {
.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
KeyPressMask | KeyReleaseMask | StructureNotifyMask,
}
);
Atom WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &WM_DELETE_WINDOW, 1);
XMapWindow(display, window);
XFlush(display);
char const* extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME };
VkInstance instance = NULL;
VkResult result = vkCreateInstance(
&(VkInstanceCreateInfo) {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.enabledExtensionCount = sizeof extensions / sizeof extensions[0],
.ppEnabledExtensionNames = extensions,
.pApplicationInfo = &(VkApplicationInfo) {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.apiVersion = VK_API_VERSION_1_0,
}
},
NULL,
&instance
);
VkSurfaceKHR surface = NULL;
result = vkCreateXlibSurfaceKHR(
instance,
&(VkXlibSurfaceCreateInfoKHR) {
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
.dpy = display,
.window = window,
},
NULL,
&surface
);
// device[0] is my nvidia gpu, device[1] is the intel gpu
uint32_t device_count = 2;
VkPhysicalDevice device[2];
vkEnumeratePhysicalDevices(instance, &device_count, device);
VkBool32 present_support = VK_FALSE;
vkGetPhysicalDeviceSurfaceSupportKHR(device[0], 0, surface, &present_support);
char close_requested = 0;
while (!close_requested) {
XEvent event = {0};
while (XPending(display) > 0) {
XNextEvent(display, &event);
switch (event.type) {
case ClientMessage: {
if ((Atom)event.xclient.data.l[0] == WM_DELETE_WINDOW) {
close_requested = 1;
}
} break;
default: break;
}
}
}
vkDestroySurfaceKHR(instance, surface, NULL);
vkDestroyInstance(instance, NULL);
XCloseDisplay(display);
}