LINUX.ORG.RU

Взаимодействие между программным и аппаратным рендерингом

 , ,


1

1

Как в тулкитах совмещается программный и аппаратный рендеринг так чтобы не было тормозов при копировании из/в видеопамять и чтобы не было избыточных буферов/копирования? Далеко не всё рисование в тулкитах делается через GPU. Можно примеры на места в коде реализации тулкитов.

В частности интересно возможно ли нарисовать буфер в RAM на OpenGL рендербуфере с клиппингом без дополнительных буферов и копирований? Буфер в RAM можно выделить с необходимым выравниванием и прочими параметрами если требуется.

★★

Ответ на: комментарий от eternal_sorrow

Нагружать видеокарту системной задачей вроде отрисовки интерфейса - это рак мозга. Видеокарта нужна чтобы с прикладными видео и 3D работать, а не системе окошки рисовать.

anonymous ()
Ответ на: комментарий от anonymous

Процессор по твоей логике тоже этим говном загружать нельзя. Святым духом интерфейс рисовать? Пусть лучше видеокарту грузит, а то она простаивает. А процессору всегда найдётся, чем заняться.

anonymous ()
Ответ на: комментарий от X512

например растеризация маски залития полигонов.

Нет, для этого есть тест трафарета (stensil testure). Или альфа канал в обычной и discard в шейдере.

ГПУ всегда рисует в свою память (даже если та отобрана у обычной RAM) если ты хочешь что-то там, а что-то тут то тебе всё равно надо будет из ГПУ результат забирать, а потом дорисовывать на ЦПУ или наоборот, но в этом случае одновременно то что нарисовал ЦПУ нужно маскировать альфой или стенсилом.

Наверное можно посмотреть в cairo как там оно внутри или типа того.

LINUX-ORG-RU ★★ ()
Ответ на: комментарий от anonymous

Нагружать видеокарту системной задачей вроде отрисовки интерфейса - это рак мозга. Видеокарта нужна чтобы с прикладными видео и 3D работать, а не системе окошки рисовать.

Да ну брось, 2д ускорение появилось в картах в 90ые и очень непривычно когда оно отрыгивает (например в яве на линухах)

rukez ★★★ ()
Ответ на: комментарий от anonymous

Нагружать видеокарту системной задачей вроде отрисовки интерфейса - это рак мозга.

Нагружать процессор графической задачей вроде отрисовки интерфейса - рак жопы. Именно поэтому виндовый гуй с 90х ускорялся на gpu.

devl547 ★★★★★ ()
Ответ на: комментарий от devl547

Че там ускорять то гсподи? Ущербные форточки рендерить просто примитивно это не бг весть какая задача, ты видел visual basic 98? примитивщина, десяток виджетов (тогда это называлось контролами) и это все. А пруф можно?

