Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / [hlsl] Найти 3 максимальных элемента в массиве на sm 3.0

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

Страницы: 1 2 Следующая »
SuslikМодераторwww11 июля 201814:03#0
Требуется это сделать хоть как-то. Не требуется запредельной скорости или алгоритмических острот, уже хоть как-нибудь. Имеется (псевдо-) код, который делает именно это:
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 вообще что ли не разрешает в массивы писать в циклах?

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

Правка: 11 июля 2018 14:08

innuendoПостоялецwww11 июля 201814:07#1
Suslik
> проблемы начинаются на sm 3.0, уже с первого цикла

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

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

Правка: 11 июля 2018 14:10

innuendoПостоялецwww11 июля 201814:22#3
Suslik
> а если я эту константу из текстуры прочитаю, тогда можно?

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

innuendoПостоялецwww11 июля 201814:30#4
Suslik
> да и куча других шейдеров вроде variable width blur как-то ведь прекрасно
> работает, в чём разница?

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

MAMOHT-92Постоялецwww11 июля 201816:34#5
values_count

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

Правка: 11 июля 2018 18:54

MikleМодераторwww11 июля 201819:46#7
Suslik
> Найти 3 максимальных элемента в массиве на sm 3.0
Нужны индексы в массиве и/или значения?
SuslikМодераторwww12 июля 20182:16#8
Mikle
индексы

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

DelfigamerПостоялецwww12 июля 20182:42#9
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);
и аналогично с циклами.
А если развернуть без переходов не получается - то компиляция проваливается, на что ты и попал.
SuslikМодераторwww12 июля 20182:47#10
Delfigamer
кто виноват? что делать?
MrShoorУчастникwww12 июля 20183:03#11
Delfigamer
> Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры
> разворачиваются в одну длинную линию и замазываются условными присваиваниями.
Это sm2.0 не поддерживает, а sm3.0 поддерживает
innuendoПостоялецwww12 июля 20183:08#12
Delfigamer
> Ну так-то верно - sm3.0 не поддерживает настоящих переходов, там все шейдеры
> разворачиваются в одну длинную линию и замазываются условными присваиваниями.
Delfigamer
> а что ты и попал.

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

SuslikМодераторwww12 июля 20183:58#13
побаловался ещё немного, пытаясь понять, почему оно не может заанроллить, если уж так хочется. проблема не в самом цикле, а в присваивании индекса массива:
error X3500: array reference cannot be used as an l-value; not natively addressable
error X3511: forced to unroll loop, but unrolling failed.

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

Правка: 12 июля 2018 4:07

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

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

Правка: 12 июля 2018 4:32

Страницы: 1 2 Следующая »

/ Форум / Программирование игр / Графика

2001—2018 © GameDev.ru — Разработка игр