5

我正在使用 OpenCL 进行一些图像处理,并希望使用它将 RGBA 图像直接写入帧缓冲区。工作流程如下图所示:

1) 将帧缓冲区映射到用户空间。

2) 使用带有“CL_MEM_ALLOC_HOST_PTR”标志的 clCreateBuffer 创建 OpenCL 缓冲区

3) 使用 clEnqueueMapBuffer 将结果映射到帧缓冲区。

但是,它不起作用。屏幕上什么都没有。然后我发现来自帧缓冲区的映射虚拟地址与映射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);
4

2 回答 2

1

对于现有缓冲区的零复制,您需要在函数调用中使用CL_MEM_USE_HOST_PTR标志。clCreateBuffer()此外,您需要将指向现有缓冲区的指针作为倒数第二个参数。

我不知道 linux 帧缓冲区在内部是如何工作的,但即使从设备到主机的零复制也有可能导致将数据额外复制到 GPU 进行渲染。因此,您可能希望直接使用 OpenGL 渲染 OpenCL 缓冲区。查看cl_khr_gl_sharingOpenCL 的扩展。

于 2017-04-25T18:24:06.517 回答
0

我还不知道 OpenCL,我只是在搜索以了解如何从中写入帧缓冲区并点击您的帖子。打开它并像在代码中那样映射它看起来不错。

我已经用 CPU 做到了:https ://sourceforge.net/projects/fbgrad/

这并不总是有效,这取决于计算机。我在旧的戴尔 Latitude D530 上,不仅不能写入帧缓冲区,而且没有 GPU,因此使用 OpenCL 比使用 CPU 没有优势。如果你有一个 /dev/fb0 并且你可以在屏幕上得到一些东西

cat /dev/random > /dev/fb0

那么您可能会从 OpenCL 获得机会。使用 Mali 至少有一种方法可以将指针从 CPU 传递到 GPU。您可能需要添加一些偏移量(我认为在 Raspberry Pi 上是这样)。它可能会被 Xorg 双重缓冲,它可能不起作用的原因有很多。

于 2019-11-08T14:24:24.093 回答