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];
}
2

Другие решения


По вопросам рекламы [email protected]