1 #include "drm.h"
2 #include "gem.h"
3 #include "igt.h"
4 #include "ion.h"
5
6 #include <ion/ion.h>
7
size_for_fb(const struct fb_configuration * config)8 size_t size_for_fb(const struct fb_configuration *config)
9 {
10 return config->width * config->height * config->pixel_size;
11 }
12
13 /**
14 * test_make_fb
15 *
16 * Tests that an ion buffer can be ingested into DRM to the point
17 * where it can be used for a framebuffer
18 **/
19
make_fb_with_buffer(int drm_fd,int ion_fd,const struct fb_configuration * config,int ion_buffer_fd)20 static void make_fb_with_buffer(int drm_fd, int ion_fd,
21 const struct fb_configuration *config,
22 int ion_buffer_fd)
23 {
24 uint32_t fb_id = 0;
25
26 igt_assert_eq(0, drm_check_prime_caps(drm_fd));
27 igt_assert_eq(0, drm_fb_for_ion_buffer(
28 drm_fd, &fb_id, ion_buffer_fd, config));
29 drm_release_fb(drm_fd, fb_id);
30 }
31
make_fb_with_fds(int drm_fd,int ion_fd,const struct fb_configuration * config)32 static void make_fb_with_fds(int drm_fd, int ion_fd,
33 const struct fb_configuration *config)
34 {
35 int ion_buffer_fd;
36
37 const int heap_id = ion_get_heap_id(ion_fd, ION_HEAP_TYPE_SYSTEM);
38 igt_assert(heap_id != -1);
39
40 igt_assert(!ion_alloc_one_fd(
41 ion_fd,
42 size_for_fb(config),
43 heap_id,
44 &ion_buffer_fd));
45
46 make_fb_with_buffer(drm_fd, ion_fd, config, ion_buffer_fd);
47
48 close(ion_buffer_fd);
49 }
50
test_make_fb(const struct fb_configuration * config)51 static void test_make_fb(const struct fb_configuration *config)
52 {
53 const int drm_fd = drm_open_driver(DRIVER_ANY);
54 igt_assert(drm_fd >= 0);
55
56 const int ion_fd = ion_open();
57 igt_assert(ion_fd >= 0);
58
59 make_fb_with_fds(drm_fd, ion_fd, config);
60
61 ion_close(ion_fd);
62 close(drm_fd);
63 }
64
65 /**
66 * test_clone
67 *
68 * Tests that an ion buffer can be 'cloned' by making a GEM buffer out of
69 * it and then reversing the process
70 **/
71
clone_with_fds(int drm_fd,int ion_fd,const struct fb_configuration * config)72 static void clone_with_fds(int drm_fd, int ion_fd,
73 const struct fb_configuration *config)
74 {
75 int ion_buffer_fd;
76
77 const int heap_id = ion_get_heap_id(ion_fd, ION_HEAP_TYPE_SYSTEM);
78 igt_assert(heap_id != -1);
79
80 igt_assert(!ion_alloc_one_fd(
81 ion_fd,
82 size_for_fb(config),
83 heap_id,
84 &ion_buffer_fd));
85
86 int clone_fd = 0;
87
88 igt_assert(!ion_clone_fd_via_gem(drm_fd, &clone_fd, ion_buffer_fd));
89
90 igt_assert(clone_fd >= 0);
91 igt_assert(clone_fd != ion_buffer_fd);
92
93 close(clone_fd);
94 close(ion_buffer_fd);
95 }
96
test_clone(const struct fb_configuration * config)97 static void test_clone(const struct fb_configuration *config)
98 {
99 const int drm_fd = drm_open_driver(DRIVER_ANY);
100 igt_assert(drm_fd >= 0);
101
102 const int ion_fd = ion_open();
103 igt_assert(ion_fd >= 0);
104
105 clone_with_fds(drm_fd, ion_fd, config);
106
107 ion_close(ion_fd);
108 close(drm_fd);
109 }
110
111 /**
112 * test_mmap
113 *
114 * Tests that the GEM version of an ion buffer contains the same data that
115 * the original ion buffer did
116 **/
117
mmap_with_buffer(int drm_fd,int ion_fd,uint8_t * buffer,size_t size)118 static void mmap_with_buffer(int drm_fd, int ion_fd,
119 uint8_t *buffer, size_t size)
120 {
121 int ion_buffer_fd;
122
123 const int heap_id = ion_get_heap_id(ion_fd, ION_HEAP_TYPE_SYSTEM);
124 igt_assert(heap_id != -1);
125
126 const struct gem_driver *gem = gem_get_driver(drm_fd);
127 igt_assert(gem != NULL);
128
129 igt_assert(!ion_alloc_one_fd(
130 ion_fd,
131 size,
132 heap_id,
133 &ion_buffer_fd));
134
135 void *ion_ptr = NULL;
136
137 igt_assert(!ion_mmap(&ion_ptr, ion_buffer_fd, size));
138
139 memcpy(buffer, ion_ptr, size);
140
141 igt_assert(!ion_munmap(ion_ptr, size));
142
143 uint32_t gem_handle = 0;
144
145 igt_assert(!gem_handle_for_ion_buffer(
146 drm_fd,
147 &gem_handle,
148 ion_buffer_fd));
149
150 close(ion_buffer_fd);
151
152 size_t gem_buf_size = 0;
153
154 igt_assert(!gem_size(drm_fd, &gem_buf_size, gem_handle));
155 igt_assert_eq(gem_buf_size, size);
156
157 void *gem_ptr = NULL;
158 igt_assert(!gem->mmap(
159 &gem_ptr,
160 drm_fd,
161 gem_handle,
162 size));
163
164 igt_assert(!memcmp(buffer, gem_ptr, size));
165
166 igt_assert(!gem->munmap(
167 drm_fd,
168 gem_handle,
169 gem_ptr,
170 size));
171
172 gem_release_handle(drm_fd, gem_handle);
173 }
174
mmap_with_fds(int drm_fd,int ion_fd,const struct fb_configuration * config)175 static void mmap_with_fds(int drm_fd, int ion_fd,
176 const struct fb_configuration *config)
177 {
178 uint8_t *buffer = malloc(size_for_fb(config));
179 igt_assert(buffer);
180
181 mmap_with_buffer(drm_fd, ion_fd, buffer, size_for_fb(config));
182
183 free(buffer);
184 }
185
test_mmap(const struct fb_configuration * config)186 static void test_mmap(const struct fb_configuration *config)
187 {
188 const int drm_fd = drm_open_driver(DRIVER_ANY);
189 igt_assert(drm_fd >= 0);
190
191 const int ion_fd = ion_open();
192 igt_assert(ion_fd >= 0);
193
194 mmap_with_fds(drm_fd, ion_fd, config);
195
196 ion_close(ion_fd);
197 close(drm_fd);
198 }
199
200 igt_main
201 {
202 const struct fb_configuration config = {
203 .width = 1024,
204 .height = 1024,
205 .pixel_format = DRM_FORMAT_ABGR8888,
206 .pixel_size = 4
207 };
208
209 igt_subtest("make-fb")
210 {
211 test_make_fb(&config);
212 }
213
214 igt_subtest("clone")
215 {
216 test_clone(&config);
217 }
218
219 igt_subtest("mmap")
220 {
221 test_mmap(&config);
222 }
223 }
224