我有一个包含2D图像的OpenCL缓冲区。
此图像的宽度大于其宽度。
我需要从这个缓冲区制作OpenCL图像。
问题是函数clEnqueueCopyImageToBuffer
不包含stride作为输入参数。
是否可以从OpenCL缓冲区(步幅大于宽度)制作OpenCL图像,只需复制一次或更快?
解决这个问题的一种方法是编写自己的内核,但也许还有更多简洁的解决方案?
答案 0 :(得分:6)
不幸的是,OpenCL规范中没有一种方法允许您在缓冲区数据的步幅不等于图像宽度时直接从缓冲区创建图像。最有效的解决方案可能是编写自己的内核来执行此操作。
最简单的解决方案不是编写自己的内核,而是使用clEnqueueCopyBufferToImage
一次复制一行。如果你的图像足够大,那么这种技术的性能可能与手写内核相当,但是你必须尝试看看。
我没有在我的原始答案中包含clEnqueueCopyBufferRect
方法,因为我的第一直觉是额外的副本会扼杀性能。然而,上面的评论让我进一步思考它,我有兴趣实现所有三种方法,看看性能实际上是什么样的。
我怀疑,最快的方法是实现内核直接执行此操作。但是,逐行复制数据的速度明显慢于我的预期。将缓冲区复制到具有clEnqueueCopyBufferRect
的中间缓冲区实际上是对性能和简单性的很好的折衷,尽管仍然比内核实现慢几倍。
可以找到此小实验的源代码here。我正在以1024的步幅复制1020x1020图像,并且时间平均超过8次。