HLSL: использование массивов внутри структуры - PullRequest
3 голосов
/ 23 августа 2010

Я столкнулся со странным поведением HLSL. Я пытаюсь использовать массив, содержащийся в структуре, например, (код пиксельного шейдера):

struct VSOUT {
    float4 projected : SV_POSITION;
    float3 pos: POSITION;
    float3 normal : NORMAL;
};


struct Something  {
    float a[17];
};


float4 shMain (VSOUT input) : SV_Target {
    Something s;

    for (int i = 0; i < (int)(input.pos.x * 800); ++i)
        s.a[(int)input.pos.x] = input.pos.x;

    return col * s.a[(int)input.pos.x];
}

Код не имеет смысла логически, это всего лишь пример. Проблема в том, что когда я пытаюсь скомпилировать этот код, я получаю следующую ошибку (строка 25 является строкой цикла for):

(25,7): ошибка X3511: принудительное развертывание цикл, но развертывание не удалось.

Однако, когда я помещаю массив за пределы структуры (просто объявляю float a[17] в shMain), все работает как положено.

Мой вопрос: почему DirectX пытается развернуть (неуправляемый) цикл for при использовании структуры? Это документированное поведение? Есть ли доступный обходной путь, кроме размещения массива вне структуры?

Я использую шейдерную модель 4.0, DirectX 10 SDK с июня 2010 года.

EDIT: Для пояснения я добавляю рабочий код, он только заменяет использование структуры Something на простой массив:

struct VSOUT {
    float4 projected : SV_POSITION;
    float3 pos: POSITION;
    float3 normal : NORMAL;
};


float4 shMain (VSOUT input) : SV_Target {
    float a[17];  // Direct declaration of the array

    for (int i = 0; i < (int)(input.pos.x * 800); ++i)
        a[(int)input.pos.x] = input.pos.x;

    return col * a[(int)input.pos.x];
}

Этот код компилируется и работает как положено. Это работает, даже если я добавлю атрибут [loop] перед циклом for, что означает, что он не развернут (что является правильным поведением).

1 Ответ

1 голос
/ 25 августа 2010

Я не уверен, но то, что я знаю, это то, что аппаратное расписание и фрагменты процесса обрабатываются блоком 2x2 (для вычислительных производных). Это может быть причиной того, что fxc пытается развернуть цикл for, чтобы программа шейдера выполнялась в режиме блокировки.

Также вы пытались использовать атрибут [loop] для генерации кода, который использует управление потоком?

...