DirectCompute шейдерный ввод / вывод данных

Я учусь DirectCompute, и я застрял с StructuredBufferes. Дело в том, что я узнал, что для подачи данных в шейдер мне нужно использовать View - SRV или UAV, в зависимости от того, чего я пытаюсь достичь. Но примеры кода с сайта Microsoft не объясняют, как представление, определенное в коде C++, соответствует определенному буферу, определенному в шейдерном коде. Тем не менее, есть ключевое слово hlsl, которое я не совсем понимаю - register(), В выборке было три буфера:

    StructuredBuffer<BuffType> Buff0 : register(t0);
    StructuredBuffer<BuffType> Buff1 : register(t1);
    RWStructuredBuffer<BuffType> BuffOut : register(u0);

В коде C++ авторы просто устанавливают ComputeShader, 1 UAV, 2 SRV и затем вызывают Context.Dispatch(,,) (при условии, что они подготовили все буферы и представления ранее). Поэтому возникает вопрос - как я понимаю, что конкретный SRV (их два) предоставляет данные для конкретного StructuredBuffer? Управляется ли он номером регистра (например, регистр (t0) заполняется первым, регистр (t1) - вторым). Если да, то что, если я хочу сначала предоставить данные во второй буфер, а затем заполнить первый? Я чувствую себя так, что мне не хватает чего-то очень важного, но в предыдущих уроках я использовал все было намного проще благодаря методам EffectVariales и .GetVariableBy. Заранее спасибо.

1 ответ

Связанные регистры, объявленные в шейдере, соответствуют индексу в аргументе массива привязки. Например, если вы звоните CSSetShaderResources(7 /*StartSlot*/, 3 /*NumViews*/, viewArray);это будет связывать viewArray[0] в register(t7), viewArray[1] в register(t8), а также viewArray[2] в register(t9), Обратите внимание, что если один из элементов viewArray является NULL, что эффективно открепит соответствующий слот регистра.

Обратите внимание, что в HLSL, опуская явное register Привязка автоматически назначит регистры, начиная с 0. И в общем случае StartSlot будет 0так что вам просто нужно убедиться, что порядок просмотров в viewArray соответствует порядку объявления в вашем шейдере. Тем не менее, рекомендуется явно назначать регистры и проверять, соответствуют ли они вашему массиву привязки, потому что, если компилятор HLSL определит, что вам не нужно одно из объявленных представлений, он устранит его и не пропустит свой слот в неявном виде. назначение. Например:

StructuredBuffer<float> foo; // register(t0)
StructuredBuffer<float> bar; // eliminated!
StructuredBuffer<float> baz; // register(t1) // skipped over bar!
RWStructuredBuffer<float> biz; // register(u0)
void main()
{
    float x = foo[0];
    if(x < 0) x = 0;
    else if(x >= 0) x = 1;
    else x = bar[0]; // branch never hit, compiler optimizes out the only use of bar!
    biz[0] = x + baz[0];
}
Другие вопросы по тегам