xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/drivers/modesetting/dri3.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *  Copyright (c) 2020, Fuzhou Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *  This program is free software; you can redistribute it and/or modify
5*4882a593Smuzhiyun  *  it under the terms of the GNU General Public License as published by
6*4882a593Smuzhiyun  *  the Free Software Foundation; either version 2 of the License, or
7*4882a593Smuzhiyun  *  (at your option) any later version.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  *  This program is distributed in the hope that it will be useful,
10*4882a593Smuzhiyun  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11*4882a593Smuzhiyun  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*4882a593Smuzhiyun  *  GNU General Public License for more details.
13*4882a593Smuzhiyun  */
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
16*4882a593Smuzhiyun #include "dix-config.h"
17*4882a593Smuzhiyun #endif
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <unistd.h>
20*4882a593Smuzhiyun #include <fcntl.h>
21*4882a593Smuzhiyun #include <drm_fourcc.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "xf86.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "dri3.h"
26*4882a593Smuzhiyun #include "driver.h"
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /* Based on glamor/glamor_egl.c#glamor_dri3_open_client */
29*4882a593Smuzhiyun static int
ms_exa_dri3_open_client(ClientPtr client,ScreenPtr screen,RRProviderPtr provider,int * fdp)30*4882a593Smuzhiyun ms_exa_dri3_open_client(ClientPtr client,
31*4882a593Smuzhiyun                         ScreenPtr screen,
32*4882a593Smuzhiyun                         RRProviderPtr provider,
33*4882a593Smuzhiyun                         int *fdp)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
36*4882a593Smuzhiyun     modesettingPtr ms = modesettingPTR(scrn);
37*4882a593Smuzhiyun     int fd;
38*4882a593Smuzhiyun     drm_magic_t magic;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun     fd = open(ms->drmmode.dri3_device_name, O_RDWR|O_CLOEXEC);
41*4882a593Smuzhiyun     if (fd < 0)
42*4882a593Smuzhiyun         return BadAlloc;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun     /* Before FD passing in the X protocol with DRI3 (and increased
45*4882a593Smuzhiyun      * security of rendering with per-process address spaces on the
46*4882a593Smuzhiyun      * GPU), the kernel had to come up with a way to have the server
47*4882a593Smuzhiyun      * decide which clients got to access the GPU, which was done by
48*4882a593Smuzhiyun      * each client getting a unique (magic) number from the kernel,
49*4882a593Smuzhiyun      * passing it to the server, and the server then telling the
50*4882a593Smuzhiyun      * kernel which clients were authenticated for using the device.
51*4882a593Smuzhiyun      *
52*4882a593Smuzhiyun      * Now that we have FD passing, the server can just set up the
53*4882a593Smuzhiyun      * authentication on its own and hand the prepared FD off to the
54*4882a593Smuzhiyun      * client.
55*4882a593Smuzhiyun      */
56*4882a593Smuzhiyun     if (drmGetMagic(fd, &magic) < 0) {
57*4882a593Smuzhiyun         if (errno == EACCES) {
58*4882a593Smuzhiyun             /* Assume that we're on a render node, and the fd is
59*4882a593Smuzhiyun              * already as authenticated as it should be.
60*4882a593Smuzhiyun              */
61*4882a593Smuzhiyun             *fdp = fd;
62*4882a593Smuzhiyun             return Success;
63*4882a593Smuzhiyun         } else {
64*4882a593Smuzhiyun             close(fd);
65*4882a593Smuzhiyun             return BadMatch;
66*4882a593Smuzhiyun         }
67*4882a593Smuzhiyun     }
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun     if (drmAuthMagic(ms->drmmode.fd, magic) < 0) {
70*4882a593Smuzhiyun         close(fd);
71*4882a593Smuzhiyun         return BadMatch;
72*4882a593Smuzhiyun     }
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun     *fdp = fd;
75*4882a593Smuzhiyun     return Success;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun static PixmapPtr
ms_exa_pixmap_from_fds(ScreenPtr screen,CARD8 num_fds,const int * fds,CARD16 width,CARD16 height,const CARD32 * strides,const CARD32 * offsets,CARD8 depth,CARD8 bpp,uint64_t modifier)79*4882a593Smuzhiyun ms_exa_pixmap_from_fds(ScreenPtr screen,
80*4882a593Smuzhiyun                        CARD8 num_fds, const int *fds,
81*4882a593Smuzhiyun                        CARD16 width, CARD16 height,
82*4882a593Smuzhiyun                        const CARD32 *strides, const CARD32 *offsets,
83*4882a593Smuzhiyun                        CARD8 depth, CARD8 bpp,
84*4882a593Smuzhiyun                        uint64_t modifier)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
87*4882a593Smuzhiyun     modesettingPtr ms = modesettingPTR(scrn);
88*4882a593Smuzhiyun 	PixmapPtr pixmap;
89*4882a593Smuzhiyun 	struct dumb_bo *bo;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun     if (num_fds != 1 || offsets[0] || modifier != DRM_FORMAT_MOD_INVALID)
92*4882a593Smuzhiyun         return NULL;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun     pixmap = drmmode_create_pixmap_header(screen, width, height,
95*4882a593Smuzhiyun                                           depth, bpp, strides[0], NULL);
96*4882a593Smuzhiyun     if (!pixmap)
97*4882a593Smuzhiyun         return NULL;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun     bo = dumb_get_bo_from_fd(ms->drmmode.fd, fds[0],
100*4882a593Smuzhiyun                              strides[0], strides[0] * height);
101*4882a593Smuzhiyun     if (!bo)
102*4882a593Smuzhiyun         goto err_free_pixmap;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun     if (!ms_exa_set_pixmap_bo(scrn, pixmap, bo, TRUE))
105*4882a593Smuzhiyun         goto err_free_bo;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun     return pixmap;
108*4882a593Smuzhiyun err_free_bo:
109*4882a593Smuzhiyun     dumb_bo_destroy(ms->drmmode.fd, bo);
110*4882a593Smuzhiyun err_free_pixmap:
111*4882a593Smuzhiyun     screen->DestroyPixmap(pixmap);
112*4882a593Smuzhiyun     return NULL;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun static int
ms_exa_egl_fd_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,CARD16 * stride,CARD32 * size)116*4882a593Smuzhiyun ms_exa_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
117*4882a593Smuzhiyun                           CARD16 *stride, CARD32 *size)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
120*4882a593Smuzhiyun     modesettingPtr ms = modesettingPTR(scrn);
121*4882a593Smuzhiyun 	struct dumb_bo *bo;
122*4882a593Smuzhiyun 	int fd;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     bo = ms_exa_bo_from_pixmap(screen, pixmap);
125*4882a593Smuzhiyun     if (!bo)
126*4882a593Smuzhiyun         return -1;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun     fd = dumb_bo_get_fd(ms->drmmode.fd, bo, 0);
129*4882a593Smuzhiyun     *stride = bo->pitch;
130*4882a593Smuzhiyun 	*size = bo->size;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun     return fd;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun static int
ms_exa_egl_fds_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,int * fds,uint32_t * strides,uint32_t * offsets,uint64_t * modifier)136*4882a593Smuzhiyun ms_exa_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
137*4882a593Smuzhiyun                            uint32_t *strides, uint32_t *offsets,
138*4882a593Smuzhiyun                            uint64_t *modifier)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
141*4882a593Smuzhiyun     modesettingPtr ms = modesettingPTR(scrn);
142*4882a593Smuzhiyun 	struct dumb_bo *bo;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun     bo = ms_exa_bo_from_pixmap(screen, pixmap);
145*4882a593Smuzhiyun     if (!bo)
146*4882a593Smuzhiyun         return 0;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun     fds[0] = dumb_bo_get_fd(ms->drmmode.fd, bo, 0);
149*4882a593Smuzhiyun     strides[0] = bo->pitch;
150*4882a593Smuzhiyun     offsets[0] = 0;
151*4882a593Smuzhiyun     *modifier = DRM_FORMAT_MOD_INVALID;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun     return 1;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun static Bool
ms_exa_get_formats(ScreenPtr screen,CARD32 * num_formats,CARD32 ** formats)157*4882a593Smuzhiyun ms_exa_get_formats(ScreenPtr screen,
158*4882a593Smuzhiyun 				   CARD32 *num_formats, CARD32 **formats)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	/* TODO: Return formats */
161*4882a593Smuzhiyun     *num_formats = 0;
162*4882a593Smuzhiyun     return TRUE;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun static Bool
ms_exa_get_modifiers(ScreenPtr screen,uint32_t format,uint32_t * num_modifiers,uint64_t ** modifiers)166*4882a593Smuzhiyun ms_exa_get_modifiers(ScreenPtr screen, uint32_t format,
167*4882a593Smuzhiyun                      uint32_t *num_modifiers, uint64_t **modifiers)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun     *num_modifiers = 0;
170*4882a593Smuzhiyun     return TRUE;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun static Bool
ms_exa_get_drawable_modifiers(DrawablePtr draw,uint32_t format,uint32_t * num_modifiers,uint64_t ** modifiers)174*4882a593Smuzhiyun ms_exa_get_drawable_modifiers(DrawablePtr draw, uint32_t format,
175*4882a593Smuzhiyun                               uint32_t *num_modifiers, uint64_t **modifiers)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun     *num_modifiers = 0;
178*4882a593Smuzhiyun     return TRUE;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun static const dri3_screen_info_rec ms_exa_dri3_info = {
182*4882a593Smuzhiyun     .version = 2,
183*4882a593Smuzhiyun     .open_client = ms_exa_dri3_open_client,
184*4882a593Smuzhiyun     .pixmap_from_fds = ms_exa_pixmap_from_fds,
185*4882a593Smuzhiyun     .fd_from_pixmap = ms_exa_egl_fd_from_pixmap,
186*4882a593Smuzhiyun     .fds_from_pixmap = ms_exa_egl_fds_from_pixmap,
187*4882a593Smuzhiyun     .get_formats = ms_exa_get_formats,
188*4882a593Smuzhiyun     .get_modifiers = ms_exa_get_modifiers,
189*4882a593Smuzhiyun     .get_drawable_modifiers = ms_exa_get_drawable_modifiers,
190*4882a593Smuzhiyun };
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun Bool
ms_exa_dri3_init(ScreenPtr screen)193*4882a593Smuzhiyun ms_exa_dri3_init(ScreenPtr screen)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
196*4882a593Smuzhiyun     modesettingPtr ms = modesettingPTR(scrn);
197*4882a593Smuzhiyun     ms->drmmode.dri3_device_name = drmGetDeviceNameFromFd2(ms->drmmode.fd);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	return dri3_screen_init(screen, &ms_exa_dri3_info);
200*4882a593Smuzhiyun }
201