xref: /aosp_15_r20/external/igt-gpu-tools/tests/ion_fb.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
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