android13/hardware/rockchip/libmpimmz/demo/mpimmz_rga_demo.cpp

178 lines
5.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <inttypes.h>
#include <sys/mman.h>
#include "im2d_api/im2d.h"
#include "rk_mpi_mmz.h"
static const int width = 1920;
static const int height = 1088;
static int do_sync = 0;
static struct timespec tik, tok;
static inline int time_diff_us(struct timespec* begin, struct timespec* end)
{
return (end->tv_sec - begin->tv_sec) * 1000000 + (end->tv_nsec - begin->tv_nsec) / 1000;
}
// 数据相同返回0否则返回1
int check_data(const void* dst, const void* src, int len)
{
int ret = 0;
uint8_t* ch_src = (uint8_t*)src;
uint8_t* ch_dst = (uint8_t*)dst;
for(int i=0; i<len; i++) {
if (ch_dst[i] != ch_src[i]) {
printf("unmatch in %d src[0x%x] dst[0x%x]\n", i, ch_src[i], ch_dst[i]);
ret = 1;
break;
}
}
return ret;
}
int rga_copy(MB_BLK mb_dst, MB_BLK mb_src, int len)
{
rga_buffer_t src, dst;
memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));
src = wrapbuffer_physicaladdr((void *)RK_MPI_MMZ_Handle2PhysAddr(mb_src), width, height, 0x15);
dst = wrapbuffer_physicaladdr((void *)RK_MPI_MMZ_Handle2PhysAddr(mb_dst), width, height, 0x15);
// 使用rga把src地址的数据拷贝到dst地址
clock_gettime(CLOCK_MONOTONIC, &tik);
imcopy(src, dst);
clock_gettime(CLOCK_MONOTONIC, &tok);
// 检查数据拷贝是否成功
void* vaddr_src = RK_MPI_MMZ_Handle2VirAddr(mb_src);
void* vaddr_dst = RK_MPI_MMZ_Handle2VirAddr(mb_dst);
if (do_sync) RK_MPI_MMZ_FlushCacheStart(mb_dst, 0, 0, RK_MMZ_SYNC_READONLY);
int ret = check_data(vaddr_dst, vaddr_src, len);
if (do_sync) RK_MPI_MMZ_FlushCacheEnd(mb_dst, 0, 0, RK_MMZ_SYNC_READONLY);
return ret;
}
int cpu_copy(MB_BLK mb_dst, MB_BLK mb_src, int len)
{
void* vaddr_src = RK_MPI_MMZ_Handle2VirAddr(mb_src);
void* vaddr_dst = RK_MPI_MMZ_Handle2VirAddr(mb_dst);
clock_gettime(CLOCK_MONOTONIC, &tik);
memcpy(vaddr_dst, vaddr_src, len);
clock_gettime(CLOCK_MONOTONIC, &tok);
// 检查数据拷贝是否成功
return check_data(vaddr_dst, vaddr_src, len);
}
int main(int argc, const char** argv)
{
int len = 3133440;//width*height*3/2;//
int flags = RK_MMZ_ALLOC_TYPE_IOMMU | RK_MMZ_ALLOC_CACHEABLE;
int test_rga = 0;
// 绑定到CPU2
cpu_set_t sCPUSet;
CPU_ZERO(&sCPUSet);
CPU_SET(2, &sCPUSet);
sched_setaffinity(0, sizeof(sCPUSet), &sCPUSet);
// 定到最高频
system("echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor");
system("echo performance > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor");
do_sync = 0;
printf("Usage: %s [--cma] [--uncache] [--rga] [--sync]\n\n", argv[0]);
// 参数解析
for (int i=1; i<argc; i++)
{
if (!strcmp(argv[i], "--cma"))
flags |= RK_MMZ_ALLOC_TYPE_CMA;
else if (!strcmp(argv[i], "--uncache"))
flags |= RK_MMZ_ALLOC_UNCACHEABLE;
else if (!strcmp(argv[i], "--rga"))
test_rga = 1;
else if (!strcmp(argv[i], "--sync"))
do_sync = 1;
}
printf("Memory: %s %s Cache, use %s copy, %s sync\n\n",
(flags&RK_MMZ_ALLOC_TYPE_CMA)?"CMA":"Non-CMA",
(flags&RK_MMZ_ALLOC_UNCACHEABLE)?"without":"with",
test_rga?"RGA":"CPU",
do_sync?"do":"not");
if (!(flags&RK_MMZ_ALLOC_TYPE_CMA) && test_rga) {
printf("unsupport rga copy for Non-CMA memory!\n");
return -1;
}
for (int i=0; i<10; i++)
{
MB_BLK mb_src, mb_dst;
void* vaddr_src;
void* vaddr_dst;
int ret;
// 分配内存
ret = RK_MPI_MMZ_Alloc(&mb_src, len, flags);
if (ret < 0) {
printf("alloc src fail\n");
return ret;
}
ret = RK_MPI_MMZ_Alloc(&mb_dst, len, flags);
if (ret < 0) {
printf("alloc dst fail\n");
return ret;
}
// 填充数据
vaddr_src = RK_MPI_MMZ_Handle2VirAddr(mb_src);
if (do_sync) RK_MPI_MMZ_FlushCacheStart(mb_src, 0, 0, RK_MMZ_SYNC_WRITEONLY);
memset(vaddr_src, 0x5A, len);
if (do_sync) RK_MPI_MMZ_FlushCacheEnd(mb_src, 0, 0, RK_MMZ_SYNC_WRITEONLY);
vaddr_dst = RK_MPI_MMZ_Handle2VirAddr(mb_dst);
if (do_sync) RK_MPI_MMZ_FlushCacheStart(mb_dst, 0, 0, RK_MMZ_SYNC_WRITEONLY);
memset(vaddr_dst, 0, len);
if (do_sync) RK_MPI_MMZ_FlushCacheEnd(mb_dst, 0, 0, RK_MMZ_SYNC_WRITEONLY);
// 复制数据
if (test_rga == 1) {
if (rga_copy(mb_dst, mb_src, len) == 0) {
printf("%d: RGA copy okay, size: %d, use time: %d us\n", i, len, time_diff_us(&tik, &tok));
} else {
printf("%d: RGA copy fail.\n", i);
}
} else {
if (cpu_copy(mb_dst, mb_src, len) == 0) {
printf("%d: CPU copy okay, size: %d, use time: %d us\n", i, len, time_diff_us(&tik, &tok));
} else {
printf("%d: CPU copy fail.\n", i);
}
}
// 释放内存
RK_MPI_MMZ_Free(mb_src);
RK_MPI_MMZ_Free(mb_dst);
sleep(1);
}
return 0;
}