test_rga.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Unit test: RGA composer - tests importbuffer_fd + wrapbuffer_handle_t
  3. * Since wrapbuffer_fd_t returns handle=0 on this platform,
  4. * we use importbuffer_fd to get a handle, then wrapbuffer_handle_t.
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <errno.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/mman.h>
  15. #include <linux/dma-heap.h>
  16. #include <rga/im2d.h>
  17. #include <rga/rga.h>
  18. static int dma_heap_alloc(const char *heap_name, size_t size, int *fd) {
  19. char path[64];
  20. snprintf(path, sizeof(path), "/dev/dma_heap/%s", heap_name);
  21. int heap_fd = open(path, O_RDWR | O_CLOEXEC);
  22. if (heap_fd < 0) return -1;
  23. struct dma_heap_allocation_data data = { .len = size, .fd_flags = O_RDWR | O_CLOEXEC };
  24. int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &data);
  25. close(heap_fd);
  26. if (ret < 0) return -1;
  27. *fd = data.fd;
  28. return 0;
  29. }
  30. static rga_buffer_t make_rga_from_fd(int fd, int w, int h, int format) {
  31. rga_buffer_t buf;
  32. memset(&buf, 0, sizeof(buf));
  33. /* Try wrapbuffer_fd_t first */
  34. buf = wrapbuffer_fd_t(fd, w, h, w, h, format);
  35. if (buf.handle != 0) return buf;
  36. /* Fallback: importbuffer_fd + wrapbuffer_handle_t */
  37. im_handle_param_t param;
  38. memset(&param, 0, sizeof(param));
  39. param.width = w;
  40. param.height = h;
  41. param.format = format;
  42. rga_buffer_handle_t handle = importbuffer_fd(fd, &param);
  43. if (handle == 0) {
  44. fprintf(stderr, " importbuffer_fd failed for fd=%d\n", fd);
  45. return buf;
  46. }
  47. buf = wrapbuffer_handle_t(handle, w, h, w, h, format);
  48. fprintf(stderr, " imported fd=%d => handle=%u (via importbuffer_fd)\n", fd, handle);
  49. return buf;
  50. }
  51. static void test_blit(const char *heap_name, int src_w, int src_h, int dst_w, int dst_h) {
  52. printf("=== RGA blit: %s, src=%dx%d, dst=%dx%d ===\n",
  53. heap_name, src_w, src_h, dst_w, dst_h);
  54. size_t src_sz = src_w * src_h * 3 / 2;
  55. size_t dst_sz = dst_w * dst_h * 3 / 2;
  56. int src_fd = -1, dst_fd = -1;
  57. if (dma_heap_alloc(heap_name, src_sz, &src_fd) < 0) {
  58. printf(" FAIL: src alloc\n\n"); return;
  59. }
  60. if (dma_heap_alloc(heap_name, dst_sz, &dst_fd) < 0) {
  61. printf(" FAIL: dst alloc\n"); close(src_fd); return;
  62. }
  63. void *src_map = mmap(NULL, src_sz, PROT_READ | PROT_WRITE, MAP_SHARED, src_fd, 0);
  64. void *dst_map = mmap(NULL, dst_sz, PROT_READ | PROT_WRITE, MAP_SHARED, dst_fd, 0);
  65. if (src_map == MAP_FAILED || dst_map == MAP_FAILED) {
  66. printf(" FAIL: mmap\n");
  67. close(src_fd); close(dst_fd); return;
  68. }
  69. /* Fill src with yellow (Y=0xFF, UV=0x40) */
  70. memset(src_map, 0xFF, src_w * src_h);
  71. memset((uint8_t*)src_map + src_w * src_h, 0x40, src_w * src_h / 2);
  72. memset(dst_map, 0x00, dst_sz);
  73. rga_buffer_t src_buf = make_rga_from_fd(src_fd, src_w, src_h, RK_FORMAT_YCbCr_420_SP);
  74. rga_buffer_t dst_buf = make_rga_from_fd(dst_fd, dst_w, dst_h, RK_FORMAT_YCbCr_420_SP);
  75. printf(" src: handle=%u\n", src_buf.handle);
  76. printf(" dst: handle=%u\n", dst_buf.handle);
  77. if (src_buf.handle == 0 || dst_buf.handle == 0) {
  78. printf(" SKIP blit (handle=0)\n");
  79. goto cleanup;
  80. }
  81. im_rect src_rect = {0, 0, src_w, src_h};
  82. im_rect dst_rect = {0, 0, dst_w, dst_h};
  83. rga_buffer_t pat;
  84. memset(&pat, 0, sizeof(pat));
  85. im_rect prect;
  86. memset(&prect, 0, sizeof(prect));
  87. printf(" Running improcess...\n");
  88. int ret = improcess(src_buf, dst_buf, pat, src_rect, dst_rect, prect, IM_SYNC);
  89. printf(" improcess => %d (%s)\n", ret, ret == IM_STATUS_SUCCESS ? "OK" : "FAIL");
  90. if (ret == IM_STATUS_SUCCESS) {
  91. uint8_t *p = (uint8_t*)dst_map;
  92. int nonzero = 0;
  93. for (int i = 0; i < dst_w * dst_h && i < 1024; i++)
  94. if (p[i] != 0) nonzero++;
  95. printf(" dst Y first 1024 bytes: %d non-zero (expect ~1024 for 0xFF fill)\n", nonzero);
  96. }
  97. cleanup:
  98. munmap(src_map, src_sz);
  99. munmap(dst_map, dst_sz);
  100. close(src_fd);
  101. close(dst_fd);
  102. printf("\n");
  103. }
  104. int main(void) {
  105. printf("=== RGA Composer Unit Test v2 ===\n\n");
  106. test_blit("system-uncached", 1920, 1080, 1920, 1080);
  107. test_blit("system-uncached", 640, 360, 640, 360);
  108. test_blit("system-uncached", 1920, 1080, 640, 360); /* scale down */
  109. test_blit("cma", 1920, 1080, 1920, 1080);
  110. printf("=== Done ===\n");
  111. return 0;
  112. }