1 #include "gem.h"
2
3 #include "gem_msm.h"
4
5 struct gem_driver_lookup
6 {
7 const char name[16];
8 struct gem_driver *driver;
9 };
10
11 static struct gem_driver_lookup drivers[] = {
12 {
13 .name = "msm_drm",
14 .driver = &gem_msm_driver
15 }
16 };
17
num_drivers()18 static inline size_t num_drivers()
19 {
20 return ARRAY_SIZE(drivers);
21 }
22
gem_get_driver(int drm_fd)23 struct gem_driver *gem_get_driver(int drm_fd)
24 {
25 char name[16] = {0};
26 drm_version_t version = {};
27
28 version.name_len = sizeof(name);
29 version.name = name;
30
31 if (drmIoctl(drm_fd, DRM_IOCTL_VERSION, &version))
32 {
33 return NULL;
34 }
35
36 for (struct gem_driver_lookup *di = drivers;
37 di - drivers < num_drivers();
38 ++di)
39 {
40 if (!strncmp(name, di->name, sizeof(name)))
41 {
42 return di->driver;
43 }
44 }
45
46 return NULL;
47 }
48
gem_size(int drm_fd,size_t * size,uint32_t gem_handle)49 int gem_size(int drm_fd, size_t *size, uint32_t gem_handle)
50 {
51 struct drm_gem_flink drm_gem_flink_arg = {
52 .handle = gem_handle,
53 .name = 0
54 };
55
56 if (drmIoctl(drm_fd,
57 DRM_IOCTL_GEM_FLINK,
58 &drm_gem_flink_arg))
59 {
60 return -1;
61 }
62
63 struct drm_gem_open drm_gem_open_arg = {
64 .name = drm_gem_flink_arg.name,
65 .handle = 0,
66 .size = 0
67 };
68
69 if (drmIoctl(drm_fd,
70 DRM_IOCTL_GEM_OPEN,
71 &drm_gem_open_arg))
72 {
73 return -1;
74 }
75
76 *size = drm_gem_open_arg.size;
77
78 if (drm_gem_open_arg.handle != gem_handle)
79 {
80 gem_release_handle(drm_fd, drm_gem_open_arg.handle);
81 }
82
83 return 0;
84 }
85
gem_release_handle(int drm_fd,uint32_t gem_handle)86 void gem_release_handle(int drm_fd, uint32_t gem_handle)
87 {
88 struct drm_gem_close drm_gem_close_arg = {
89 .handle = gem_handle,
90 .pad = 0
91 };
92
93 drmIoctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &drm_gem_close_arg);
94 }
95
drm_fb_for_gem_handle(int drm_fd,uint32_t * fb_id,uint32_t gem_handle,const struct fb_configuration * fb_config)96 int drm_fb_for_gem_handle(int drm_fd, uint32_t *fb_id, uint32_t gem_handle,
97 const struct fb_configuration *fb_config)
98 {
99 struct drm_mode_fb_cmd2 drm_mode_addfb2_arg = {
100 .fb_id = 0,
101 .width = fb_config->width,
102 .height = fb_config->height,
103 .pixel_format = fb_config->pixel_format,
104 .flags = DRM_MODE_FB_MODIFIERS,
105 .handles = { gem_handle, 0, 0, 0 },
106 .pitches = { fb_config->width * fb_config->pixel_size, 0, 0, 0 },
107 .offsets = { 0, 0, 0, 0 },
108 .modifier = { 0 }
109 };
110
111 if (drmIoctl(drm_fd, DRM_IOCTL_MODE_ADDFB2, &drm_mode_addfb2_arg))
112 {
113 return -1;
114 }
115
116 *fb_id = drm_mode_addfb2_arg.fb_id;
117
118 return 0;
119 }
120