Операции над шейдерной программой замораживают контекст GL при использовании достаточно большого SSBO
Я делаю параллельное сокращение в вычислительном шейдере. Я рекурсивно вычисляю ограничивающий блок фрагментов (начиная с G-буфера, полученного в результате рендеринга сцены), а затем ограничивающий блок фрагментов ограничивающих блоков и так далее, пока не получу один ограничивающий блок.
Первоначально я делал это с текстурой глубины и одного vec2
удерживая минимальную и максимальную глубины, я сохранял иерархию в SSBO следующим образом:
// Each tile holds the min and max depth of the subtiles in the level under it.
// Each tile holds 32 items and is 8*4 or 4*8 depending on the level. Conceptually,
// the texDepth texture is level 4.
layout(std430, binding = 5) buffer aabbHierarchy
{
vec2 level0[8 * 4], // one 8*4 tile
level1[32 * 32], // 8*4 4*8 tiles
level2[256 * 128], // 32*32 8*4 tiles
level3[1024 * 1024]; // 256*128 4*8 tiles
};
В конце концов я столкнулся с проблемами и решил перейти на полные AABB. Структура и SSBO изменились так:
struct AABB
{
vec4 low, high;
};
layout(std430, binding = 5) buffer aabbHierarchy
{
AABB level0[8 * 4],
level1[32 * 32],
level2[256 * 128],
level3[1024 * 1024];
};
Конечно, я изменил все, что связано с выполнением фактического расчета соответственно.
Но теперь, как выясняется, контекст GL зависает, когда я выполняю любой вызов после glUseProgram
на этой программе. glUseProgram
вызов сам по себе не имеет никаких проблем, но любой вызов GL, который я делаю после зависания моего приложения. Это, очевидно, не произошло при первоначальном использовании vec2
,
Я сделал математику, и мой SSBO составляет 34 636 800 байт (с AABB
), что намного меньше, чем ограничение размера блока SSBO в 128 МБ. Ни в одной точке моего заявления нет glCheckError
возвращает все, кроме 0, и все мои компиляции шейдеров, распределение буферов и создание текстур работают (по крайней мере, они не возвращают ошибку). В качестве дополнительного бонуса, выделение такого же размера SSBO, как с AABB
но используя его как vec2
в шейдере приложение не замораживается.
Я использую контекст OpenGL 4.4 с #version 430
в вычислительном шейдере, без расширения. Это работает на ASUS RoG fx553vd с Nvidia GeForce GTX 1050.
РЕДАКТИРОВАТЬ: так как я не мог воспроизвести в MCVE, это должно быть что-то делать с кодом вокруг него. Тем не менее, полное отсутствие сообщений об ошибках действительно странно. Мне удалось найти ту самую строку, которая спровоцировала ошибку, и воспроизвести тот факт, что в этом контексте любой вызов GL (даже такой простой, как glGetIntegerv
) заморозит приложение.
Это довольно большой проект, извините за это. Проблемная линия есть, а корень проекта есть. Обратите внимание, что это aabbHierarchy
филиал, а не мастер. Я добавил расширенную трассировку, чтобы было ясно, где и когда происходит сбой программы.
РЕДАКТИРОВАТЬ 2: Я добавил контекст отладки OpenGL, и все, что он сделал для меня, это распечатал пару строк "подробной информации о буфере", которые не помогли.
1 ответ
Оказывается, это проблема с драйверами. Я смог предоставить минимальный рабочий пример, который зависает на моем Nvidia, но отлично работает на моем интегрированном графическом процессоре Intel.
Для дальнейшего использования, начиная с 06.02.2009, драйвер Nvidia уже давно использует вычислительные шейдеры, которые объявляют массивы структур в буферных интерфейсных блоках. Это прекрасно работает:
layout(std430, binding = 0) buffer bleh
{
vec2 array[100000];
};
но это займет 5 фактических секунд, чтобы закончить выполнение glUseProgram
:
struct AABB
{
vec2 a;
};
layout(std430, binding = 0) buffer bleh
{
AABB array[100000];
};
Мой выглядит как замораживание, потому что я выделяю более 30 МБ буферного хранилища с шейдерной структурой через структуру, что совершенно нормально, но увидеть, как драйверу Nvidia требуется 5 секунд для обработки 100 КБ, я могу только Интересно, сколько времени это займет.
На моем Intel GPU glUseProgram
вызов для обоих выполняется мгновенно. Я сообщу об этом Nvidia как можно скорее.