我正在使用OpenCL进行一些图像处理,并希望用它将RGBA图像直接写入帧缓冲区。工作流程如下所示:
1)将帧缓冲区映射到用户空间。
2)使用clCreateBuffer创建OpenCL缓冲区,标志为" CL_MEM_ALLOC_HOST_PTR"
3)使用clEnqueueMapBuffer将结果映射到帧缓冲区。
但是,它不起作用。屏幕上什么都没有。然后我发现framebuffer中映射的虚拟地址与映射OpenCL的虚拟地址不同。有没有机构完成从GPU到帧缓冲区的零拷贝数据移动?我应该使用什么方法来帮助它?
一些关键代码:
if ((fd_fb = open("/dev/fb0", O_RDWR, 0)) < 0) {
printf("Unable to open /dev/fb0\n");
return -1;
}
fb0 = (unsigned char *)mmap(0, fb0_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
...
cmDevSrc4 = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, sizeof(cl_uchar) * imagesize * 4, NULL, &status);
...
fb0 = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue, cmDevSrc4, CL_TRUE, CL_MAP_READ, 0, sizeof(cl_uchar) * imagesize * 4, 0, NULL, NULL, &ciErr);
答案 0 :(得分:1)
对于使用现有缓冲区的零拷贝,您需要在CL_MEM_USE_HOST_PTR
函数调用中使用clCreateBuffer()
标志。此外,您需要将指向现有缓冲区的指针作为倒数第二个参数。
我不知道linux framebuffer内部是如何工作的,但即使使用从设备到主机的零拷贝,它也可能导致额外的数据复制到GPU进行渲染。因此,您可能希望直接使用OpenGL渲染OpenCL缓冲区。查看OpenCL的cl_khr_gl_sharing
扩展名。
答案 1 :(得分:0)
我还不了解OpenCL,我只是在做一个搜索,以了解有关从中写入帧缓冲区并点击您的帖子的信息。像在代码中那样打开并映射它看起来不错。
我已经使用CPU完成此操作:https://sourceforge.net/projects/fbgrad/
这并不总是有效,这取决于计算机。我使用的是旧版Dell Latitude D530,不仅无法写入帧缓冲区,而且没有GPU,因此与使用CPU相比,使用OpenCL没有优势。如果您有/ dev / fb0,并且可以使用
在屏幕上显示一些内容cat /dev/random > /dev/fb0
那么您可能有机会使用OpenCL。至少对于Mali,有一种方法可以将指针从CPU传递到GPU。您可能需要添加一些偏移量(我认为在Raspberry Pi上为true)。而且Xorg可能会对它进行双重缓冲,有很多原因使其可能无法正常工作。