Получить результаты вычислений на GPU обратно в программу CPU в OpenGL
Есть ли способ получить результаты от шейдера, работающего на GPU, обратно к программе, работающей на CPU?
Я хочу создать полигональную сетку из простых данных вокселей на основе дорогостоящего вычислительного алгоритма на GPU, но мне нужен результат на CPU для физических расчетов.
1 ответ
Определите "результаты"?
В общем, если вы выполняете вычисления в стиле GPGPU с OpenGL, вам нужно будет структурировать свои шейдеры в соответствии с требованиями системы рендеринга. Системы рендеринга спроектированы как односторонние: в них поступают данные и создается изображение. Возвращение назад, когда система рендеринга производит данные, обычно не является структурой рендеринга.
Это не значит, что вы не можете сделать это, конечно. Но вам нужно спроектировать все вокруг ограничений OpenGL.
OpenGL предлагает ряд хуков, где вы можете записывать данные с определенных этапов шейдера. Большинство из них требуют специализированного оборудования
Фрагмент выходов шейдера
Любое оборудование, способное к фрагментным шейдерам, очевидно, позволит вам записывать в текущий кадровый буфер, который вы рендерите. Благодаря использованию объектов и текстур кадрового буфера с форматами изображений с плавающей запятой или целыми числами, вы можете записывать практически любые данные, которые вы хотите, для различных изображений. Оказавшись в текстуре, вы можете просто позвонить glGetTexImage
чтобы получить визуализированные данные пикселей. Или вы можете просто сделать glReadPixels
чтобы получить это, если FBO все еще связано. В любом случае работает.
Основные ограничения этого метода:
Количество изображений, которые вы можете прикрепить к кадровому буферу; это ограничивает объем данных, которые вы можете записать. На оборудовании до GL 3.x FBO обычно ограничивались только 4 изображениями плюс буфер глубины / трафарета. В 3.x и более качественном оборудовании вы можете ожидать минимум 8 изображений.
Тот факт, что вы оказываете. Это означает, что вам нужно настроить данные вершин так, чтобы треугольник располагался именно там, где вы хотите, чтобы он модифицировал данные. Это не тривиальное начинание. Также сложно получить полезные входные данные, так как вы обычно хотите, чтобы каждый тексель был довольно независимым от другого. Структурировать ваш фрагментный шейдер вокруг этих ограничений сложно. Не невозможно, но во многих случаях нетривиально.
Преобразование обратной связи
Эта функция OpenGL 3.0 позволяет захватывать выходные данные этапа обработки вершин OpenGL (вершинный шейдер и дополнительный геометрический шейдер) в одном или нескольких буферных объектах.
Это гораздо более естественно для захвата вершинных данных, с которыми вы хотите поиграть или отрендерить снова. В вашем случае вам нужно будет прочитать его обратно после рендеринга, возможно, с glGetBufferSubData
позвонить, или с помощью glMapBufferRange
для чтения.
Ограничения здесь заключаются в том, что вы обычно можете захватить только 4 выходных значения, где каждое значение является vec4. Есть также некоторые строгие ограничения макета. Некоторое оборудование OpenGL 3.x и 4.x предлагает возможность записи данных в несколько потоков обратной связи, которые могут быть записаны в разные буферы.
Загрузка / хранение изображений
Эта особенность GL 4.2 представляет собой вершину записи: вы можете привязать изображение (текстуру буфера, если вы хотите записать в буфер) и просто записать в него. Существуют ограничения по упорядочению памяти, с которыми вам нужно работать.
Это очень гибкий, но очень сложный. Помимо сложности в правильном использовании, есть ряд ограничений. Количество изображений, к которым вы можете написать, будет довольно ограниченным, возможно, 8 или около того. И реализации могут иметь общие пределы записи, так что 8 изображений для записи, возможно, должны быть совместно использованы выходами фрагментного шейдера.
Более того, вывод изображения гарантирован только для фрагментного шейдера (и 4.3 вычислительных шейдеров). То есть аппаратное обеспечение может запретить вам использовать загрузку / сохранение изображений на этапах шейдеров не-FS/CS.