Bin*_*inn 5 framebuffer opencl memory-mapping zero-copy
我正在使用 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);
Run Code Online (Sandbox Code Playgroud)
对于现有缓冲区的零复制,您需要CL_MEM_USE_HOST_PTR在函数调用中使用标志clCreateBuffer()。此外,您需要将指向现有缓冲区的指针作为倒数第二个参数。
我不知道 Linux 帧缓冲区内部是如何工作的,但即使是从设备到主机的零复制,也有可能导致额外将数据复制到 GPU 进行渲染。因此您可能想直接使用 OpenGL 渲染 OpenCL 缓冲区。查看cl_khr_gl_sharingOpenCL 的扩展。