xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/linux/DeviceVkLinux.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DeviceVkLinux.cpp:
7 //    Implements the class methods for DeviceVkLinux.
8 //
9 
10 #include "libANGLE/renderer/vulkan/linux/DeviceVkLinux.h"
11 
12 #include <unistd.h>
13 
14 #include "common/debug.h"
15 #include "common/vulkan/vulkan_icd.h"
16 #include "libANGLE/Display.h"
17 #include "libANGLE/renderer/vulkan/DisplayVk.h"
18 #include "libANGLE/renderer/vulkan/vk_renderer.h"
19 
20 namespace rx
21 {
22 
DeviceVkLinux(DisplayVk * display)23 DeviceVkLinux::DeviceVkLinux(DisplayVk *display) : mDisplay(display) {}
24 
initialize()25 egl::Error DeviceVkLinux::initialize()
26 {
27     vk::Renderer *renderer                         = mDisplay->getRenderer();
28     VkPhysicalDeviceDrmPropertiesEXT drmProperties = renderer->getPhysicalDeviceDrmProperties();
29 
30     // Unfortunately `VkPhysicalDeviceDrmPropertiesEXT` doesn't give us the information about the
31     // filesystem layout needed by the EGL version. As ChromeOS/Exo is currently the only user,
32     // implement the extension only for Linux where we can reasonably assume `/dev/dri/...` file
33     // paths.
34     if (drmProperties.hasPrimary)
35     {
36         char deviceName[50];
37         const long long primaryMinor = drmProperties.primaryMinor;
38         snprintf(deviceName, sizeof(deviceName), "/dev/dri/card%lld", primaryMinor);
39 
40         if (access(deviceName, F_OK) != -1)
41         {
42             mDrmDevice = deviceName;
43         }
44     }
45     if (drmProperties.hasRender)
46     {
47         char deviceName[50];
48         const long long renderMinor = drmProperties.renderMinor;
49         snprintf(deviceName, sizeof(deviceName), "/dev/dri/renderD%lld", renderMinor);
50 
51         if (access(deviceName, F_OK) != -1)
52         {
53             mDrmRenderNode = deviceName;
54         }
55     }
56 
57     if (mDrmDevice.empty() && !mDrmRenderNode.empty())
58     {
59         mDrmDevice = mDrmRenderNode;
60     }
61 
62     return egl::NoError();
63 }
64 
generateExtensions(egl::DeviceExtensions * outExtensions) const65 void DeviceVkLinux::generateExtensions(egl::DeviceExtensions *outExtensions) const
66 {
67     DeviceVk::generateExtensions(outExtensions);
68 
69     if (!mDrmDevice.empty())
70     {
71         outExtensions->deviceDrmEXT = true;
72     }
73     if (!mDrmRenderNode.empty())
74     {
75         outExtensions->deviceDrmRenderNodeEXT = true;
76     }
77 }
78 
getDeviceString(EGLint name)79 const std::string DeviceVkLinux::getDeviceString(EGLint name)
80 {
81     switch (name)
82     {
83         case EGL_DRM_DEVICE_FILE_EXT:
84             return mDrmDevice;
85         case EGL_DRM_RENDER_NODE_FILE_EXT:
86             return mDrmRenderNode;
87         default:
88             UNIMPLEMENTED();
89             return std::string();
90     }
91 }
92 
93 }  // namespace rx
94