Перекрывающиеся регистры в шейдере Халла?

Я делаю некоторую аппаратную тесселяцию и мне удалось получить базовый эффект подразделения, поэтому я попытался перейти к тесселяции Фонга (которая предназначена для округления краев). Теперь, когда я хочу добавить дополнительные выходы в функцию Patch Constant и записать их, но один из них выдает ошибку.

struct ConstantOutputType
{
    float edges[3] : SV_TessFactor;
    float inside : SV_InsideTessFactor;

    float3 f3B0 : POSITION0;
    float3 f3B1 : POSITION1;
    float3 f3B2 : POSITION2;

    float3 f3N0 : NORMAL0;
    float3 f3N1 : NORMAL1;
    float3 f3N2 : NORMAL2;
};

ConstantOutputType PatchConstantFunction(InputPatch<HullInputType, 3> inputPatch, uint patchId : SV_PrimitiveID)
{    
    ConstantOutputType output = (ConstantOutputType)0;


    // Set the tessellation factors for the three edges of the triangle.
    output.edges[0] = inputPatch[0].dep;
    output.edges[1] = inputPatch[1].dep;
    output.edges[2] = inputPatch[2].dep;

    // Set the tessellation factor for tessallating inside the triangle.
    output.inside = (inputPatch[0].dep + inputPatch[1].dep + inputPatch[2].dep)/3.0f;


    output.f3B0 = inputPatch[0].pos.xyz;
    output.f3B1 = inputPatch[1].pos.xyz;
    output.f3B2 = inputPatch[2].pos.xyz;

    //output.f3N0 = inputPatch[0].nor.xyz;  <=====This throws the error (setting the normal)
    output.f3N1 = inputPatch[1].nor.xyz;
    output.f3N2 = inputPatch[2].nor.xyz;

    return output;
} 

Выдается ошибка: ошибка X8000: внутренняя ошибка компилятора D3D11: неверный байт-код: компоненты входного объявления для регистра 1 перекрываются с предыдущим объявлением для того же регистра. Код операции № 47 (количество основано на 1). ошибка X8000: D3D11 Внутренняя ошибка компилятора: Неверный байт-код: Не удается продолжить проверку - прерывание. Что я не могу понять, что это значит (учитывая, что это моя самая первая попытка шейдера корпуса).

Если я это закомментирую, это будет работать, если я установлю произвольное значение для этого, это тоже сработает (например: output.f3N0 = float3(0,1,0)). Я также пытался изменить семантику для переменных, но не помогло. Я был бы очень рад, если бы кто-то мог дать мне некоторое представление об этом.

ОБНОВЛЕНИЕ: ввод данных корпуса в соответствии с запросом:

struct HullInputType
{
    float3 pos              : POSITION;
    float2 tex              : TEXCOORD0;
    float3 nor              : TEXCOORD1;
    float  dep              : TEXCOORD2;
};

1 ответ

Решение

Хорошо, похоже, что (float dep: TEXCOORD2;) во входной структуре шейдерного корпуса была проблемой. Возможно, поскольку шейдерный блок работает с регистрами float4, две переменные float3 не могли быть объединены, но float2 и float были объединены в регистр float4. То же самое с двумя float2, но float2 и float3 не могут быть соединены и не будут перекрываться. Так что я предполагаю, что буду отправлять информацию глубины (float dep) с (float2 tex) в переменной float3.

Интересно, что у кого-то это работает. И это в моем доменном пиксельном шейдере не перекрывает регистры таким способом.

ОБНОВЛЕНИЕ: Это не работает, ошибка исчезла, я могу скомпилировать шейдер, но если я попытаюсь использовать эту переменную, назначив ее из входной структуры, тогда весь графический рендеринг просто перестанет работать (даже неасселлированные вызовы). Это происходит на ТС устройстве, на WARP как-то работает.

ОБНОВЛЕНИЕ 2: Теперь я исправил это, отправив только float4s, но мне не нравится этот бит. Очень странно, что мне не нужно этого делать в моих вершинных и пиксельных шейдерах, может быть, это глюк? Или это может быть аппаратная несовместимость графического процессора (Nvidia GT525M).

Другие вопросы по тегам