我正在编写自己的图形库(是的,它的作业:)并使用 cuda 快速进行所有渲染和计算。
我在绘制填充三角形时遇到问题。我是这样写的,一个进程画一个三角形。当场景中有很多小三角形时它工作得很好,但是当三角形很大时它完全破坏了性能。
我的想法是做两次传球。首先计算仅包含有关扫描线信息的选项卡(从这里到那里绘制)。这将是每个进程计算的三角形,就像在当前算法中一样。在第二遍中,真正绘制每个三角形多个进程的扫描线。
但它会足够快吗?也许有更好的解决方案?
我正在编写自己的图形库(是的,它的作业:)并使用 cuda 快速进行所有渲染和计算。
我在绘制填充三角形时遇到问题。我是这样写的,一个进程画一个三角形。当场景中有很多小三角形时它工作得很好,但是当三角形很大时它完全破坏了性能。
我的想法是做两次传球。首先计算仅包含有关扫描线信息的选项卡(从这里到那里绘制)。这将是每个进程计算的三角形,就像在当前算法中一样。在第二遍中,真正绘制每个三角形多个进程的扫描线。
但它会足够快吗?也许有更好的解决方案?
您可以查看此博客:A Software Rendering Pipeline in CUDA。我认为这不是最好的方法,但至少作者分享了一些有用的资源。
其次,阅读这篇论文:A Programmable, Parallel Rendering Architecture。我认为这是最新的论文之一,它也是基于 CUDA 的。
如果我必须这样做,我会使用像 Larrabee(即 TBR)甚至 REYES 中的数据并行光栅化管道,并将其适应 CUDA:
http://www.ddj.com/architect/217200602 http://home.comcast.net/~tom_forsyth/larrabee/Standford%20Forsyth%20Larrabee%202010.zip (参见演示文稿的第二部分)
我怀疑您对 CUDA 以及如何使用它有一些误解,尤其是当您提到“过程”时,在 CUDA 术语中没有这样的东西。
对于大多数 CUDA 应用程序,要获得良好的性能有两个重要的事情:优化内存访问并确保 warp 中的每个“活动”CUDA 线程与 warp 中的其他活动线程同时执行相同的操作。这两个听起来对您的应用程序都很重要。
为了优化您的内存访问,您需要确保从全局内存读取和对全局内存的写入是合并的。您可以在 CUDA 编程指南中阅读更多相关信息,但这实质上意味着,半扭曲中的相邻线程必须从相邻的内存位置读取或写入。此外,每个线程应一次读取或写入 4、8 或 16 个字节。
如果您的内存访问模式是随机的,那么您可能需要考虑使用纹理内存。当您需要在一个块中引用已被其他线程读取的内存时,您应该使用共享内存。
在你的情况下,我不确定你的输入数据是什么,但你至少应该确保你的写入是合并的。您可能需要投入一些不小的努力才能让您的阅读有效地工作。
对于第二部分,我建议每个 CUDA 线程处理输出图像中的一个像素。使用这种策略,您应该注意内核中的循环,这些循环将根据每个线程的数据执行更长或更短。经线中的每个线程都应该以相同的顺序执行相同数量的步骤。唯一的例外是,让warp中的一些线程不执行任何操作而其余线程一起执行相同的操作,并没有真正的性能损失。
因此,我建议让每个线程检查它的像素是否在给定的三角形内。如果没有,它应该什么都不做。如果是,它应该计算该像素的输出颜色。
另外,我强烈建议您阅读有关 CUDA 的更多信息,因为您似乎在没有很好地理解一些基本原理的情况下跳入深渊。
不要粗鲁,但这不就是显卡的设计初衷吗?似乎使用标准的 OpenGL 和 Direct3D API 会更有意义。
为什么不使用 API 来进行基本渲染,而不是使用低得多的 CUDA?然后,如果您希望执行不支持的其他操作,您可以使用 CUDA 将它们应用到顶部。或者也许将它们实现为着色器。