【发布时间】:2017-08-17 20:40:12
【问题描述】:
我正在开发一个 OpenGL 图形引擎,它可以准确地渲染透明网格。完整项目可用here;它是一个 Visual Studio 2017 解决方案(您可能需要安装 Windows 10 SDK),但还包括一个在 Linux 下构建的 makefile。它使用 GPU 上的片段链表,然后从后到前对这些片段进行排序和混合。
更具体地说,这是通过两个缓冲区和一个原子计数器完成的:第一个缓冲区为每个像素保存一个指向其列表头部的指针,并在渲染网格时自动更新;第二个缓冲区保存实际节点(节点是片段的颜色和指向下一个节点的指针),原子计数器用于在第二个缓冲区中保留唯一位置。
问题是,在我的带有独立 AMD 显卡的笔记本上一切正常,但在我的另一台 nVidia PC(GT 740,非常便宜)上崩溃。 它在 Windows 和 Linux 以及官方驱动程序和开源堆栈都崩溃。导致这种情况的代码在排序着色器中(请参阅 TODO 注释):
int listBegin = listsHeads[getPixelBufferIndex()];
if(listBegin != -1)
{
// Sort linked list using bubble sort
bool swapped;
do
{
// Start at list head
swapped = false;
int previousNode = listBegin;
int currentNode = listsNodes[listBegin].nextNode;
// Loop until list end
while(currentNode != -1)
{
// Furthest first
float previousDepth = listsNodes[previousNode].depth;
float currentDepth = listsNodes[currentNode].depth;
// TODO fix crash on nVidia
if(previousDepth < currentDepth)
{
swapped = true;
FragmentNode temp;
temp.color = listsNodes[currentNode].color;
temp.meshId = listsNodes[currentNode].meshId;
listsNodes[currentNode].color = listsNodes[previousNode].color;
listsNodes[currentNode].depth = previousDepth;
listsNodes[currentNode].meshId = listsNodes[previousNode].meshId;
listsNodes[previousNode].color = temp.color;
listsNodes[previousNode].depth = currentDepth;
listsNodes[previousNode].meshId = temp.meshId;
}
previousNode = currentNode;
currentNode = listsNodes[currentNode].nextNode;
}
}
while(swapped);
}
如果我在程序不再崩溃的情况下删除内部,但结果当然是不正确的,因为列表没有排序。 我开始认为我的特定显卡型号存在问题,因为在同一张卡上同时使用二进制驱动程序和开源堆栈崩溃似乎表明了这一点。但也许实际上着色器中有一个我找不到的错误。
有什么想法吗?这是我想要的输出:
【问题讨论】:
-
盲射:用两个浮点变量替换
FragmentNode temp。 -
不幸的是它不起作用。
标签: c++ opengl glsl nvidia glfw