aboutsummaryrefslogtreecommitdiffstats
path: root/tests/ion_fb.c
blob: b8b8616105b66bb2c280b2e04bc8cdb179490a3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include "drm.h"
#include "gem.h"
#include "igt.h"
#include "ion.h"

#include <ion/ion.h>

size_t size_for_fb(const struct fb_configuration *config)
{
	return config->width * config->height * config->pixel_size;
}

/**
 * test_make_fb
 *
 * Tests that an ion buffer can be ingested into DRM to the point
 * where it can be used for a framebuffer
 **/

static void make_fb_with_buffer(int drm_fd, int ion_fd,
				const struct fb_configuration *config,
				int ion_buffer_fd)
{
	uint32_t fb_id = 0;

	igt_assert_eq(0, drm_check_prime_caps(drm_fd));
	igt_assert_eq(0, drm_fb_for_ion_buffer(
			drm_fd, &fb_id, ion_buffer_fd, config));
	drm_release_fb(drm_fd, fb_id);
}

static void make_fb_with_fds(int drm_fd, int ion_fd,
			     const struct fb_configuration *config)
{
	int ion_buffer_fd;

	const int heap_id = ion_get_heap_id(ion_fd, ION_HEAP_TYPE_SYSTEM);
	igt_assert(heap_id != -1);

	igt_assert(!ion_alloc_one_fd(
			ion_fd,
			size_for_fb(config),
			heap_id,
			&ion_buffer_fd));

        make_fb_with_buffer(drm_fd, ion_fd, config, ion_buffer_fd);

	close(ion_buffer_fd);
}

static void test_make_fb(const struct fb_configuration *config)
{
	const int drm_fd = drm_open_driver(DRIVER_ANY);
	igt_assert(drm_fd >= 0);

	const int ion_fd = ion_open();
	igt_assert(ion_fd >= 0);

	make_fb_with_fds(drm_fd, ion_fd, config);

	ion_close(ion_fd);
	close(drm_fd);
}

/**
 * test_clone
 *
 * Tests that an ion buffer can be 'cloned' by making a GEM buffer out of
 * it and then reversing the process
 **/

static void clone_with_fds(int drm_fd, int ion_fd,
			   const struct fb_configuration *config)
{
	int ion_buffer_fd;

	const int heap_id = ion_get_heap_id(ion_fd, ION_HEAP_TYPE_SYSTEM);
	igt_assert(heap_id != -1);

	igt_assert(!ion_alloc_one_fd(
			ion_fd,
			size_for_fb(config),
			heap_id,
			&ion_buffer_fd));

	int clone_fd = 0;

	igt_assert(!ion_clone_fd_via_gem(drm_fd, &clone_fd, ion_buffer_fd));

	igt_assert(clone_fd >= 0);
	igt_assert(clone_fd != ion_buffer_fd);

	close(clone_fd);
	close(ion_buffer_fd);
}

static void test_clone(const struct fb_configuration *config)
{
	const int drm_fd = drm_open_driver(DRIVER_ANY);
	igt_assert(drm_fd >= 0);

	const int ion_fd = ion_open();
	igt_assert(ion_fd >= 0);

	clone_with_fds(drm_fd, ion_fd, config);

	ion_close(ion_fd);
	close(drm_fd);
}

/**
 * test_mmap
 *
 * Tests that the GEM version of an ion buffer contains the same data that
 * the original ion buffer did
 **/

static void mmap_with_buffer(int drm_fd, int ion_fd,
			     uint8_t *buffer, size_t size)
{
	int ion_buffer_fd;

	const int heap_id = ion_get_heap_id(ion_fd, ION_HEAP_TYPE_SYSTEM);
	igt_assert(heap_id != -1);

	const struct gem_driver *gem = gem_get_driver(drm_fd);
	igt_assert(gem != NULL);

	igt_assert(!ion_alloc_one_fd(
			ion_fd,
			size,
			heap_id,
			&ion_buffer_fd));

	void *ion_ptr = NULL;

	igt_assert(!ion_mmap(&ion_ptr, ion_buffer_fd, size));

	memcpy(buffer, ion_ptr, size);

	igt_assert(!ion_munmap(ion_ptr, size));

	uint32_t gem_handle = 0;

	igt_assert(!gem_handle_for_ion_buffer(
			drm_fd,
			&gem_handle,
			ion_buffer_fd));

	close(ion_buffer_fd);

	size_t gem_buf_size = 0;

	igt_assert(!gem_size(drm_fd, &gem_buf_size, gem_handle));
	igt_assert_eq(gem_buf_size, size);

	void *gem_ptr = NULL;
	igt_assert(!gem->mmap(
			&gem_ptr,
			drm_fd,
			gem_handle,
			size));

	igt_assert(!memcmp(buffer, gem_ptr, size));

	igt_assert(!gem->munmap(
			drm_fd,
			gem_handle,
			gem_ptr,
			size));

	gem_release_handle(drm_fd, gem_handle);
}

static void mmap_with_fds(int drm_fd, int ion_fd,
			      const struct fb_configuration *config)
{
	uint8_t *buffer = malloc(size_for_fb(config));
	igt_assert(buffer);

	mmap_with_buffer(drm_fd, ion_fd, buffer, size_for_fb(config));

	free(buffer);
}

static void test_mmap(const struct fb_configuration *config)
{
	const int drm_fd = drm_open_driver(DRIVER_ANY);
	igt_assert(drm_fd >= 0);

	const int ion_fd = ion_open();
	igt_assert(ion_fd >= 0);

	mmap_with_fds(drm_fd, ion_fd, config);

	ion_close(ion_fd);
	close(drm_fd);
}

igt_main
{
	const struct fb_configuration config = {
		.width = 1024,
		.height = 1024,
		.pixel_format = DRM_FORMAT_ABGR8888,
		.pixel_size = 4
	};

	igt_subtest("make-fb")
	{
		test_make_fb(&config);
	}

	igt_subtest("clone")
	{
		test_clone(&config);
	}

	igt_subtest("mmap")
	{
		test_mmap(&config);
	}
}