Do not assume drm card is card0 It's not guaranteed that cards start at /dev/dri/card0, in fact on the latest kernel on Fedora at least with i915drmfb driver, it's often /dev/dri/card1. Bug: b/176909700 Change-Id: I8fd75090f460453c4c7f44ba8363fc715de91e90 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/66268 Reviewed-by: Nicolas Caramelli <caramelli.devel@gmail.com> Tested-by: Nicolas Capens <nicolascapens@google.com> Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/WSI/DisplaySurfaceKHR.cpp b/src/WSI/DisplaySurfaceKHR.cpp index bc8141a..b54563d 100644 --- a/src/WSI/DisplaySurfaceKHR.cpp +++ b/src/WSI/DisplaySurfaceKHR.cpp
@@ -17,6 +17,7 @@ #include "Vulkan/VkDeviceMemory.hpp" #include "Vulkan/VkImage.hpp" +#include <dirent.h> #include <fcntl.h> #include <string.h> #include <sys/mman.h> @@ -25,13 +26,61 @@ namespace vk { +static int openCard() +{ + constexpr size_t DIR_NAME_MAX = sizeof("/dev/dri/") - 1; + constexpr size_t PRE_NODE_NAME_MAX = sizeof("card") - 1; + constexpr size_t POST_NODE_NAME_MAX = sizeof("255") - 1; + constexpr size_t NODE_NAME_MAX = + DIR_NAME_MAX + PRE_NODE_NAME_MAX + POST_NODE_NAME_MAX; + char name[NODE_NAME_MAX] = "/dev/dri/"; + int fd = -VK_NOT_READY; + + /* + * Open the first DRM/KMS device. The libdrm drmOpen*() functions + * from drmOpen() is of no practical use as any modern system will + * handle that through udev or an equivalent component. + */ + DIR *folder = opendir(name); + if(!folder) + { + return -errno; + } + + strncat(name, "card", 5); + for(struct dirent *res; (res = readdir(folder));) + { + if(!strncmp(res->d_name, "card", 4)) + { + strncat(name, res->d_name + PRE_NODE_NAME_MAX, 4); + fd = open(name, O_RDWR); + if(fd >= 0) + { + break; + } + + name[DIR_NAME_MAX + PRE_NODE_NAME_MAX] = 0; + fd = -errno; + } + } + + closedir(folder); + + return fd; +} + VkResult DisplaySurfaceKHR::GetDisplayModeProperties(uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) { *pPropertyCount = 1; if(pProperties) { - int fd = open("/dev/dri/card0", O_RDWR); + const int fd = openCard(); + if(fd < 0) + { + return VK_NOT_READY; + } + drmModeRes *res = drmModeGetResources(fd); drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]); pProperties->displayMode = (uintptr_t)connector->modes[0].name; @@ -48,7 +97,12 @@ VkResult DisplaySurfaceKHR::GetDisplayPlaneCapabilities(VkDisplayPlaneCapabilitiesKHR *pCapabilities) { - int fd = open("/dev/dri/card0", O_RDWR); + const int fd = openCard(); + if(fd < 0) + { + return VK_NOT_READY; + } + drmModeRes *res = drmModeGetResources(fd); drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]); pCapabilities->supportedAlpha = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; @@ -81,7 +135,12 @@ if(pDisplays) { - int fd = open("/dev/dri/card0", O_RDWR); + const int fd = openCard(); + if(fd < 0) + { + return VK_NOT_READY; + } + drmModeRes *res = drmModeGetResources(fd); *pDisplays = res->connectors[0]; drmModeFreeResources(res); @@ -97,7 +156,12 @@ if(pProperties) { - int fd = open("/dev/dri/card0", O_RDWR); + const int fd = openCard(); + if(fd < 0) + { + return VK_NOT_READY; + } + drmModeRes *res = drmModeGetResources(fd); pProperties->currentDisplay = res->connectors[0]; pProperties->currentStackIndex = 0; @@ -114,7 +178,12 @@ if(pProperties) { - int fd = open("/dev/dri/card0", O_RDWR); + const int fd = openCard(); + if(fd < 0) + { + return VK_NOT_READY; + } + drmModeRes *res = drmModeGetResources(fd); drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]); pProperties->display = res->connectors[0]; @@ -141,7 +210,12 @@ DisplaySurfaceKHR::DisplaySurfaceKHR(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, void *mem) { - fd = open("/dev/dri/card0", O_RDWR); + fd = openCard(); + if(fd < 0) + { + return; + } + drmModeRes *res = drmModeGetResources(fd); connector_id = res->connectors[0]; drmModeFreeResources(res);