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

Я изучаю DirectCompute и застрял в StructuredBufferes. Дело в том, что я узнал, что для передачи данных в шейдер мне нужно использовать View - SRV или БПЛА, в зависимости от того, чего я пытаюсь достичь. Но примеры кода с сайта 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. Заранее спасибо.


person Ilia    schedule 16.09.2015    source источник


Ответы (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];
}
person MooseBoys    schedule 09.10.2015