Вычислить шейдер зависает при установке двух пикселей во время цикла RWTexture2D (DirectX11, SM5) - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь выполнить некоторые базовые клеточные автоматы на вычислительном шейдере (DirectCompute), но без двойной буферизации, поэтому я использую представление неупорядоченного доступа к RWTexture2D<uint> для данных, однако у меня действительно странное зависание/ аварии здесь, я мог бы сделать очень маленький фрагмент, который вызывает проблему:

int w = 256;
for (int x = 0; x < w; ++x)
{
    for (int y = 1; y < w; ++y)
    {
        if (map[int2(x, y - 1)])
        {
            map[int2(x, y)] = 10;
            map[int2(x, y-1)] = 30;
        }
    }
}

где map равно RWTexture2D<uint>.

Если я удаляю if или один изназначения, это работает, я думал, что это может быть какой-то предел, поэтому я попытался зациклить только 1/4 текстуры, но проблема сохраняется.Этот код отправляется с помощью (1,1,1), а numthreads в ядре тоже (1,1,1), в моем реальном сценарии я хочу выполнить цикл снизу вверх и заполнить пустоты (0)пиксель, который я сейчас зацикливаю (вспомним эффект типа «падающего песка»), поэтому он не может быть параллельным, кроме столбцов, поскольку он зависит от нижнего пикселя.

Я не понимаю, что такоевызывая зависание шейдера, нет ошибки или чего-то в этом роде, он просто зависает и никогда не прерывается.

РЕДАКТИРОВАТЬ: После некоторого дальнейшего исследования я наткнулся на что-то действительно интригующее;когда я передаю это значение w в постоянный буфер, все работает нормально.Я понятия не имею, что может вызвать это, может быть, какая-то оптимизация компиляции пошла не так, может быть, он пытается развернуть цикл, что вызывает некоторые проблемы, и передача значения в постоянный буфер отключает это, однако я собираю шейдеры в отладкебез оптимизации, поэтому я не знаю.

1 Ответ

0 голосов
/ 01 октября 2018

У меня были проблемы с объявлением переменных в глобальной области видимости, как это раньше.Я считаю, что это потому, что это не статический констант (поэтому объявить как статический констант, и он должен работать).Скорее всего, он обрабатывает его как постоянный буфер (с некоторыми именами по умолчанию), а его содержимое не определено, поскольку вы не привязываете буфер, что приводит к неопределенным результатам.Таким образом, следующий код должен работать:

static const int w = 256;
for (int x = 0; x < w; ++x)
{
    for (int y = 1; y < w; ++y)
    {
        if (map[int2(x, y - 1)])
        {
            map[int2(x, y)] = 10;
            map[int2(x, y-1)] = 30;
        }
    }
}
...