mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-23 05:15:58 +01:00
render/vulkan: prefer render node for wlr_renderer_get_drm_fd()
Instead of returning a primary node from wlr_renderer_get_drm_fd(), prefer to return a render node if any.
This commit is contained in:
parent
8db0d82890
commit
40117e1e0d
3 changed files with 54 additions and 3 deletions
|
@ -66,6 +66,7 @@ struct wlr_vk_device {
|
||||||
// Tries to find the VkPhysicalDevice for the given drm fd.
|
// Tries to find the VkPhysicalDevice for the given drm fd.
|
||||||
// Might find none and return VK_NULL_HANDLE.
|
// Might find none and return VK_NULL_HANDLE.
|
||||||
VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd);
|
VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd);
|
||||||
|
int vulkan_open_phdev_drm_fd(VkPhysicalDevice phdev);
|
||||||
|
|
||||||
// Creates a device for the given instance and physical device.
|
// Creates a device for the given instance and physical device.
|
||||||
struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini,
|
struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini,
|
||||||
|
|
|
@ -2240,10 +2240,10 @@ struct wlr_renderer *wlr_vk_renderer_create_with_drm_fd(int drm_fd) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We duplicate it so it's not closed while we still need it.
|
// Do not use the drm_fd that was passed in: we should prefer the render
|
||||||
dev->drm_fd = fcntl(drm_fd, F_DUPFD_CLOEXEC, 0);
|
// node even if a primary node was provided
|
||||||
|
dev->drm_fd = vulkan_open_phdev_drm_fd(phdev);
|
||||||
if (dev->drm_fd < 0) {
|
if (dev->drm_fd < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed");
|
|
||||||
vulkan_device_destroy(dev);
|
vulkan_device_destroy(dev);
|
||||||
vulkan_instance_destroy(ini);
|
vulkan_instance_destroy(ini);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
#if !defined(__FreeBSD__)
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -366,6 +370,52 @@ VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd)
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vulkan_open_phdev_drm_fd(VkPhysicalDevice phdev) {
|
||||||
|
// vulkan_find_drm_phdev() already checks that VK_EXT_physical_device_drm
|
||||||
|
// is supported
|
||||||
|
VkPhysicalDeviceDrmPropertiesEXT drm_props = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT,
|
||||||
|
};
|
||||||
|
VkPhysicalDeviceProperties2 props = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
|
||||||
|
.pNext = &drm_props,
|
||||||
|
};
|
||||||
|
vkGetPhysicalDeviceProperties2(phdev, &props);
|
||||||
|
|
||||||
|
dev_t devid;
|
||||||
|
if (drm_props.hasRender) {
|
||||||
|
devid = makedev(drm_props.renderMajor, drm_props.renderMinor);
|
||||||
|
} else if (drm_props.hasPrimary) {
|
||||||
|
devid = makedev(drm_props.primaryMajor, drm_props.primaryMinor);
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_ERROR, "Physical device is missing both render and primary nodes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmDevice *device = NULL;
|
||||||
|
if (drmGetDeviceFromDevId(devid, 0, &device) != 0) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "drmGetDeviceFromDevId failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *name = NULL;
|
||||||
|
if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
|
||||||
|
name = device->nodes[DRM_NODE_RENDER];
|
||||||
|
} else {
|
||||||
|
assert(device->available_nodes & (1 << DRM_NODE_PRIMARY));
|
||||||
|
name = device->nodes[DRM_NODE_PRIMARY];
|
||||||
|
wlr_log(WLR_DEBUG, "DRM device %s has no render node, "
|
||||||
|
"falling back to primary node", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drm_fd = open(name, O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||||||
|
if (drm_fd < 0) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "Failed to open DRM node %s", name);
|
||||||
|
}
|
||||||
|
drmFreeDevice(&device);
|
||||||
|
return drm_fd;
|
||||||
|
}
|
||||||
|
|
||||||
static void load_device_proc(struct wlr_vk_device *dev, const char *name,
|
static void load_device_proc(struct wlr_vk_device *dev, const char *name,
|
||||||
void *proc_ptr) {
|
void *proc_ptr) {
|
||||||
void *proc = (void *)vkGetDeviceProcAddr(dev->dev, name);
|
void *proc = (void *)vkGetDeviceProcAddr(dev->dev, name);
|
||||||
|
|
Loading…
Reference in a new issue