XoFfiCEr ★★★★ ()
Последнее исправление: XoFfiCEr (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Нет, для этого есть тест трафарета (stensil testure). Или альфа канал в обычной и discard в шейдере.

Это уже применение маски. А рисовать саму маску как? На входе есть набор точек соединённых прямыми линиями или кривыми Безье возможно с самопересечениями. На выходе надо 8 битную маску прозрачности. Например AGG с этим прекрасно и быстро справляется безо всяких триангуляций.

даже если та отобрана у обычной RAM

А так можно?

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

Например AGG с этим прекрасно и быстро справляется безо всяких триангуляций.

Для того что-бы рисовать на ГПУ треугольники вообще не нужны, разве что два полноэкранных если выводить на экран буфер отрисовки. Ты рисуешь шейдерами, то есть вот тебе тексель или группа из них RGBA крась его как хочешь например во вне экранный буффер или сразу в несколько буфферов MRT рендеринг. И всё.

А рисовать саму маску как?

Так же как и всё иное. Например ты можешь на CPU нарисовать маску и отдать её как текстуру в то место где рисуется остальное, ну и применяешь свою одноканальную маску как трафарет, можешь с градациями. Или можно всё делать наоборот.

А так можно?

Это я про хрень когда ГПУ автоматом расширяет свою память за счёт обычной оперативки. А так то в ручную, не уверен что можно. Хотя может в вулканах и/или ГЛ4,6 можно, но сомневаюсь.

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

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

Важно для тебя одно , загружать в ГПУ текстуры можно прям в реалтайме это очень быстро, а вот выгружать из ГПУ это дорого. Так что твой вариант сначала изображение обрабатывается на ЦПУ а затем отправляется как текстура на ГПУ там что надо аппаратно дорисовыввется и отображается (если тебе надо отображать)

Вот тут я просто беру дифы анимации, накладываю их друг на друга для получения следующего кадра (всё это работает чисто на ЦПУ) затем формирую текстуру и отдаю ей на отрисовку примитивному шейдеру. https://www.youtube.com/watch?v=vEN_W6g_CD8 . Если сделать наоборот, тоесть рисовать сначала на ГПУ затем получать результат доработывать на CPU то это будет раз в 20 медленее.

LINUX-ORG-RU ★★ ()
Ответ на: комментарий от LINUX-ORG-RU

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

А без дополнительной текстуры сразу на экран с клиппингом рисовать никак нельзя? Не хочется видеопамять тратить чисто на дубликат буфера в RAM. Этот буфер будет размером с весь экран.

Может можно от-mmap-мть видеопамять и скопировать прямоугольные области клиппинга с помощью CPU или какого-нибудь DMA контроллера?

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от X512

Начну с конца.

Не хочется видеопамять тратить чисто на дубликат буфера в RAM

Если у тебя изначально имеется картинка которая загружается сначала в RAM потом биндится как текстура, после этого бинда она в видеопамяти и из RAM ты её можешь выгружать, она не нужна. ГПУ не умеет рисовать в оперативную память, а если бы умел это было бы медленее чем отрисовать на ГПУ в видеопамяти и выгрузить в оперативку. В этом нет смысла. Разве что память общая как на консолях или портативках. Видеопамять ты займёшь в любом случае. П вот оперативку можешь освобождать спокойно.

Этот буфер будет размером с весь экран.

Не обязательно, если тебе не надо пиксель в пиксель то просто устанавливаешь вьюпорт на любое рахрешение например 200x200 при экране 1920x1080 рисуешь во внеэкранный буфер, затем рисуешь уже на экран выставив вьюпорт на 1920x1080. Да будет мыло =)

А без дополнительной текстуры сразу на экран с клиппингом рисовать никак нельзя?

Можно! И даже часто нужно. Никаких текстур, никаких буферов! Видеопамять чиста, оперативка чиста!… ТОлько вот на CPU ты ничего не получишь ибо ты сразу на экран в таком случае рисуешь.

Ты хочешь гибрид. Твоё это MRT рендеринг (когда можно рисовать одним шейдером сразу в несколько текстур) + отложенный рендеринг (для рисования во внеэкранные буферы (любого нужного тебе размера вне зависимости от разрешения экрана)). Всё. Так же у тебя есть возможность выбора множества формата текстур хоть по 8 бит в 1 канал хоть по 16 в 4 канала хоть 32 бита на 3 канала.

LINUX-ORG-RU ★★ ()
Ответ на: комментарий от X512

Может можно от-mmap-мть видеопамять и скопировать прямоугольные области клиппинга с помощью CPU или какого-нибудь DMA контроллера?

Может и можно, тут я не знаю. Да наверняка можно чё нет то. Только вот это будет прибито гвоздями. Я же говорил о портабельных вариантах. Наверное есть что-то для mesa + linux особенности DMA. Но это уже вне моих знаний. Может кто с эмбедом в этой области возился там такое наверняка вполне себе норм решение. В общем на этом мои полномочия всё =)

LINUX-ORG-RU ★★ ()
Ответ на: комментарий от LINUX-ORG-RU

Опишу задачу точнее. Есть программа, которая рисует на RAM буфере, изменённая часть этого буфера должна загружаться в текстуру, а потом эта текстура и другая 3D графика рисуется на GPU. RAM буфер размером с экран.

Изменение определяется регионом (набором прямоугольников). За пределами региона копировать нельзя, там может быть мусор. Неизменённая часть текстуры в GPU должна сохраняться.

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

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

