Записки сумасшедшего: Qt+OpenGL
Мы продолжаем наш репортаж про Qt и OpenGL.
В Qt, если кто не знает, есть приятные врапперы для OpenGL. QOpenGLShaderProgram для шейдеров, QOpenGLBuffer для буферов ну и так далее. Я ими пользуюсь, потому что удобно, сахарок вкусный типа QOpenGLVertexArrayObject::Binder, опять же деструкторы все удалят и так далее.
И есть QOpenGLTexture, любовь с ней в FRV у меня не задалась (делаю все руками в результате), а тут в рамках HelloWorld-2017 решил вернуться к ней.
И получился (почти) полный fail:
В native-OpenGL-режиме все хорошо и работает (моя ошибка была в том, что я не звал setFormat() /в примерах Qt текстуры используются для загрузки прямо из png/jpeg и там не надо инициализировать по частям: create/allocateStorage/setData, но я нашел пример на github).
А вот в родном/основном для Qt режиме "GL ES поверх ANGLE поверх DX11" оно не просто не работает, а валится с грохотом (для 3D-текстур):
- Оно, внутри у себя, определяет, что возможен immutable storage
- И, соответственно, пытается аллоцировать данные черех glTexStorage3D
- А эта функция в ANGLE не резолвится (2D, я надеюсь, работает нормально)
А почему, спрашивается? Да, поди, ни одна сука не использовала, хоть враппер и есть. Если кто и использовал, так с 2D.
Даже баг файлить не буду, буду по старинке, glGenTextures() (это не говоря о том, что я вот не понимаю как скрестить QOpenGLTexture с PBO, а хочется и этого тоже).
Comments
Но зачем такое извращение с
Но зачем такое извращение с OpenGL и зачем ES на большой платформе?!
Какое именно извращение?
Какое именно извращение?
А с ES на большой платформе все просто: есть некоторое количество юзеров у которых OpenGL неживой, а DX11 - вполне живой.
Ну вот именно это изврещение
Ну вот именно это изврещение — имитация ES поверх чего попало. Но ответ, в общем, понятен.
Это не извращение, это жизнь.
Это не извращение, это жизнь. Весь WebGL (в том же Chrome) так и работает, в точности через эту дырочку.
Да и FireFox. Но как же
Да и FireFox. Но как же Вулкан? Как же нативный DX?!
Все эти дырочки обычно же очень ограничивают.
Ну мне же не нужно вертеть
Ну мне же не нужно вертеть миллион полигонов на 120fps.
А для совсем простой демозаики на 8Mpix (экран 4k) хватит и GL ES3 и вообще там надо очень мало. И данных, помимо собственно текстур, у меня очень мало.
То есть я понял что хочу гарантированную плавучку и гарантированные 3D-текстуры (для LUT), это соответственно GL ES3 и/или OpenGL 3+ (3.3/Core чтобы не заморачиваться со всякой ерундой, там посмотрим).
А писать две/три/четыре версии кода (native DX, Vulcan, GL4.3+) я не вижу пока смысла на своих задачах. С тем же FRV извернулись с 2.1+ (но color management сделан через анус и больше я так не хочу)
собственно комментарий -
собственно комментарий - какое-то время назад виндовые встроенные драйверы тупо шли с вырезанным нахрен опенглем. ну и интел тоже, те еще...
"виндовые встроенные драйвера
"виндовые встроенные драйвера" - это SVGA-драйвер?
Начиная с семерки точно (вглубь не проверял) - драйвера из windows update полноценные.
скорее из образа системы.
скорее из образа системы. пару раз точно приходилось ставить родные для получения opengl, при том что aero/DX работали полностью.
Все таки для людей не
Все таки для людей не репортящих баги есть в аду отдельный котел)
Есть, да.
Есть, да.
Но я их репорчу (немало, штуки 3 за этот месяц) и результат меня огорчает.
Пусть починят что-то, для чего я не дал готового патча (таких сейчас 2 или 3 висит в bugreports.qt) - тогда я увижу что конструкция работает.
Я пару дней назад написал
Я пару дней назад написал одной солидной компании, что для людей, не реагирующих на баг-репорты, есть специальный круг ада.
Вот там все и встретимся.
Вот там все и встретимся. Потому что это все одни и те же люди
В аду остро стоит квартирный
В аду остро стоит квартирный вопрос.
Запалим пионерский костер,
Запалим пионерский костер, погреемся у него
Случайно выяснилось, что этот
Случайно выяснилось, что этот баг исправлен в Qt 5.9.3
(ну или раньше, но в 5.9.3 уже все хорошо)
Ну и значит без моего костра обойдутся.
Алексей, здравсвуйте!
Алексей, здравсвуйте!
Добрался таки и я до Qt/GL... Увы
Уже после дня экспериментов с PBO нашел пример (http://www.songho.ca/opengl/gl_pbo.html). В примере три режима: без PBO, с одним PBO, c двумя PBO
Что вижу в результатах:
PBO mode: 1 (single PBO)
Transfer Rate: 1347.2 MB/s. (21.1 FPS)
Transfer Rate: 1360.9 MB/s. (21.3 FPS)
Transfer Rate: 1419.8 MB/s. (22.2 FPS)
PBO mode: 2 (two PBO)
Transfer Rate: 2405.6 MB/s. (37.6 FPS)
Transfer Rate: 2441.2 MB/s. (38.1 FPS)
Transfer Rate: 2446.7 MB/s. (38.2 FPS)
PBO mode: 0 (glTexSubImage2D)
Transfer Rate: 1855.7 MB/s. (29.0 FPS)
Transfer Rate: 1852.0 MB/s. (28.9 FPS)
Transfer Rate: 1860.3 MB/s. (29.1 FPS)
И что-то не понимаю. Т.е. цикл с glTexSubImage2D быстрее, чем с одним PBO.
Но в примере хоть тайминги glTexSubImage2D соответствуют действительности.
На моем же Qt-шном рабочем примере glTexSubImage2D при включенном буфере ну совсем не non-blocking.
Вызов glTexSubImage2D для данных ~80Mb блокирует на 50мс в пике, почти столько же, сколько занимает вышележащий memcpy в замапленный указатель.
Может, вы с подскажете, что я могу делать не так... Может, Qt резолвит функции OpenGL как-то по своему. Куда смотреть?
Спасибо!
У меня, во всяком случае пока
У меня, во всяком случае пока, не бывает "следующего кадра", соотв. в PBO не вижу смысла.
Глянул тот пример.
Глянул тот пример.
pboMode=0 - 500fps,
1,2 = 1000fps
(округленно).
А имеет смысл, похоже, даже с одним буфером (а второй - смысла не имеет). Если вылезет заметно в профайлере - буду пробовать (хотя на фоне распаковки raw - вылезет вряд-ли)
Я рассчитывал, что с одним
Я рассчитывал, что с одним PBO буффером glTexSubImage будет работать асинхронно (через DMA) и я не залипну на 50мс в главном потоке. Но, по сути glTexSubImage _у меня_ почему-то блокирующий и занимает те же миллисикунды, что и простой glTexSubImage и memcpy.
Т.е., не учитывая распаковки, получается, что только загнать 80Mb рав в (избыточном, но оптимальном?) формате RGBA8 - это 50мс (macbook pro'14)... А с ним там еще что-то делать нужно. Т.е. в данном случае с OpenGL работать нужно с несколькими контекстами в разных потоках? Или есть какие известные решения? Ну, может, там, из области обработки видео - там, по идее, движение туда-сюда должно быть существенным?
Ну да, glTex(Sub)Image -
Ну да, glTex(Sub)Image - блокирующий.
В том примерчике - он не
В том примерчике - он не блокирующий. Я там сделал размеры текстуры 4096x4096 и вижу copyTime в режиме c PBO - меньше 1мс.
У вас в любом случае
У вас в любом случае отрисовка не может начаться до того, как в GPU залита текстура.
Да, это понятно. Но хотелось
Да, это понятно. Но хотелось избежать именно блокировки в потоке CPU.
Но почему в примере вызов не блокирующий, а у меня блокирующий - не понятно.
Там с вынесением OpenGL в
Там с вынесением OpenGL в другой thread какие-то пляски с бубном.
Впрочем, в районе Qt 5.6 появился пример про threaded OpenGL - возможно эти пляски как-то упростили, не вдавался.
Даже в 5.4 он есть.
Даже в 5.4 он есть.
У меня все в главном потоке
У меня все в главном потоке покаместь. С новым контекстом в отдельном потоке вроде ничего сложного. Это будет следующий шаг.
Не то что бы асинхронность glTexImage2D меня спасет... На рендеринге выскочит, да и простой memcpy в замапленный пиксельный буффер плюс теже 50мс.
Буду дальше пытаться разбираться...
Вообщем, glTextSubImage2d из
Вообщем, glTextSubImage2d из буффера действительно асинхронный.
У меня была проблема, видимо, с тем, что я генерировал и настраивал текстуру в том же цикле, в котором создавал буфер. После переноса генерации и настройки текстуры на стадию инициализации - glTextSubImage2d заработала с нулевой задержкой.
Ну возможно там есть какие-то
Ну возможно там есть какие-то неявные синхронизации, я не задумывался