Ограничения использования интерфейса
Текущее оборудование GPU не поддерживает различные сведения о слотах в среде выполнения шейдера. Как следствие, ссылки на интерфейс нельзя изменить в условном выражении, таком как оператор if или switch.
В следующем коде шейдера показано, когда будет происходить это ограничение и возможный альтернативный подход.
Учитывая следующие объявления интерфейса:
interface A
{
float GetRatio();
bool IsGood();
};
interface B
{
float GetValue();
};
A arrayA[6];
B arrayB[6];
Учитывая следующие объявления классов:
class C1 : A
{
float var;
float GetRatio() { return 1.0f; }
bool IsGood() { return true; }
};
class C2 : C1, B
{
float GetRatio() { return C1::GetRatio() * 0.33f; }
float GetValue() { return 5.0f; }
bool IsGood() { return false; }
};
class C3 : B
{
float var;
float GetValue() { return -1.0f; }
};
class C4 : A, B
{
float var;
float GetRatio() { return var; }
float GetValue() { return var * 2.0f; }
bool IsGood() { return var > 0.0f; }
};
Ссылку на интерфейс нельзя изменить в условном выражении (оператор if):
float main() : wicked
{
float rev;
{
A a = arrayA[0];
for( uint i = 0; i < 6; ++i )
{
if( arrayA[i].IsGood() )
{
// This forces the loop to be unrolled,
// since the slot information is changing.
a = arrayA[i];
rev -= arrayA[i-2].GetRatio();
}
else
{
// This causes an error since the compiler is
// unable to determine the interface slot
rev += arrayB[i].GetValue() + a.GetRatio();
}
}
}
return rev;
}
При одинаковых объявлениях интерфейса и класса можно использовать индекс для предоставления одинаковых функциональных возможностей и предотвращения принудительной отмены цикла.
float main() : wicked
{
float rev;
{
uint index = 0;
for( uint i = 0; i < 6; ++i )
{
if( arrayA[i].IsGood() )
{
index = i;
rev -= arrayA[i-2].GetRatio();
}
else
{
rev += arrayB[i].GetValue() + arrayA[index].GetRatio();
}
}
}
return rev;
}
Связанные темы