xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/winsys/pvr_winsys.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include <fcntl.h>
25 #include <stdbool.h>
26 #include <vulkan/vulkan.h>
27 #include <xf86drm.h>
28 
29 #include "powervr/pvr_drm_public.h"
30 #include "pvr_private.h"
31 #include "pvr_winsys.h"
32 #include "vk_log.h"
33 
34 #if defined(PVR_SUPPORT_SERVICES_DRIVER)
35 #   include "pvrsrvkm/pvr_srv_public.h"
36 #endif
37 
pvr_winsys_destroy(struct pvr_winsys * ws)38 void pvr_winsys_destroy(struct pvr_winsys *ws)
39 {
40    const int display_fd = ws->display_fd;
41    const int render_fd = ws->render_fd;
42 
43    ws->ops->destroy(ws);
44 
45    if (display_fd >= 0)
46       close(display_fd);
47 
48    if (render_fd >= 0)
49       close(render_fd);
50 }
51 
pvr_winsys_create(const char * render_path,const char * display_path,const VkAllocationCallbacks * alloc,struct pvr_winsys ** const ws_out)52 VkResult pvr_winsys_create(const char *render_path,
53                            const char *display_path,
54                            const VkAllocationCallbacks *alloc,
55                            struct pvr_winsys **const ws_out)
56 {
57    drmVersionPtr version;
58    VkResult result;
59    int display_fd;
60    int render_fd;
61 
62    render_fd = open(render_path, O_RDWR | O_CLOEXEC);
63    if (render_fd < 0) {
64       result = vk_errorf(NULL,
65                          VK_ERROR_INITIALIZATION_FAILED,
66                          "Failed to open render device %s",
67                          render_path);
68       goto err_out;
69    }
70 
71    if (display_path) {
72       display_fd = open(display_path, O_RDWR | O_CLOEXEC);
73       if (display_fd < 0) {
74          result = vk_errorf(NULL,
75                             VK_ERROR_INITIALIZATION_FAILED,
76                             "Failed to open display device %s",
77                             display_path);
78          goto err_close_render_fd;
79       }
80    } else {
81       display_fd = -1;
82    }
83 
84    version = drmGetVersion(render_fd);
85    if (!version) {
86       result = vk_errorf(NULL,
87                          VK_ERROR_INCOMPATIBLE_DRIVER,
88                          "Failed to query kernel driver version for device.");
89       goto err_close_display_fd;
90    }
91 
92    if (strcmp(version->name, "powervr") == 0) {
93       result = pvr_drm_winsys_create(render_fd, display_fd, alloc, ws_out);
94 #if defined(PVR_SUPPORT_SERVICES_DRIVER)
95    } else if (strcmp(version->name, "pvr") == 0) {
96       result = pvr_srv_winsys_create(render_fd, display_fd, alloc, ws_out);
97 #endif
98    } else {
99       result = vk_errorf(
100          NULL,
101          VK_ERROR_INCOMPATIBLE_DRIVER,
102          "Device does not use any of the supported pvrsrvkm or powervr kernel driver.");
103    }
104 
105    drmFreeVersion(version);
106 
107    if (result != VK_SUCCESS)
108       goto err_close_display_fd;
109 
110    return VK_SUCCESS;
111 
112 err_close_display_fd:
113    if (display_fd >= 0)
114       close(display_fd);
115 
116 err_close_render_fd:
117    close(render_fd);
118 
119 err_out:
120    return result;
121 }
122