Войти
ПрограммированиеФорумГрафика

[hlsl] Найти 3 максимальных элемента в массиве на sm 3.0

Страницы: 1 2 Следующая »
#0
(Правка: 14:08) 14:03, 11 июля 2018

Требуется это сделать хоть как-то. Не требуется запредельной скорости или алгоритмических острот, уже хоть как-нибудь. Имеется (псевдо-) код, который делает именно это:

uniform float4 values[32];
uniform int values_count;

float4 main(in float4 pos : POSITION) : COLOR
{
  float weights[32];
  int count = 0;
  [loop]
  for(int i = 0; i < values_count; i++)
  {
    float weight = SomeFunc(pos, values[i]);
    weights[count] = weight;
    count += weight > 0 ? 1 : 0; //branchless, все дела
  }
  //...дальше очень умный код с поиском 3 максимальных элементов в массиве weights[]
}
на sm 5.0 код работает прекрасно, проблем нет. проблемы начинаются на sm 3.0, уже с первого цикла, где я подготавливаю данные, чтобы потом циклы не крутить по полупустому массиву(я знаю, что в нём будет много нулей). к сожалению, компилятора под рукой нет, но ошибка была примерно "can't force unroll with [loop] modifier". wtf? я специально указал [loop], чтоб он даже не пытался анроллить. если его убрать, ошибка другая: "error X3511: forced to unroll loop, but unrolling failed.". почему оно пытается unroll'ить этот цикл? почему не получается?

sm 3.0 вообще что ли не разрешает в массивы писать в циклах?

программа минимум — понять, почему оно вообще не работает. программа максимум: понять, как сделать, чтоб заработало.

#1
14:07, 11 июля 2018

Suslik
> проблемы начинаются на sm 3.0, уже с первого цикла

нельзя на Sm3.0 делать динамик цикл по константам

#2
(Правка: 14:10) 14:09, 11 июля 2018

innuendo
а если я эту константу из текстуры прочитаю, тогда можно? да и куча других шейдеров вроде variable width blur как-то ведь прекрасно работает, в чём разница?

#3
14:22, 11 июля 2018

Suslik
> а если я эту константу из текстуры прочитаю, тогда можно?

можно юниформы загнать в текстуру

#4
14:30, 11 июля 2018

Suslik
> да и куча других шейдеров вроде variable width blur как-то ведь прекрасно
> работает, в чём разница?

там цикл разматывается и все обращения к константам с фиксированным индексом

#5
16:34, 11 июля 2018
values_count

у тебя есть какое-то максимальное значение, выше которого не будет? Если это 32, тогда делай цикл от 0 до 32-1 (захреначь дефайном) и если у тебя i  >= values_count, тогда ничего не делай, а пусть цикл докручивается.
#6
(Правка: 18:54) 18:54, 11 июля 2018

Suslik
Можешь собрать минимальный код шейдера, который у тебя не компилируется по этой причине и выложить сюда?

#7
19:46, 11 июля 2018

Suslik
> Найти 3 максимальных элемента в массиве на sm 3.0
Нужны индексы в массиве и/или значения?

#8
2:16, 12 июля 2018

Mikle
индексы

MrShoor
ещё поплюхаюсь и если не получится, то выложу

#9
2:42, 12 июля 2018

Suslik
Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры разворачиваются в одну длинную линию и замазываются условными присваиваниями.
То есть, типа,

if(cond)
  left = effect(right);
else
  right = effect(left);
разворачивается в
newleft = effect(right);
newright = effect(left);
left = step(cond, left, newleft);
right = step(cond, right, newright);
и аналогично с циклами.
А если развернуть без переходов не получается - то компиляция проваливается, на что ты и попал.
#10
2:47, 12 июля 2018

Delfigamer
кто виноват? что делать?

#11
3:03, 12 июля 2018

Delfigamer
> Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры
> разворачиваются в одну длинную линию и замазываются условными присваиваниями.
Это sm2.0 не поддерживает, а sm3.0 поддерживает

#12
3:08, 12 июля 2018

Delfigamer
> Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры
> разворачиваются в одну длинную линию и замазываются условными присваиваниями.
Delfigamer
> а что ты и попал.

вот тут ты и попал

#13
(Правка: 4:07) 3:58, 12 июля 2018

побаловался ещё немного, пытаясь понять, почему оно не может заанроллить, если уж так хочется. проблема не в самом цикле, а в присваивании индекса массива:

error X3500: array reference cannot be used as an l-value; not natively addressable
error X3511: forced to unroll loop, but unrolling failed.

как можно обойти проблему, если я заранее знаю, что в исходном массиве будут большинство нулей?

#14
(Правка: 4:32) 4:15, 12 июля 2018

Suslik
> проблема не в самом цикле, а в присваивании индекса массива:
Если это то что в первом посте, то при развертывании цикла должна получаться константа, а у тебя count это вычисляемая переменная, поэтому и ругается.

А нельзя не делать этот поиск для каждого фрагмента, а как-то отсортировать values заранее?

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика