我正在尝试使用计算着色器进行图像处理。作为Vulkan的新手,我有一些(可能是天真的)问题:
我试着看一个像素的邻域。所以AFAIK我有两种可能性:
a ,将一个图像传递给计算着色器并直接对邻域像素进行采样( x +/- i , y +/- j )
b ,将多个图像传递到计算着色器(每个都是偏移的)并仅采样当前位置( x , y )< / p>
示例性能 a vs b 是否存在差异(除了b需要更多内存传递给GPU)?
我需要将像素信息(+元信息)从一个管道阶段传递到另一个管道阶段(并在命令完成后将其读回)。
a ,除了传递设置了存储位的图像之外,我能以其他方式执行此操作吗?
b ,当从主机回读信息时我可能需要使用帧缓冲?
答案 0 :(得分:0)
使用单个图像并在偏移处采样(可能使用textureGather?)会更有效,可能会有很多。每个纹理操作都有一个成本,这使用更少。更重要的是,GPU中的纹理缓存通常会在采样点周围加载一个小区域,因此对相邻像素进行采样可能会在缓存中出现。
更好的方法是将所有像素加载到共享内存中,然后从那里开始工作。然后,不是从线程(i,j)和所有该线程的八个邻居中获取像素(i,j),而是仅获取它一次。您仍需要在由单个工作组处理的区域边缘上进行额外提取。 (对于它的价值,这种技术不是特定于Vulkan的:你也会在CUDA,OpenCL,D3D Compute和GL Compute中看到它。)
将数据保留在计算着色器之外的唯一方法是将其写入存储缓冲区或存储器映像。要在CPU上读取它,请将vkCmdCopyImageToBuffer或vkCmdCopyBuffer用于主机可读资源,然后映射它。