test_dma_heap.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Unit test: DMA-BUF heap allocation + DRM import
  3. * Tests whether dma_heap buffers can be imported into DRM (GEM handle).
  4. */
  5. #define _GNU_SOURCE
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <errno.h>
  12. #include <sys/ioctl.h>
  13. #include <sys/mman.h>
  14. #include <linux/dma-heap.h>
  15. #include <xf86drm.h>
  16. #include <xf86drmMode.h>
  17. static int dma_heap_alloc(const char *heap_name, size_t size, int *fd) {
  18. char path[64];
  19. snprintf(path, sizeof(path), "/dev/dma_heap/%s", heap_name);
  20. int heap_fd = open(path, O_RDWR | O_CLOEXEC);
  21. if (heap_fd < 0) {
  22. fprintf(stderr, " open(%s) failed: %s\n", path, strerror(errno));
  23. return -1;
  24. }
  25. struct dma_heap_allocation_data data = {
  26. .len = size,
  27. .fd_flags = O_RDWR | O_CLOEXEC,
  28. };
  29. int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &data);
  30. close(heap_fd);
  31. if (ret < 0) {
  32. fprintf(stderr, " DMA_HEAP_IOCTL_ALLOC(%s) failed: %s\n", heap_name, strerror(errno));
  33. return -1;
  34. }
  35. *fd = data.fd;
  36. return 0;
  37. }
  38. static void test_heap(const char *heap_name) {
  39. printf("=== Testing heap: %s ===\n", heap_name);
  40. int fd = -1;
  41. if (dma_heap_alloc(heap_name, 1920 * 1080 * 3 / 2, &fd) < 0) {
  42. printf(" FAIL: cannot allocate from %s\n\n", heap_name);
  43. return;
  44. }
  45. printf(" OK: allocated buffer fd=%d size=%zu\n", 1920 * 1080 * 3 / 2, 1920 * 1080 * 3 / 2);
  46. /* Test mmap */
  47. size_t sz = 1920 * 1080 * 3 / 2;
  48. void *map = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  49. if (map == MAP_FAILED) {
  50. printf(" FAIL: mmap failed: %s\n\n", strerror(errno));
  51. close(fd);
  52. return;
  53. }
  54. printf(" OK: mmap at %p\n", map);
  55. /* Write something */
  56. memset(map, 0x80, sz);
  57. printf(" OK: memset succeeded\n");
  58. munmap(map, sz);
  59. /* Test DRM import */
  60. int drm_fd = open("/dev/dri/card0", O_RDWR);
  61. if (drm_fd < 0) {
  62. printf(" WARN: cannot open /dev/dri/card0: %s\n", strerror(errno));
  63. close(fd);
  64. return;
  65. }
  66. uint32_t handle = 0;
  67. int ret = drmPrimeFDToHandle(drm_fd, fd, &handle);
  68. if (ret) {
  69. printf(" FAIL: drmPrimeFDToHandle(fd=%d) failed: %d (%s)\n",
  70. fd, ret, strerror(-ret));
  71. } else {
  72. printf(" OK: drmPrimeFDToHandle => GEM handle=%u\n", handle);
  73. }
  74. /* Try second import (should reuse handle) */
  75. uint32_t handle2 = 0;
  76. ret = drmPrimeFDToHandle(drm_fd, fd, &handle2);
  77. if (ret) {
  78. printf(" FAIL: second drmPrimeFDToHandle failed: %d\n", ret);
  79. } else {
  80. printf(" OK: second import => handle=%u (same=%d)\n", handle2, handle2 == handle);
  81. }
  82. close(drm_fd);
  83. close(fd);
  84. printf("\n");
  85. }
  86. int main(void) {
  87. printf("=== DMA-BUF Heap Unit Test ===\n\n");
  88. /* List available heaps */
  89. printf("Available heaps (from /proc):\n");
  90. system("ls -la /dev/dma_heap/ 2>/dev/null || echo ' (no /dev/dma_heap/)'");
  91. printf("\n");
  92. test_heap("reserved");
  93. test_heap("system-uncached");
  94. test_heap("system");
  95. test_heap("cma");
  96. printf("=== Done ===\n");
  97. return 0;
  98. }