mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-06-13 14:32:57 -04:00
Merge branch 'vulkan-split-render-display' into 'master'
render/vulkan: add support for split render/display devices Closes #4055 See merge request wlroots/wlroots!5379
This commit is contained in:
commit
a91e4afc7d
1 changed files with 75 additions and 15 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
#include <xf86drmMode.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/version.h>
|
#include <wlr/version.h>
|
||||||
|
|
@ -252,6 +253,14 @@ static void log_phdev(const VkPhysicalDeviceProperties *props) {
|
||||||
wlr_log(WLR_INFO, " Driver version: %u.%u.%u", dv_major, dv_minor, dv_patch);
|
wlr_log(WLR_INFO, " Driver version: %u.%u.%u", dv_major, dv_minor, dv_patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_vk_phdev_info {
|
||||||
|
VkPhysicalDeviceType type;
|
||||||
|
char name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
|
||||||
|
|
||||||
|
bool has_drm, has_render;
|
||||||
|
dev_t primary_devid, render_devid;
|
||||||
|
};
|
||||||
|
|
||||||
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) {
|
||||||
VkResult res;
|
VkResult res;
|
||||||
uint32_t num_phdevs;
|
uint32_t num_phdevs;
|
||||||
|
|
@ -269,12 +278,7 @@ VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd)
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat drm_stat = {0};
|
struct wlr_vk_phdev_info devices[1 + num_phdevs];
|
||||||
if (drm_fd >= 0 && fstat(drm_fd, &drm_stat) != 0) {
|
|
||||||
wlr_log_errno(WLR_ERROR, "fstat failed");
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_phdevs; ++i) {
|
for (uint32_t i = 0; i < num_phdevs; ++i) {
|
||||||
VkPhysicalDevice phdev = phdevs[i];
|
VkPhysicalDevice phdev = phdevs[i];
|
||||||
|
|
||||||
|
|
@ -330,25 +334,81 @@ VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd)
|
||||||
wlr_log(WLR_INFO, " Driver name: %s (%s)", driver_props.driverName, driver_props.driverInfo);
|
wlr_log(WLR_INFO, " Driver name: %s (%s)", driver_props.driverName, driver_props.driverInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_vk_phdev_info info = {
|
||||||
|
.type = phdev_props.deviceType,
|
||||||
|
.has_drm = has_drm_props,
|
||||||
|
};
|
||||||
|
memcpy(info.name, phdev_props.deviceName, sizeof(phdev_props.deviceName));
|
||||||
|
if (has_drm_props) {
|
||||||
|
info.has_render = drm_props.hasRender;
|
||||||
|
info.primary_devid = makedev(drm_props.primaryMajor, drm_props.primaryMinor);
|
||||||
|
info.render_devid = makedev(drm_props.renderMajor, drm_props.renderMinor);
|
||||||
|
}
|
||||||
|
devices[i] = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a Vulkan device matching the DRM device's dev_t
|
||||||
|
struct stat drm_stat = {0};
|
||||||
|
if (drm_fd >= 0 && fstat(drm_fd, &drm_stat) != 0) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "fstat failed");
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_phdevs; ++i) {
|
||||||
|
VkPhysicalDevice phdev = phdevs[i];
|
||||||
|
const struct wlr_vk_phdev_info *info = &devices[i];
|
||||||
|
|
||||||
bool found;
|
bool found;
|
||||||
if (drm_fd >= 0) {
|
if (drm_fd >= 0) {
|
||||||
if (!has_drm_props) {
|
if (!info->has_drm) {
|
||||||
wlr_log(WLR_DEBUG, " Ignoring physical device \"%s\": "
|
wlr_log(WLR_DEBUG, " Ignoring physical device \"%s\": "
|
||||||
"VK_EXT_physical_device_drm not supported",
|
"VK_EXT_physical_device_drm not supported", info->name);
|
||||||
phdev_props.deviceName);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_t primary_devid = makedev(drm_props.primaryMajor, drm_props.primaryMinor);
|
found = info->primary_devid == drm_stat.st_rdev || info->render_devid == drm_stat.st_rdev;
|
||||||
dev_t render_devid = makedev(drm_props.renderMajor, drm_props.renderMinor);
|
|
||||||
found = primary_devid == drm_stat.st_rdev || render_devid == drm_stat.st_rdev;
|
|
||||||
} else {
|
} else {
|
||||||
found = phdev_props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU;
|
found = info->type == VK_PHYSICAL_DEVICE_TYPE_CPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
wlr_log(WLR_INFO, "Found matching Vulkan physical device: %s",
|
wlr_log(WLR_INFO, "Found matching Vulkan physical device: %s", info->name);
|
||||||
phdev_props.deviceName);
|
return phdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the DRM device we're interested in uses the platform bus, is
|
||||||
|
// KMS-capable, and has no render node associated, search for a sibling
|
||||||
|
// render-capable platform bus device. The platform bus is a good enough
|
||||||
|
// hint that these two devices should be compatible.
|
||||||
|
drmDevice *drm_dev = NULL;
|
||||||
|
if (drmGetDevice2(drm_fd, 0, &drm_dev) != 0) {
|
||||||
|
wlr_log(WLR_ERROR, "drmGetDevice2() failed");
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
bool is_platform_lone_kms = drm_dev->bustype == DRM_BUS_PLATFORM &&
|
||||||
|
!(drm_dev->available_nodes & (1 << DRM_NODE_RENDER)) && drmIsKMS(drm_fd);
|
||||||
|
drmFreeDevice(&drm_dev);
|
||||||
|
if (!is_platform_lone_kms) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_phdevs; ++i) {
|
||||||
|
VkPhysicalDevice phdev = phdevs[i];
|
||||||
|
const struct wlr_vk_phdev_info *info = &devices[i];
|
||||||
|
|
||||||
|
if (!info->has_render) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmDevice *drm_dev = NULL;
|
||||||
|
if (drmGetDeviceFromDevId(info->render_devid, 0, &drm_dev) != 0) {
|
||||||
|
wlr_log(WLR_ERROR, "drmGetDeviceFromDevId() failed");
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drm_dev->bustype == DRM_BUS_PLATFORM) {
|
||||||
|
wlr_log(WLR_INFO, "Found Vulkan physical device on platform bus: %s", info->name);
|
||||||
return phdev;
|
return phdev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue