xref: /aosp_15_r20/external/mesa3d/src/freedreno/drm/freedreno_device.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2012-2018 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * Authors:
6*61046927SAndroid Build Coastguard Worker  *    Rob Clark <[email protected]>
7*61046927SAndroid Build Coastguard Worker  */
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include <unistd.h>
10*61046927SAndroid Build Coastguard Worker #include <sys/stat.h>
11*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "util/os_file.h"
14*61046927SAndroid Build Coastguard Worker #include "util/u_process.h"
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker #include "freedreno_rd_output.h"
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker #include "freedreno_drmif.h"
19*61046927SAndroid Build Coastguard Worker #include "freedreno_drm_perfetto.h"
20*61046927SAndroid Build Coastguard Worker #include "freedreno_priv.h"
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker struct fd_device *msm_device_new(int fd, drmVersionPtr version);
23*61046927SAndroid Build Coastguard Worker #ifdef HAVE_FREEDRENO_VIRTIO
24*61046927SAndroid Build Coastguard Worker struct fd_device *virtio_device_new(int fd, drmVersionPtr version);
25*61046927SAndroid Build Coastguard Worker #endif
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker uint64_t os_page_size = 4096;
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker struct fd_device *
fd_device_new(int fd)30*61046927SAndroid Build Coastguard Worker fd_device_new(int fd)
31*61046927SAndroid Build Coastguard Worker {
32*61046927SAndroid Build Coastguard Worker    struct fd_device *dev = NULL;
33*61046927SAndroid Build Coastguard Worker    drmVersionPtr version;
34*61046927SAndroid Build Coastguard Worker    bool use_heap = false;
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker    os_get_page_size(&os_page_size);
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker    /* figure out if we are kgsl or msm drm driver: */
39*61046927SAndroid Build Coastguard Worker    version = drmGetVersion(fd);
40*61046927SAndroid Build Coastguard Worker    if (!version) {
41*61046927SAndroid Build Coastguard Worker       ERROR_MSG("cannot get version: %s", strerror(errno));
42*61046927SAndroid Build Coastguard Worker       return NULL;
43*61046927SAndroid Build Coastguard Worker    }
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker    if (!strcmp(version->name, "msm")) {
46*61046927SAndroid Build Coastguard Worker       DEBUG_MSG("msm DRM device");
47*61046927SAndroid Build Coastguard Worker       if (version->version_major != 1) {
48*61046927SAndroid Build Coastguard Worker          ERROR_MSG("unsupported version: %u.%u.%u", version->version_major,
49*61046927SAndroid Build Coastguard Worker                    version->version_minor, version->version_patchlevel);
50*61046927SAndroid Build Coastguard Worker          goto out;
51*61046927SAndroid Build Coastguard Worker       }
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker       dev = msm_device_new(fd, version);
54*61046927SAndroid Build Coastguard Worker #ifdef HAVE_FREEDRENO_VIRTIO
55*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(version->name, "virtio_gpu")) {
56*61046927SAndroid Build Coastguard Worker       DEBUG_MSG("virtio_gpu DRM device");
57*61046927SAndroid Build Coastguard Worker       dev = virtio_device_new(fd, version);
58*61046927SAndroid Build Coastguard Worker       /* Only devices that support a hypervisor are a6xx+, so avoid the
59*61046927SAndroid Build Coastguard Worker        * extra guest<->host round trips associated with pipe creation:
60*61046927SAndroid Build Coastguard Worker        */
61*61046927SAndroid Build Coastguard Worker       use_heap = true;
62*61046927SAndroid Build Coastguard Worker #endif
63*61046927SAndroid Build Coastguard Worker #if HAVE_FREEDRENO_KGSL
64*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(version->name, "kgsl")) {
65*61046927SAndroid Build Coastguard Worker       DEBUG_MSG("kgsl DRM device");
66*61046927SAndroid Build Coastguard Worker       dev = kgsl_device_new(fd);
67*61046927SAndroid Build Coastguard Worker #endif
68*61046927SAndroid Build Coastguard Worker    }
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    if (!dev) {
71*61046927SAndroid Build Coastguard Worker       INFO_MSG("unsupported device: %s", version->name);
72*61046927SAndroid Build Coastguard Worker       goto out;
73*61046927SAndroid Build Coastguard Worker    }
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker out:
76*61046927SAndroid Build Coastguard Worker    drmFreeVersion(version);
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker    if (!dev)
79*61046927SAndroid Build Coastguard Worker       return NULL;
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker    fd_drm_perfetto_init();
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    fd_rd_dump_env_init();
84*61046927SAndroid Build Coastguard Worker    fd_rd_output_init(&dev->rd, util_get_process_name());
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    p_atomic_set(&dev->refcnt, 1);
87*61046927SAndroid Build Coastguard Worker    dev->fd = fd;
88*61046927SAndroid Build Coastguard Worker    dev->handle_table =
89*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);
90*61046927SAndroid Build Coastguard Worker    dev->name_table =
91*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);
92*61046927SAndroid Build Coastguard Worker    fd_bo_cache_init(&dev->bo_cache, false, "bo");
93*61046927SAndroid Build Coastguard Worker    fd_bo_cache_init(&dev->ring_cache, true, "ring");
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker    list_inithead(&dev->deferred_submits);
96*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&dev->submit_lock, mtx_plain);
97*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&dev->suballoc_lock, mtx_plain);
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    if (!use_heap) {
100*61046927SAndroid Build Coastguard Worker       struct fd_pipe *pipe = fd_pipe_new(dev, FD_PIPE_3D);
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker       if (!pipe)
103*61046927SAndroid Build Coastguard Worker          goto fail;
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker       /* Userspace fences don't appear to be reliable enough (missing some
106*61046927SAndroid Build Coastguard Worker        * cache flushes?) on older gens, so limit sub-alloc heaps to a6xx+
107*61046927SAndroid Build Coastguard Worker        * for now:
108*61046927SAndroid Build Coastguard Worker        */
109*61046927SAndroid Build Coastguard Worker       use_heap = fd_dev_gen(&pipe->dev_id) >= 6;
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker       fd_pipe_del(pipe);
112*61046927SAndroid Build Coastguard Worker    }
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    if (use_heap) {
115*61046927SAndroid Build Coastguard Worker       dev->ring_heap = fd_bo_heap_new(dev, RING_FLAGS);
116*61046927SAndroid Build Coastguard Worker       dev->default_heap = fd_bo_heap_new(dev, 0);
117*61046927SAndroid Build Coastguard Worker    }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    return dev;
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker fail:
122*61046927SAndroid Build Coastguard Worker    fd_device_del(dev);
123*61046927SAndroid Build Coastguard Worker    return NULL;
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker /* like fd_device_new() but creates it's own private dup() of the fd
127*61046927SAndroid Build Coastguard Worker  * which is close()d when the device is finalized.
128*61046927SAndroid Build Coastguard Worker  */
129*61046927SAndroid Build Coastguard Worker struct fd_device *
fd_device_new_dup(int fd)130*61046927SAndroid Build Coastguard Worker fd_device_new_dup(int fd)
131*61046927SAndroid Build Coastguard Worker {
132*61046927SAndroid Build Coastguard Worker    int dup_fd = os_dupfd_cloexec(fd);
133*61046927SAndroid Build Coastguard Worker    struct fd_device *dev = fd_device_new(dup_fd);
134*61046927SAndroid Build Coastguard Worker    if (dev)
135*61046927SAndroid Build Coastguard Worker       dev->closefd = 1;
136*61046927SAndroid Build Coastguard Worker    else
137*61046927SAndroid Build Coastguard Worker       close(dup_fd);
138*61046927SAndroid Build Coastguard Worker    return dev;
139*61046927SAndroid Build Coastguard Worker }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker /* Convenience helper to open the drm device and return new fd_device:
142*61046927SAndroid Build Coastguard Worker  */
143*61046927SAndroid Build Coastguard Worker struct fd_device *
fd_device_open(void)144*61046927SAndroid Build Coastguard Worker fd_device_open(void)
145*61046927SAndroid Build Coastguard Worker {
146*61046927SAndroid Build Coastguard Worker    int fd;
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker    fd = drmOpenWithType("msm", NULL, DRM_NODE_RENDER);
149*61046927SAndroid Build Coastguard Worker #ifdef HAVE_FREEDRENO_VIRTIO
150*61046927SAndroid Build Coastguard Worker    if (fd < 0)
151*61046927SAndroid Build Coastguard Worker       fd = drmOpenWithType("virtio_gpu", NULL, DRM_NODE_RENDER);
152*61046927SAndroid Build Coastguard Worker #endif
153*61046927SAndroid Build Coastguard Worker    if (fd < 0)
154*61046927SAndroid Build Coastguard Worker       return NULL;
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker    return fd_device_new(fd);
157*61046927SAndroid Build Coastguard Worker }
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker struct fd_device *
fd_device_ref(struct fd_device * dev)160*61046927SAndroid Build Coastguard Worker fd_device_ref(struct fd_device *dev)
161*61046927SAndroid Build Coastguard Worker {
162*61046927SAndroid Build Coastguard Worker    ref(&dev->refcnt);
163*61046927SAndroid Build Coastguard Worker    return dev;
164*61046927SAndroid Build Coastguard Worker }
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker void
fd_device_purge(struct fd_device * dev)167*61046927SAndroid Build Coastguard Worker fd_device_purge(struct fd_device *dev)
168*61046927SAndroid Build Coastguard Worker {
169*61046927SAndroid Build Coastguard Worker    fd_bo_cache_cleanup(&dev->bo_cache, 0);
170*61046927SAndroid Build Coastguard Worker    fd_bo_cache_cleanup(&dev->ring_cache, 0);
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker void
fd_device_del(struct fd_device * dev)174*61046927SAndroid Build Coastguard Worker fd_device_del(struct fd_device *dev)
175*61046927SAndroid Build Coastguard Worker {
176*61046927SAndroid Build Coastguard Worker    if (!unref(&dev->refcnt))
177*61046927SAndroid Build Coastguard Worker       return;
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker    fd_rd_output_fini(&dev->rd);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    assert(list_is_empty(&dev->deferred_submits));
182*61046927SAndroid Build Coastguard Worker    assert(!dev->deferred_submits_fence);
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker    if (dev->suballoc_bo)
185*61046927SAndroid Build Coastguard Worker       fd_bo_del(dev->suballoc_bo);
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    if (dev->ring_heap)
188*61046927SAndroid Build Coastguard Worker       fd_bo_heap_destroy(dev->ring_heap);
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker    if (dev->default_heap)
191*61046927SAndroid Build Coastguard Worker       fd_bo_heap_destroy(dev->default_heap);
192*61046927SAndroid Build Coastguard Worker 
193*61046927SAndroid Build Coastguard Worker    fd_bo_cache_cleanup(&dev->bo_cache, 0);
194*61046927SAndroid Build Coastguard Worker    fd_bo_cache_cleanup(&dev->ring_cache, 0);
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    /* Needs to be after bo cache cleanup in case backend has a
197*61046927SAndroid Build Coastguard Worker     * util_vma_heap that it destroys:
198*61046927SAndroid Build Coastguard Worker     */
199*61046927SAndroid Build Coastguard Worker    dev->funcs->destroy(dev);
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(dev->handle_table, NULL);
202*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(dev->name_table, NULL);
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker    if (fd_device_threaded_submit(dev))
205*61046927SAndroid Build Coastguard Worker       util_queue_destroy(&dev->submit_queue);
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker    if (dev->closefd)
208*61046927SAndroid Build Coastguard Worker       close(dev->fd);
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker    free(dev);
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker int
fd_device_fd(struct fd_device * dev)214*61046927SAndroid Build Coastguard Worker fd_device_fd(struct fd_device *dev)
215*61046927SAndroid Build Coastguard Worker {
216*61046927SAndroid Build Coastguard Worker    return dev->fd;
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker enum fd_version
fd_device_version(struct fd_device * dev)220*61046927SAndroid Build Coastguard Worker fd_device_version(struct fd_device *dev)
221*61046927SAndroid Build Coastguard Worker {
222*61046927SAndroid Build Coastguard Worker    return dev->version;
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker DEBUG_GET_ONCE_BOOL_OPTION(libgl, "LIBGL_DEBUG", false)
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker bool
fd_dbg(void)228*61046927SAndroid Build Coastguard Worker fd_dbg(void)
229*61046927SAndroid Build Coastguard Worker {
230*61046927SAndroid Build Coastguard Worker    return debug_get_option_libgl();
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker bool
fd_has_syncobj(struct fd_device * dev)234*61046927SAndroid Build Coastguard Worker fd_has_syncobj(struct fd_device *dev)
235*61046927SAndroid Build Coastguard Worker {
236*61046927SAndroid Build Coastguard Worker    uint64_t value;
237*61046927SAndroid Build Coastguard Worker    if (drmGetCap(dev->fd, DRM_CAP_SYNCOBJ, &value))
238*61046927SAndroid Build Coastguard Worker       return false;
239*61046927SAndroid Build Coastguard Worker    return value && dev->version >= FD_VERSION_FENCE_FD;
240*61046927SAndroid Build Coastguard Worker }
241