Возможно, это не реальный ответ на проблему, но, возможно, даст немного больше понимания.Я немного проверил сгенерированный код сборки и преобразовал его обратно в код высокого уровня.Я старался максимально сжать его и удалить все копии и временные данные, которые неявно следуют за операциями высокого уровня.Я использовал b
переменные как временные буферы и f
s как временные буферы.Первый (с версией 2.2):
power = ( c > 0.0 ) ? vValue : ( 1.0 - vValue );
R1 = tex2D( palette, float2( power, 0.0 ) );
vRealValue = abs( vValue - 0.5 );
b1 = ( tValue < th1 );
b2 = ( tValue <= th2 );
b3 = b1;
b1 = b1 && b2 && ( vRealValue > th0 );
R1 = b1 ? R1 : BackGroundColor;
color = ( b2 && !b3 ) ? float4( 0.0, tValue, 0.0, 1.0 ) : R1;
, а второй (с версией 3.0):
vRealValue = abs( vValue - 0.5 );
f0 = c;
b0 = ( 0 < f0 );
b1 = ( tValue < th1 );
b2 = ( tValue <= th2 );
b4 = b1 && b2 && ( vRealValue > th0 );
b0 = b0;
b3 = b1;
power = ( b4 && !b0 ) ? ( 1.0 - vValue ) : vValue;
R1 = tex2D( palette, float2( power, 0.0 ) );
R1 = b4 ? R1 : BackGroundColor;
color = ( b2 && !b3 ) ? float4( 0.0, tValue, 0.0, 1.0 ) : R1;
Большинство частей практически одинаковы.Вторая программа делает некоторые ненужные операции.Он копирует переменную c
во временную, а не использует ее напрямую.Кроме того, он переключает vValue
и 1-vValue
при вычислении мощности, поэтому ему необходимо отрицать b0
(что приводит к еще одному CMP
), в то время как первый вообще не использует временный (он использует * 1014)* напрямую вместо SLT
и CMP
).В этом вычислении он также использует b4
, что совершенно не нужно, потому что когда b4
равно false, результат доступа к текстуре в любом случае не имеет значения.Это приводит к еще одному &&
(реализовано с MUL
).Существует также ненужная копия от b1
до b3
(в первой программе она необходима, но не во второй).И крайне бесполезная копия из b0
в себя (которая замаскирована как ABS
, но так как значение приходит от SLT
, оно может быть только 0,0 или 1,0, а ABS
вырождается в MOV
).
Итак, вторая программа очень похожа на первую с некоторыми дополнительными, но ИМХО совершенно бесполезными инструкциями.Похоже, оптимизатор проделал худшую работу по сравнению с предыдущей (!) Версией.Поскольку компилятор Cg является продуктом nVidia (а не какой-то другой, не именуемой графической компанией), это поведение действительно странно.