/* * Unit test: DMA-BUF heap allocation + DRM import * Tests whether dma_heap buffers can be imported into DRM (GEM handle). */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include static int dma_heap_alloc(const char *heap_name, size_t size, int *fd) { char path[64]; snprintf(path, sizeof(path), "/dev/dma_heap/%s", heap_name); int heap_fd = open(path, O_RDWR | O_CLOEXEC); if (heap_fd < 0) { fprintf(stderr, " open(%s) failed: %s\n", path, strerror(errno)); return -1; } struct dma_heap_allocation_data data = { .len = size, .fd_flags = O_RDWR | O_CLOEXEC, }; int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &data); close(heap_fd); if (ret < 0) { fprintf(stderr, " DMA_HEAP_IOCTL_ALLOC(%s) failed: %s\n", heap_name, strerror(errno)); return -1; } *fd = data.fd; return 0; } static void test_heap(const char *heap_name) { printf("=== Testing heap: %s ===\n", heap_name); int fd = -1; if (dma_heap_alloc(heap_name, 1920 * 1080 * 3 / 2, &fd) < 0) { printf(" FAIL: cannot allocate from %s\n\n", heap_name); return; } printf(" OK: allocated buffer fd=%d size=%zu\n", 1920 * 1080 * 3 / 2, 1920 * 1080 * 3 / 2); /* Test mmap */ size_t sz = 1920 * 1080 * 3 / 2; void *map = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { printf(" FAIL: mmap failed: %s\n\n", strerror(errno)); close(fd); return; } printf(" OK: mmap at %p\n", map); /* Write something */ memset(map, 0x80, sz); printf(" OK: memset succeeded\n"); munmap(map, sz); /* Test DRM import */ int drm_fd = open("/dev/dri/card0", O_RDWR); if (drm_fd < 0) { printf(" WARN: cannot open /dev/dri/card0: %s\n", strerror(errno)); close(fd); return; } uint32_t handle = 0; int ret = drmPrimeFDToHandle(drm_fd, fd, &handle); if (ret) { printf(" FAIL: drmPrimeFDToHandle(fd=%d) failed: %d (%s)\n", fd, ret, strerror(-ret)); } else { printf(" OK: drmPrimeFDToHandle => GEM handle=%u\n", handle); } /* Try second import (should reuse handle) */ uint32_t handle2 = 0; ret = drmPrimeFDToHandle(drm_fd, fd, &handle2); if (ret) { printf(" FAIL: second drmPrimeFDToHandle failed: %d\n", ret); } else { printf(" OK: second import => handle=%u (same=%d)\n", handle2, handle2 == handle); } close(drm_fd); close(fd); printf("\n"); } int main(void) { printf("=== DMA-BUF Heap Unit Test ===\n\n"); /* List available heaps */ printf("Available heaps (from /proc):\n"); system("ls -la /dev/dma_heap/ 2>/dev/null || echo ' (no /dev/dma_heap/)'"); printf("\n"); test_heap("reserved"); test_heap("system-uncached"); test_heap("system"); test_heap("cma"); printf("=== Done ===\n"); return 0; }