Какие функции OpenGL не ускоряются GPU?

Я был потрясен, когда прочитал это (из OpenGL wiki):

glTranslate, glRotate, glScale

эти аппаратное ускорение?

нет, нет ГП исполнять это. Водитель вычисляет матрица на CPU и загружает ее в ГПУ.

все остальные операции матрицы сделано на CPU, а также : glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho.

вот почему эти функции считаются устаревшими в GL 3.0. У вас должна быть своя математическая библиотека, создайте свою собственную матрицу, загрузите матрица шейдеру.

на очень долгое время я думал, что большинство функций OpenGL используют GPU для вычисления. Я не уверен, что это распространенное заблуждение, но через некоторое время это имеет смысл. Старые функции OpenGL (2.X и старше) действительно не подходит для реальных приложений из-за слишком большого количества переключателей состояния.

Это заставляет меня понять, что, возможно, многие функции OpenGL вообще не используют GPU.

Итак, вопрос:

какие вызовы функций OpenGL не используют GPU?

Я считаю, что зная ответ на этот вопрос поможет мне стать лучшим программистом с OpenGL. Пожалуйста, поделитесь некоторыми из ваших интуиция.

Edit:

Я знаю, что этот вопрос легко приводит к оптимизации уровня. Это хорошо, но это не цель этого вопроса.

Если кто-то знает набор функций GL на определенной популярной реализации (как предложил AshleysBrain, nVidia/ATI и, возможно, зависящий от ос), которые не используют GPU, это то, что мне нужно!

правдоподобные руководства по оптимизации приходят позже. Давайте сосредоточимся на функциях, для этого тема.

Edit2:

эта тема не о том, как работают преобразования матриц. Есть другое темы для этого.

5 ответов


мальчик, это большая тема.

во-первых, я начну с очевидного: поскольку вы вызываете функцию (любую функцию) из ЦП, она должна работать хотя бы частично на ЦП. Так что вопрос в том, сколько работы выполняется на CPU и сколько на GPU.

во-вторых, чтобы GPU мог выполнить какую-то команду, CPU должен подготовить описание команды для передачи. Минимальный набор здесь-это маркер команды, описывающий, что делать, а также данные для выполнения операции. Как CPU запускает GPU для выполнения команды, также несколько важно. Поскольку большую часть времени это дорого, CPU делает это не часто, а скорее пакетами команд в буферах команд и просто отправляет весь буфер для обработки GPU.

все это говорит о том, что передача работы на GPU не является бесплатным упражнением. Эта стоимость должна быть сопоставлена с просто запуском функции на CPU (независимо от того, о чем мы говорим о.)

сделав шаг назад, вы должны спросить себя зачем вам нужна видеокарта. Дело в том, что чистая реализация CPU выполняет эту работу (как упоминает AshleysBrain). Мощность GPU происходит от его дизайна для обработки:

  • специализированные задачи (растеризация, смешивание, фильтрация текстуры, блитинг,...)
  • сильно параллельные рабочие нагрузки (DeadMG указывает на это в своем ответе), когда процессор больше предназначен для обработки однопоточной работы.

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

жесткий в общем). Таким образом, некоторые реализации только решают переместить ограниченное подмножество вызовов в списке отображения в вычисляемый формат и просто воспроизвести остальную часть потока команд на CPU.

выбор еще один, где неясно, есть ли значение для выполнения на ГПУ.

наконец, я должен сказать, что в целом существует небольшая корреляция между вызовами API и объемом работы на CPU или GPU. API настройки состояния имеет тенденцию изменять структуру только где-то в данных драйвера. Его эффект виден только тогда, когда вызывается ничья или что-то подобное.

многие API GL работают именно так. В этот момент, спрашивая,glEnable(GL_BLEND) выполняется на CPU или GPU довольно бессмысленно. Важно ли смешивать произойдет на GPU при вызове Draw. Итак, в этом смысле,большинство точки входа GL не ускоряются вообще.

Я также мог бы немного расширить передачу данных, но Данвил коснулся этого.

Я закончу с маленьким "S / W path". Исторически сложилось так, что GL должен был работать для спецификации независимо от того, какие аппаратные специальные случаи были. Это означало, что если h/w не обрабатывал конкретную функцию GL, то он должен был эмулировать ее или полностью реализовать в программном обеспечении. Есть многочисленные случаи этого, но один, который поразил много людей, когда GLSL начал появляться.