такое ощущение что про UMA тут никто не слышал

https://www.khronos.org/registry/OpenGL/extensions/INTEL/INTEL_map_texture.txt

anonymous ()
Ответ на: комментарий от X512

Опишу задачу точнее. Есть программа, которая рисует на RAM буфере

Ок, есть картинка например 512x512. Понял.

изменённая часть этого буфера должна загружаться в текстуру

Тоесть не весь буфер становится текстурой? А например есть буфер 512x512 CPU заполняет скажем 64x64 пикселя в каком то месте. И нужно именно это место взять и получить тоже текстуру 64x64 котрая ижу и пойдёт на отрисовку?

Или

Есть текстура 512x512 есть набор прямоугольных областей и нужно весь этот буфер сделать текстурой, но в шейдере забирать только те области что являются обновлёнными?

Ты можешь вычислить на основе этих прямоугольников текстырные координаты, всё что за ними рисоваться не будет. Ты можешь одновременно с буфером те места где ЦПУ нарисовал рисовать ещё в альфа канал и по его значению просто отбрасывать нам где альфа равна нулю например, а остальное рисовать.

Мне кажется тебе никаких DMA и прочих ммапов не надо. Тебе просто нужно подобрать для себя вариант, как удобнее. Покурить OpenGL и поиграться.

По сути ты просто берёшь картинку от ЦПУ отдаёшь её на ГПУ и всё. Единственное что тебе надо просто указать области на вьюпорте, где рисовать, а где нет, тут много вариантов. Просто надо пробовать. Опять же повторюсь ты ещё на этапе цпу в альфа канале картинки в этих твоих прямоугольниках можешь просто писать ТУТ НУЛИК ТУТ НИРИСУИМ, А ТУТ ИДИНИЧКО! ТУТ РИСУИМ! в шейдере ты просто делаешь if(my_tex.a < 1.f) discard; и всё. И никакой магии

Неизменённая часть текстуры в GPU должна сохраняться.

Гпу вообще никак не изменит твою текстуру. Что её изменить она должна быть пришита к рендер буферу в который можно рисовать.

LINUX-ORG-RU ★★ ()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

RAM буфер и текстура имеют одинаковый размер равный размеру всего экрана (не окна), например 1920x1080 (или больше с учётом выравнивания). При обновлении RAM буфер должен скопироваться в текстуру только в указанных местах. Места копирования указываются набором прямоугольников. Вне указанных мест содержимое текстуры должно оставаться от прошлых раз без изменений.

Этот RAM буфер и текстура создаются один раз при запуске и больше не меняются если разрешение экрана не менять.

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от X512

Аааа, тогда просто у тебя будет да дубль в ГПУ на ЦПУ ты рисуешь в прямоугольных областях. А затем зная эти области используешь glCopyImageSubData для копирования этих областей в рендер буфер в который уже будет дорисовывать ГПУ итог просто выводишь на экран. ГПУ ты сообщаешь какие места трогать нельзя через альфа канал картинки. Если нужно можешь перезаписывать иногда (или всегда) изображение из ГПУ в RAM целиком или выборочно через glGetTextureSubImage ибо ты знаешь координаты заранее где у тебя что. Тему можно закрывать =)

А если серьёзно то тут просто нужно искать свой путь решения ,экспериментируя. Удачи. У меня борщ стынет. Мном ном.

LINUX-ORG-RU ★★ ()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от eternal_sorrow

и это плохо

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

izzholtik ★★ ()
Ответ на: комментарий от anonymous

Умеет.

Да, но нельзя просто пулучить указатель на массив и записать туда чиселко на CPU как хочет ТС. А так то да, многие видюшки кушают RAM как свою память только вот там всё огорожено (((

LINUX-ORG-RU ★★ ()
Ответ на: комментарий от LINUX-ORG-RU

Нашёл glTexSubImage2D и GL_PIXEL_UNPACK_BUFFER. По идее через это можно обновлять текстуру без дополнительного буфера в GPU. И без масок/шейдеров/stencil. Надо будет пробовать.

X512 ★★ ()
Последнее исправление: X512 (всего исправлений: 1)