Я работаю над графическим движком OpenGL, который может точно отображать прозрачные сетки. Полный проект доступен здесь; это решение Visual Studio 2017 (вам может потребоваться установить Windows 10 SDK), но оно также включает make-файл для сборки под Linux. Он использует связанные списки фрагментов на графическом процессоре, которые затем сортируются и смешиваются друг с другом.
В частности, это делается с помощью двух буферов и атомарного счетчика: первый буфер содержит для каждого пикселя указатель на заголовок своего списка и атомарно обновляется при рендеринге мешей; второй буфер содержит фактические узлы (узел - это цвет фрагмента и указатель на следующий узел), а атомарный счетчик используется для резервирования уникальной позиции во втором буфере.
Проблема в том, что на моем ноутбуке с дискретной графикой AMD все работает нормально, но вылетает на другом моем ПК nVidia (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);
}
Если я удалю внутреннее, если программа больше не выйдет из строя, но, конечно, результат будет неверным, так как списки не отсортированы. Я начинаю думать, что есть проблема с моей конкретной моделью графической карты , потому что сбой как с двоичным драйвером, так и со стеком с открытым исходным кодом на одной и той же карте, похоже, предполагает это. Но, возможно, в шейдере действительно есть ошибка, которую я не смог найти.
Любая идея? Вот результат, который я хочу:
1 ответ
Переключение с пузырьковой сортировки на сортировку по выбору решило проблему. Однако не знаю, почему это вызывало сбой графического процессора.
Похожие вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.
FragmentNode temp
двумя варами с плавающей запятой.