Skip to content

Instantly share code, notes, and snippets.

@yshui
Created December 17, 2025 06:27
Show Gist options
  • Select an option

  • Save yshui/05795c1054b1c5ec898a7fe6e268e3bb to your computer and use it in GitHub Desktop.

Select an option

Save yshui/05795c1054b1c5ec898a7fe6e268e3bb to your computer and use it in GitHub Desktop.
#include <vulkan/vulkan_core.h>
#include <wayland-client-core.h>
#include <wayland-client-protocol.h>
#include <wayland-client.h>
#include <wayland-util.h>
#include <vulkan/vulkan.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "lease.h"
struct connector {
struct wp_drm_lease_connector_v1 *iface;
uint32_t id;
char *name;
char *desc;
bool done;
};
struct lease_device {
struct wp_drm_lease_device_v1 *iface;
int drm_fd;
struct connector conn;
bool done;
} lease_devices[10] = {};
int num_lease_devices = 0;
void conn_done(void *data, struct wp_drm_lease_connector_v1 *conn) {
struct connector *c = data;
c->done = true;
}
void conn_name(void *data, struct wp_drm_lease_connector_v1 *conn, const char *name) {
struct connector *c = data;
c->name = strdup(name);
}
void conn_id(void *data, struct wp_drm_lease_connector_v1 *conn, uint32_t id) {
struct connector *c = data;
c->id = id;
}
void conn_desc(void *data, struct wp_drm_lease_connector_v1 *conn, const char *desc) {
struct connector *c = data;
c->desc = strdup(desc);
}
void conn_withdrawn(void *data, struct wp_drm_lease_connector_v1 *conn) {}
static const struct wp_drm_lease_connector_v1_listener conn_listener = {
.done = conn_done,
.name = conn_name,
.connector_id = conn_id,
.description = conn_desc,
.withdrawn = conn_withdrawn,
};
void lease_release(void *data, struct wp_drm_lease_device_v1 *dev) {}
void lease_connector(void *data, struct wp_drm_lease_device_v1 *dev,
struct wp_drm_lease_connector_v1 *conn) {
struct lease_device *wd = data;
wd->conn.iface = conn;
wp_drm_lease_connector_v1_add_listener(conn, &conn_listener, &wd->conn);
}
void lease_drm_fd(void *data, struct wp_drm_lease_device_v1 *dev, int drm_fd) {
struct lease_device *wd = data;
wd->drm_fd = drm_fd;
}
void lease_done(void *data, struct wp_drm_lease_device_v1 *dev) {
struct lease_device *wd = data;
wd->done = true;
}
static const struct wp_drm_lease_device_v1_listener device_listener = {
.released = lease_release,
.connector = lease_connector,
.drm_fd = lease_drm_fd,
.done = lease_done,
};
static void
registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version) {
if (strcmp(interface, wp_drm_lease_device_v1_interface.name) == 0) {
lease_devices[num_lease_devices].iface = wl_registry_bind(
registry, name, &wp_drm_lease_device_v1_interface, 1);
wp_drm_lease_device_v1_add_listener(
lease_devices[num_lease_devices].iface, &device_listener,
&lease_devices[num_lease_devices]);
num_lease_devices++;
}
}
static void registry_handle_global_remove(void *data, struct wl_registry *registry,
uint32_t name) {}
static const struct wl_registry_listener registry_listener = {
.global = registry_handle_global,
.global_remove = registry_handle_global_remove,
};
struct lease {
struct wp_drm_lease_v1 *iface;
int fd;
} lease;
void lease_lease_fd(void *data, struct wp_drm_lease_v1 *lease, int fd) {
struct lease *l = data;
l->fd = fd;
}
void lease_finished(void *data, struct wp_drm_lease_v1 *lease) {}
static const struct wp_drm_lease_v1_listener lease_listener = {
.lease_fd = lease_lease_fd,
.finished = lease_finished,
};
int main() {
struct wl_display *dpy = wl_display_connect(NULL);
struct wl_registry *registry = wl_display_get_registry(dpy);
wl_registry_add_listener(registry, &registry_listener, NULL);
wl_display_roundtrip(dpy);
wl_display_roundtrip(dpy);
struct lease_device *selected = NULL;
for (int i = 0; i < num_lease_devices; i++) {
if (lease_devices[i].conn.desc &&
strncmp(lease_devices[i].conn.desc, "Valve", 5) == 0) {
selected = &lease_devices[i];
break;
}
}
assert(selected);
struct wp_drm_lease_request_v1 *req =
wp_drm_lease_device_v1_create_lease_request(selected->iface);
wp_drm_lease_request_v1_request_connector(req, selected->conn.iface);
lease.iface = wp_drm_lease_request_v1_submit(req);
lease.fd = -1;
wp_drm_lease_v1_add_listener(lease.iface, &lease_listener, &lease);
wl_display_roundtrip(dpy);
assert(lease.fd != -1);
// now, vulkan
const struct VkApplicationInfo app = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pApplicationName = "Test",
.applicationVersion = 1,
.pEngineName = "Test",
.engineVersion = 1,
.apiVersion = VK_API_VERSION_1_2,
};
const char *exts[] = {
"VK_KHR_surface",
"VK_KHR_xlib_surface",
"VK_KHR_display",
"VK_EXT_direct_mode_display",
"VK_EXT_display_surface_counter",
"VK_KHR_external_memory_capabilities",
"VK_KHR_external_semaphore_capabilities",
"VK_KHR_get_physical_device_properties2",
"VK_EXT_debug_utils",
"VK_EXT_acquire_drm_display",
};
const struct VkInstanceCreateInfo vkci = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pApplicationInfo = &app,
.enabledExtensionCount = 10,
.ppEnabledExtensionNames = exts,
};
VkInstance instance;
VkResult res = vkCreateInstance(&vkci, NULL, &instance);
assert(res == VK_SUCCESS);
VkPhysicalDevice devices[2];
uint32_t num_phydev = 2;
res = vkEnumeratePhysicalDevices(instance, &num_phydev, devices);
assert(res == VK_SUCCESS);
assert(num_phydev > 0);
#define GETPROC(name) \
PFN_##name p##name = (void *)vkGetInstanceProcAddr(instance, #name)
GETPROC(vkGetDrmDisplayEXT);
GETPROC(vkAcquireDrmDisplayEXT);
GETPROC(vkCreateDisplayPlaneSurfaceKHR);
GETPROC(vkGetDisplayModePropertiesKHR);
GETPROC(vkGetPhysicalDeviceSurfaceFormatsKHR);
VkDisplayKHR vkdpy;
res = pvkGetDrmDisplayEXT(devices[0], selected->drm_fd, selected->conn.id,
&vkdpy);
assert(res == VK_SUCCESS);
VkDisplayModePropertiesKHR display_modes[10];
uint32_t num_display_modes = 10;
res = pvkGetDisplayModePropertiesKHR(devices[0], vkdpy, &num_display_modes,
display_modes);
assert(res == VK_SUCCESS);
assert(num_display_modes > 0);
res = pvkAcquireDrmDisplayEXT(devices[0], lease.fd, vkdpy);
assert(res == VK_SUCCESS);
VkExtent2D size = display_modes[0].parameters.visibleRegion;
const struct VkDisplaySurfaceCreateInfoKHR dsci = {
.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,
.displayMode = display_modes[0].displayMode,
.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.globalAlpha = 1.0,
.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR,
.imageExtent = size,
};
VkSurfaceKHR surface;
res = pvkCreateDisplayPlaneSurfaceKHR(instance, &dsci, NULL, &surface);
assert(res == VK_SUCCESS);
uint32_t num_formats = 10;
VkSurfaceFormatKHR formats[10];
res = pvkGetPhysicalDeviceSurfaceFormatsKHR(devices[0], surface,
&num_formats, formats);
assert(res == VK_SUCCESS);
assert(num_formats > 0); // <- fails here
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment