我有一个渲染步骤,我想在动态生成的纹理上执行。
该算法可以并行独立地对行进行操作。对于每一行,该算法将以从左到右的顺序访问每个像素并就地修改它(如果有帮助,则不需要不同的输出缓冲区)。每次传递都使用状态变量,这些变量必须在每行的开头重置并在我们遍历列时持续存在。
我可以设置 OpenGL 着色器、OpenCL 或其他什么来执行此操作吗?请提供带有代码的最小示例。
我有一个渲染步骤,我想在动态生成的纹理上执行。
该算法可以并行独立地对行进行操作。对于每一行,该算法将以从左到右的顺序访问每个像素并就地修改它(如果有帮助,则不需要不同的输出缓冲区)。每次传递都使用状态变量,这些变量必须在每行的开头重置并在我们遍历列时持续存在。
我可以设置 OpenGL 着色器、OpenCL 或其他什么来执行此操作吗?请提供带有代码的最小示例。
如果您可以访问实现 EXT_shader_image_load_store 或 ARB_shader_image_load_store 的 GL 4.x 类硬件,我想您可以完成它。否则,图像的原位读/写通常是不可能的(尽管有 NV_texture_barrier 的方法)。
话虽如此,一旦您开始希望像素以您的方式共享状态,您就会扼杀大部分从并行性中获得的潜在收益。如果您为像素计算的值取决于其左侧像素的计算,那么您实际上无法并行执行每个像素。这意味着您的算法实际上具有的唯一并行性是每行。
那不会给你买太多东西。
如果您真的想这样做,请使用 OpenCL。对这种事情友好得多。
是的,你可以做到。不,您不需要 4.X 硬件,您需要片段着色器(带有流控制)、帧缓冲区对象和浮点纹理支持。
您需要将数据编码为 2D 纹理。
将“状态变量”存储在每行的第一个像素中,并将其余数据编码到其余像素中。不言而喻,推荐使用浮点纹理格式。
使用两个帧缓冲区,并使用在第一列更新“状态变量”的片段着色器在循环中将它们渲染到彼此,并在另一列(即“当前”)上执行您需要的任何操作。为了减少浪费的资源量,您可以将渲染限制为要处理的列。NVidia OpenGL SDK 示例有“生命游戏”、“GDGPU 流体”、“GPU 粒子”演示,它们以类似的方式工作——将数据编码到纹理中,然后使用着色器对其进行更新。
但是,因为您可以做到,并不意味着您应该这样做,也不意味着它可以保证很快。一些 GPU 可能具有非常高的内存纹理内存读取速度,但计算速度相对较慢(反之亦然),并且并非所有 GPU 都有许多用于并行处理事物的传送带。
此外,根据您的应用程序,CUDA 或 OpenCL 可能更合适。