поскольку не было практического способа оценить размер кода шейдера GLSL, было решено, что GL должен принимать любую длину шейдера как допустимую. Вывод был довольно ясен: либо реализовать h/w, который может принимать шейдеры произвольной длины-не реалистичные в то время -, либо реализовать эмуляцию шейдеров s/w (или, как решили некоторые поставщики, просто не соответствовать). Итак, если вы срабатывало это условие на фрагмент шейдера, шансы были весь вашего GL в конечном итоге выполняется на CPU, даже когда у вас был GPU, сидящий без дела, по крайней мере, для этой ничьей.


вопрос, возможно, должен быть "какие функции едят неожиданно большое количество времени процессора?"

сохранение матричного стека для проекции и просмотра-это не то, что GPU может обрабатывать лучше, чем CPU (наоборот ...). Другим примером может быть компиляция шейдеров. Почему это должно работать на GPU? Есть парсер, компилятор, ..., которые являются обычными программами процессора, такими как компилятор C++.

потенциально "опасные" вызовы функций, например glReadPixels, потому что данные могут быть скопированы из памяти хоста (=CPU) в память устройства (=GPU) по ограниченной шине. В этой категории также есть такие функции, как glTexImage_D или glBufferData.

так вообще говоря, если вы хотите знать, сколько времени процессора съедает вызов OpenGL, попробуйте понять его функциональность. И остерегайтесь всех функций, которые копируют данные с хоста на устройство и обратно!


обычно, если операция per-something, она будет происходить на GPU. Примером является фактическое преобразование-это делается один раз на вершину. С другой стороны, если это происходит только один раз за большую операцию, это будет на ЦП - например, создание матрицы преобразования, которая выполняется только один раз для каждого изменения состояния объекта или один раз за кадр.

Это просто общий ответ, и некоторые функции будут происходить наоборот - а также зависеть от реализации. Однако, как правило, это не должно иметь значения для вас, программиста. До тех пор, пока вы позволяете GPU много времени, чтобы сделать это работа, пока вы делаете игру sim или что-то еще, или иметь прочную модель резьбы, вам не нужно беспокоиться об этом так много.

@отправка данных на GPU: насколько я знаю (используется только Direct3D), все это делается в шейдере, вот для чего шейдеры.


glTranslate, glRotate и glScale изменяют текущую активную матрицу преобразования. Это, конечно, операция CPU. Матрицы вида модели и проекции просто описывают, как GPU должен преобразовывать вершины при выдаче команды рендеринга.

Так, например, при вызове glTranslate ничего не переводится вообще. Перед рендерингом умножаются текущие матрицы проекции и вида модели (MVP = projection * modelview) , затем эта единственная матрица копируется в GPU, а затем GPU выполняет умножение матриц * вершин ("T&L") для каждой вершины. Итак, перевод/масштабирование / проекция вершин is сделано GPU.

и вы действительно не должны беспокоиться о производительности, если вы не используете эти функции в каком-то внутреннем цикле. glTranslate приводит к три дополнения. glScale и glRotate немного сложнее.

мой совет заключается в том, что вы должны узнать немного больше о линейной алгебре. Это необходимо для работы с 3D API.


существуют программные реализации OpenGL, поэтому возможно, что нет функции OpenGL работают на GPU. Существует также аппаратное обеспечение, которое не поддерживает определенные состояния рендеринга в аппаратном обеспечении, поэтому, если вы установите определенное состояние, переключитесь на рендеринг программного обеспечения, и снова ничего не будет работать на GPU (хотя там есть один). Поэтому я не думаю, что существует четкое различие между "ускоренными функциями GPU" и "ускоренными функциями без GPU".

на безопасная сторона, держите вещи как можно проще. Простой рендеринг с вершинами и основными функциями, такими как Z-буферизация, являются скорее всего для аппаратного ускорения, поэтому, если вы можете придерживаться этого с минимальным изменением состояния, вы, скорее всего, будете держать аппаратное ускорение. Это также способ максимизировать производительность аппаратно-ускоренного рендеринга-графические карты любят оставаться в одном состоянии и просто хрустеть кучей вершин.