HLSL Shader компилируется, но вылетает при создании состояния конвейерного вычисления - PullRequest
2 голосов
/ 24 марта 2020

У меня есть вычислительный шейдер D3D12 (Shader Model 6.0), который успешно компилируется. Когда я компилирую его с отключенной оптимизацией (/ Od), он работает нормально, выходные данные верны.

Когда я включил оптимизацию, она также компилируется, но вылетает, когда я создаю состояние конвейера вычисления. Я получаю следующий вывод, когда я вызываю CreateComputePipelineState

Exception thrown at 0x00007FFE1A2FC800 (nvwgf2umx.dll) in D3DCompute.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

Слой отладки также ни на что не жаловался. Другие шейдеры, которые я написал, работают нормально, и я проверил этот проблемный шейдер c, я уверен, что нет предельного поведения. Почему это происходит?

Редактировать: минимальный шейдер для воспроизведения этой проблемы

#define MACRO_MAX(a, b) (((b) > (a)) ? (b) : (a))

#define BINS_TRACKED_PER_THREAD 2
#define BLOCK_THREADS       64
#define RADIX_BITS          7
#define RADIX_DIGITS        128
#define LOG_PACKTING_RATIO  1
#define LOG_COUNTER_LANES   6
#define COUNTER_LANES       64
#define MASK                ((1 << 16) - 1)

groupshared uint TempStorage[8192];

[numthreads(BLOCK_THREADS, 1, 1)]
void main(uint blockIdx : SV_GroupID, uint threadIdx : SV_GroupThreadID)
{
    uint exDigitPrefix[BINS_TRACKED_PER_THREAD];

    {
        [unroll(BINS_TRACKED_PER_THREAD)]
        for (uint track = 0; track < BINS_TRACKED_PER_THREAD; ++track) {
            uint binIdx = (threadIdx * BINS_TRACKED_PER_THREAD) + track;

            if ((BLOCK_THREADS == RADIX_DIGITS) || (binIdx < RADIX_DIGITS)) {

                uint counterLane = binIdx & (COUNTER_LANES - 1);
                uint subCounter = binIdx >> (LOG_COUNTER_LANES);

                exDigitPrefix[track] = (TempStorage[counterLane * BLOCK_THREADS] >> (16 * subCounter)) & MASK;
            }
        }
    }
    GroupMemoryBarrierWithGroupSync();

    {
        [unroll(BINS_TRACKED_PER_THREAD)]
        for (uint track = 0; track < BINS_TRACKED_PER_THREAD; ++track) {
            uint binIdx = (threadIdx * BINS_TRACKED_PER_THREAD) + track;
            if ((BLOCK_THREADS == RADIX_DIGITS) || (binIdx < RADIX_DIGITS))
                TempStorage[binIdx] = exDigitPrefix[track];
        }
    }
    GroupMemoryBarrierWithGroupSync();
}
...