2015-09-16 5 views
1

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

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

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

ответ

2

Реестровые привязки, объявленные в шейдере, соответствуют индексу в аргументе массива привязки. Например, если вы позвоните 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]; 
} 
+0

Это хорошее объяснение, спасибо. – Ilia

Смежные вопросы