#include "drm.h" #include "gem.h" #include "igt.h" #include "ion.h" #include 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); } }