Итак, было задано много подобных вопросов, но в моей ситуации Мне действительно нужно поделиться данными .
Вот моя ситуация. У меня есть программа, которая стремится заполнить 3D-текстуру значениями, начиная сверху вниз и опускаясь вниз. Программа заполняет своего рода модель водопада.
Функция, которая принимает значение, связанное с ячейкой в трехмерной текстуре, и ее положение относительно текущей ячейки, т.е. f(x, position)
, и создает новое значение, добавленное к текущей ячейке. Вы можете думать об этом как о заливке типа
Теперь, если бы мне были нужны только смежные значения, я мог бы просто использовать точки-призраки,проблема заключается в том, что одно значение распространяется от его текущего местоположения наружу, поэтому смежные значения будут обновляться вне того текущего текущего блока, в котором я работаю.
Теперь мне не нужно передавать весь блокДанные из соседних блоков мне просто нужны, на каждом шаге, значения соседних блоков, окружающих текущую сетку. Я все еще буду использовать призрачные точки, но мне нужно будет передать «новые» значения, чтобы использовать их.
Моя проблема заключается в том, что каждый говорит, что "используйте другой вызов вычислительного шейдера", чтобы обойти это. Это неприемлемо, не хватает работы, чтобы оправдать стоимость запуска ядра.
Единственные параметры, которые я вижу:
- использовать атомарные целочисленные значения для связи между группами, чтобы группы знали, что они могут использовать значение в некоторой глобальной памяти, которая соответствует этим элементам граничных данных
- делит время выполнения насквозь, копируя значения соседних ячеек в отдельный буфер, а затем снова запускает весь процесс, чтобы учесть новые смежные значения для каждой стороны (в кубе их 6).
- использовать только один групповой вызов для всей вещи. Может быть достаточно других вещей, которые GPU делает, чтобы гарантировать это
- , используя несколько вызовов вычислительных шейдеров для каждого "слоя" 3D-текстуры, что потребовало бы сброса значений в глобальную память, а затем считывания их обратно вдля каждого уровня, фактически удваивая стоимость чтения глобальной памяти и вызывая издержки ядра, поскольку каждое ядро должно быть запущено по порядку. Если бы я мог хранить одну и ту же память в общей памяти между вызовами ядра и не перечитывать ее обратно, это уменьшило бы проблему двойной задержки.
Нет ли другого способа скопировать границы в вычислительных шейдерах?