LINUX.ORG.RU

X11 robustness: DRI3 без аппаратного ускорения

 , , ,

X11 robustness: DRI3 без аппаратного ускорения

7

4

Уже больше 5 лет как использую разные GPU от AMD и сталкиваюсь с разнообразными проблемами, приводящими к его зависанию. К сожалению, в современном линуксовом десктопе, особенно на AMD зависание GPU зачастую не получается обработать прозрачно для софта. В лучшем случае могут попортиться данные, связанные с активными задачами, в худшем - gpu вообще становится неработоспособен до снятия питания (этим грешили некоторые APU на gfx9)

Успешный GPU Reset

Если в случае с неработоспособным GPU другого выхода, кроме как отказ от него нет, дискретные GPU обычно могут успешно пройти сброс.

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

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

Direct Rendering Interface - как это работает

Чтобы вывести текстуру на экран, кто-то должен её разместить в определённом прямоугольнике, с учётом возможного перекрытия другими окнами. Для этого есть разные способы. Где-то раньше применялись маски и color key, где-то просто оверлей - всё это было частью 2D ускорения.

Для indirect рендеринга (AIGLX) всё просто - там рисует opengl на экран сам X11 и может использовать встроенные возможности драйвера по указанию ViewPort. Для direct rendering же всё несколько сложнее.

В DRI2 иксы открывают устройство, создают текстуру для вывода на экран и отдают буфферы на клиент через GEM flink. Так же иксы авторизуют доступ к устройству. Сильно не углублялся в первую версию DRI, но вероятно там вместо gem handle драйвер оперировал физическими адресами напрямую. DRI3 сильно упрощает этот механизм. В эпоху DRI3 у процессов есть доступ к GPU независимо от x-сервера - они могут рендерить всегда. Иксы только реализуют вывод на экран. Причём приложение может как запросить буффер у иксов, так и отправить туда буффер уже отрендеренной текстуры.

Остаётся вопрос - как же эту текстуру поместить в окне?

Ситуация с 2D ускорением

В отличие от других ОС, в linux решили отказаться от 2D ускорения. Это достаточно печально, так как в отличие от opengl композитинга и glamor, 2d ускорение могло бы совсем не зависеть от состояния внутри GPU. Обычно реализации 2D ускорения представляют из себя некоторый stateless command buffer, который ни от каких внешних факторов не зависит. В общем, вероятно, будь у нас 2д ускорение - можно было бы просто перезапустить софт, который привёл к сбою и продолжать работать.

Наиболее активно используемой реализацией 2D ускорения является glamor, работающий поверх opengl. Это чем-то напоминает композитный менеджер, но не умеющий прозрачность и работающий прямо внутри иксов. Сейчас же все xf86-video драйвера, реализующие 2д ускорение, заброшены (intel не работает на последних gpu, nouveau работает даже хуже modesetting и не может в dri3), а разрабы рекомендуют использовать modesetting или вообще wayland. Для amdgpu 2d ускорения и не было никогда, а отключение glamor на amdgpu отключит и dri3. А в wayland такого ускорения вероятно никогда и не будет, т.к добавить его сразу во все реализации, да ещё и для всех GPU практически нереально. Да и ускорять в wayland нечего - приложения уже отдают/получают отрисованные поверхности

Отключение glamor - что произойдёт?

Возможно с этим сталкивались те, кто пробовал использовать xf86-video-intel на последних поколениях, совместимых с i915. Там отключается ускорение и с драйвером iris это может приводить к некорректной отрисовке.

Если включить dri3 «в лоб» - мы увидим opengl текстуры, но они не будут обновляться, так и оставшись на первом кадре. То же самое происходит, если принудительно включить dri3 в коде amdgpu. Причина же в том, что нет возможности прочитать текстуру из CPU напрямую, а при отключении ускорения иксы используют CPU путь.

msdri - патчи, которые так и не смержили

С проблемой столкнулись и на raspberry pi, только там причиной нестабильности драйвера был лимит CMA памяти в 256мб:

https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/945

Реализация GBM на Raspberry PI немного отличается. потому там включение dri3 помогло.

Вероятно, из-за того, что патч не работает на других GPU, его так и не смержили, хотя этот патченный xorg продолжает использоваться в Raspberry OS

TigerVNC - работоспособная, но медленная реализация

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

Out-of-tree драйвер. Эксперименты с GBM

xf86-video-modesetting зачем-то был вмержен в основное дерево Xorg. Цели этого неясны, но работать с in-tree драйвером куда сложнее.

Потому первое что было предпринято - код из ветки с msdri3 был перенесён поверх старого xf86-video-modesetting на autotools. Почему не meson? ИМХО, meson вместо того, чтобы исправить проблемы autotools, перенял их, потому тратить время на то, чтобы с ним разобраться того не стоит. Обе системы сборки максимально плохо выполняют свою задачу и потягаться с ними наверно может только SConstruct.

Что получилось? После пары правок, modesetting собрался. Ещё пара правок и заработал даже glamor.

Но с AccelMethod=msdri3 пусть приложения и запускались, на экране застрявал первый выведенный кадр.

Дальше я начал пытаться вместо GBM пытаться замаппить текстуру напрямую. Если на intel это даже срабатывало (пусть и с неправильным тайлингом), на amdgpu mmap просто падал. Всё верно - текстура не была аллоцирована как CPU_VISIBLE. Да если бы и была, то читалась бы она со скоростью около 50 мегабит в секунду - доступ к некэшированной памяти очень медленный. Так же я попробовал amdgpu-шные ioctl для маппинга, но они тоже не помогли, да и хочется получить универсальное решение. Обновил исходники modesetting до последней версии (позже выяснил, что это было ошибкой) и решил начать делать с нуля.

Доступ к текстурам из CPU - как это работает

Все текстуры представляются на уровне ядра как dmabuf, который передаётся между процессами в виде файлового дескриптора.

Внутри процесса тексстура может быть представлена помимо дескриптора как prime handle и gem flink.

gem flink - тоже глобальный дескриптор текстуры, но привязанный к конкретному GPU - этот способ появился ещё до унификации текстур в dmabuf, в эпоху dri2, а prime handle валиден только для конкретного открытого дескриптора из /dev/dri - то есть это дескриптор уже открытого gem объекта. В dri2 текстуры передавались только от иксов в клиент через gem flink, в dri3 же в обе стороны.

Для унификации и работы с этими самыми gem’ами используется GBM - то есть каждая текстура для нас представляет пару dmabuf fd и непрозрачную структуру gbm_bo. В более новых версиях появились drm modifier, определяющие формат и способы работы с текстурой, но реализовывать их пока не обязательно. Так же GBM реализует аллокацию, импорт, освобождение текстур, но делается всё это не через стандартные DRM API, а через приватные реализации для конкретного GPU.

Конечно использовать GBM - не лучший способ, т.к он всё равно лезет в реализацию opengl (но не использует сам opengl, а оперирует с теми stateless API, что предоставляет drm драйвер).

К сожалению, никаких API для чтения/записи/flush текстур нет, однако если присмотреться к описанию флагов для gbm_bo_map:

/**
 * Flags to indicate the type of mapping for the buffer - these are
 * passed into gbm_bo_map(). The caller must set the union of all the
 * flags that are appropriate.
 *
 * These flags are independent of the GBM_BO_USE_* creation flags. However,
 * mapping the buffer may require copying to/from a staging buffer.
 *
 * See also: pipe_map_flags
 */
enum gbm_bo_transfer_flags {
   /**
    * Buffer contents read back (or accessed directly) at transfer
    * create time.
    */
   GBM_BO_TRANSFER_READ       = (1 << 0),
   /**
    * Buffer contents will be written back at unmap time
    * (or modified as a result of being accessed directly).
    */
   GBM_BO_TRANSFER_WRITE      = (1 << 1),
   /**
    * Read/modify/write
    */
   GBM_BO_TRANSFER_READ_WRITE = (GBM_BO_TRANSFER_READ | GBM_BO_TRANSFER_WRITE),
};

void *
gbm_bo_map(struct gbm_bo *bo,
           uint32_t x, uint32_t y, uint32_t width, uint32_t height,
           uint32_t flags, uint32_t *stride, void **map_data);

Становится понятно, почему трюк из msdri3 не сработал: GBM_BO_TRANSFER_READ_WRITE гарантирует только последовательность read-modify-write.

То есть нам не нужно копировать всю текстуру вручную, достаточно замаппить её через GBM_BO_TRANSFER_READ_WRITE на время операции записи, а так же повторно маппить с GBM_BO_TRANSFER_READ на время чтения.

Первая реализация - заставляем GL/Vulkan рисоваться

Для простоты вместо актуальной версии dri3 я указал самую первую - она требует предоставить всего 3 функции - открытие девноды, импорт внешнего дескриптора как Pixmap и получение дескриптора для существуюшего Pixmap. Для отрисовки opengl приложений обычно хватает первых двух.

Открытие ноды взял как есть из msdri3:

https://gitlab.freedesktop.org/cpmichael/modesetting/-/blob/ms_dri3/hw/xfree86/drivers/modesetting/dri3.c#L278

Остальные изменения из msdri3 пока не пригодились, sync заработал просто включением стандартного SyncShm и этого достаточно для работы приложений

Заставить текстуры обновляться оказалось проще простого - перед чтением текстуры исполняется screen->SourceValidate - в нём можно и подготовить текстуру к чтению. И вот тут то я столкнулся с проблемой. Если я просто заменяю SourceValidate на свой - всё работает как надо и текстура обновляется, но стоит мне вызвать оригинальную функцию - мой враппер перестаёт работать… Но в любом случае, без вызова оригинальной функции текстура уже начала обновляться

Страшные костыли в xfree86 и почему (возможно) разрабы ушли на wayland

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

В конце концов я выяснил, что SourceValidate переписывает адрес на какой-то другой. Гугление привело вот к такому врапперу:

https://cgit.freedesktop.org/xorg/xserver/commit/?id=b89e6dbdfbb50e3b5bc7fcb7eccc397c467c92f8

Чуть позже я выяснил, что остальные врапперы не работают по этой же причине - только вот переписывание их повторно вообще отправляло иксы в вечную рекурсию.

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

Вторая проблема, которая тоже отняла много времени - это сломанный код в апстриме.

Ещё несколько лет назад, чтобы исправить тиринг (которого нет на специализированных дровах вроде amdgpu, но есть на modesetting) в иксы начали внедрять TearFree, попутно ломая внутренние API.

И пусть сам TearFree отключается (мне пришлось его выключить из-за более старой версии xorg в системе), изменения затрагивают и обычный код обновления/vblank…

И судя по всему, даже несмотря на наличие таких прекрасных инструментов, как address sanitizer, эти новые изменения никто не проверял. Когда мне надоело ловить странные зависания и переписывания указателей и я начал запускать xorg с предзагруженным санитайзером, нашлось несколько use-after-free. И пусть мне кое-как удалось их заткнуть (не уверен в корректности логики), я в итоге вернулся на старую ветку, с которой экспериментировал ранее. Да, xf86-video-modesetting в апстриме не готов, не используйте его по возможности.

Тиринг, композитинг, отрисовка

Когда олучилость заставить dri3 поверхности обновляться, столкнулся с другой проблемой - захват окон через xcomposite не работает. Да и вообще, gl окна рисуются с постоянным тирингом, который на софтовой отрисовки вряд ли получится исправить.

С полноэкранными окнами дела обстоят несколько проще - для них предусмотрен механизм PageFlip. Когда окно покрывает всю поврехность экрана. драйвер отправляет его текстуру напрямую в kmsdrm, тем самым минуя программную отрисовку. Это уже было реализовано в msdri3, потому сделал по аналогии - glxgears -fullscreen стал рисоваться без тиринга.

Таким образом, я могу использовать иксовые opengl композиторы и тогда оконные приложения тоже смогут избежать тиринг - надо только починить функцию редиректа окон в composite

В dri3 это отчевает третья функция - pixmap_to_fd - именно она вызывается, когда клиент делает XCompositeNameWindowPixmap чтобы представить текстуру чужого окна в opengl.

Причём мало того, что она должна экспортировать существующую пиксмапу как текстуру, так ещё и держать её в актуальном состоянии.

Тут то мне и потребовалось перегружать всю отрисовку. Чтобы понять, какие функции могут писать пиксмапы, пришлось подсмотреть в код glamor и его врапперы для amdgpu. А так же куча времени потрачена на попытки не переписывать врапперы, но в итоге просто была написана общая функция, возвращающая указатель на момент вызова, на подобии того враппера для SourceValidate:

// call function, but restore original pointer (some methods may replace API)
#define CallWrap(real, saved, func) do { void *tmp = real; real = saved, func, saved = real, real = tmp;} while(0)

Композитинг заработал, но производительность оставляет желать лучшего - в окне терминала konsole (версия из TDE) отрисовка каждого символа дёргает маппинг на запись, а потом обратно на чтение, тем самым вызывая аж 3 копирования тексуры целиком. Это можно попытаться оптимизировтаь, проверяя состояние текстуры и пропуская синхронизации, но здесь возможен и другой путь.

DUMB Buffer и прямой маппинг памяти

В отличие от полученных от приложений текстур, текстуру для иксовых пиксмап выделяет сам иксовый драйвер. И она может быть CPU_VISIBLE и маппиться напрямую, а не через staging buffer. GBM так сделать не позволяет, однако он позволяет импортировать текстуру созданную другим способом. И этот способ есть в KMSDRM устройствоах - DRM_IOCTL_MODE_CREATE_DUMB. Это универсальное API для аллокации текстуры с DMABUF, который можно читать и писать из CPU, но к сожалению только в синхронном режиме. Текстура, выводимая на экран в modesetting без glamor создаётся именно через него.

Первая мысль была - замапить dumb object напрямую для всех текстур, для которых получается pixmap’а… Но не тут то было - когда я это сделал, после запуска композитора иксы зависли в memcpy навечно…

Да, чтение без кэша настолько медленное, что пришлось подключаться по ssh и прибивать иксы удалённо - пускай там и 50 мегабит в секунду, вывод нескольких кадров без композитинга копировал много текстур и застопорился надолго…

К сожалению, DRM api не имеет универсального способа управление кэшем. Есть приватные команды для конкретных GPU, есть кастомные dmabuf драйверы, но через сам drm включить кэширование нельзя.

Потому как обходной способ я стал включать dmabuf только на время записи, для чтения возвращая старый CPU указатель, который иксы обновят при необходимости через SourceValidate.

Производительность, конечно, всё равно неидеальная, konsole всё ещё подтормаживает, но не так дико, как с лишними копирвоаними текстуры.

Ну и конечно не хватает какого-либо ускорения. В идеале хотя бы замаппить текстуры через Vulkan, при необходимости откатываясь на программную реализацию. Даже для маппинга текстур он предоставляет куда большие возможности, чем GBM.

Исходный код получившегося драйвера доступен по ссылке:

https://git.disroot.org/mittorn/xf86-video-modesetting/src/branch/softdri3-old Это вынесенный обратно в out-of-tree modesetting драйвер, поскольку с ним так будет проще работать. Для установки не обязательно ставить в систему, можно установить прямо в хомяк:

./configure --prefix /home/user/xf86-video-modesetting-prefix --with-xorg-module-dir=/home/user/xorg-modules
make install

И прописать в xorg-conf

Section "Files"
        ModulePath "/home/user/xorg-modules"
        ModulePath "/usr/lib64/xorg/modules"
EndSection

Другие изменения

Так как изначальная задача касалась работы в условиях возможного GPU reset, с ним есть и другие нюансы.

К сожалению, GPU reset не всегда происходит успешно. Возможно, из-за багов в прошивке или драйвере SMU, а возможно из-за особенностей конкретного GPU, часто через 3-4 секунды после gpu reset, резетилась железно вся система, если софт продолжал что-то рендерить.

Т.к я использую довольно старое ядро и не хочу пока обновлять, немного попатчил его, чтобы обойти проблему:

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 49f734137f15..ba67bdd65b47 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4794,7 +4795,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
 				if (r)
 					goto out;
 
-				vram_lost = amdgpu_device_check_vram_lost(tmp_adev);
+				vram_lost = false; //amdgpu_device_check_vram_lost(tmp_adev);
 				if (vram_lost) {
 					DRM_INFO("VRAM is lost due to GPU reset!\n");
 					amdgpu_inc_vram_lost(tmp_adev);
@@ -5060,7 +5061,9 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
 	/*
 	 * Special case: RAS triggered and full reset isn't supported
 	 */
-	need_emergency_restart = amdgpu_ras_need_emergency_restart(adev);
+	need_emergency_restart = 0; //amdgpu_ras_need_emergency_restart(adev);
+	if(amdgpu_ras_need_emergency_restart(adev))
+		DRM_WARN("EMERGENCY REBOOT REQUESTED!!!");
 
 	/*
 	 * Flush RAM to disk so that after reboot
@@ -5072,9 +5075,17 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
 		ksys_sync_helper();
 		emergency_restart();
 	}
+	
 
 	dev_info(adev->dev, "GPU %s begin!\n",
 		need_emergency_restart ? "jobs stop":"reset");
+	{
+	char path[] = "/gpu_reset_helper.sh";
+	char *argv[] = {path, NULL};
+	char *envp[] = {NULL};
+	int ret = call_usermodehelper(path, argv, envp, UMH_WAIT_PROC);
+	printk("helper script ret=%d\n", ret);
+	}
 
 	if (!amdgpu_sriov_vf(adev))
 		hive = amdgpu_get_xgmi_hive(adev);

Хотел сначала на pastebin залить, но тот устроил мне DoS атаку через cloudflare и часть статьи была утеряна :(

  • Во-первых, выставляю vram lost всегда в 0, чтобы софт мог продолжать работаь
  • Во-вторых, вызываю usermode helper перед началом резета.

Хелпером является специальный скрипт, который останавливает все процессы и переключает VT. Делался он ещё до софтовой реализации dri3, но с ней работает надёжнее.

Пример скриптов, заточенных под используемый софт

/gpu_reset-helper_sh

#!/bin/sh
echo reset >> /tmp/reset_helper_log
/sbin/start-stop-daemon -S -b -x /emergency-chvt.sh
for p in $(lsof -t /dev/dri/card0 /dev/dri/renderD128); do
case $(readlink /proc/$p/exe) in
/usr/bin/Xorg)
echo skipping Xorg >> /tmp/reset_helper_log
;;
*hlvr*|*.exe|*chamfer*|*monado-service|*wivrn-service|*ovr-utils*)
echo killing $p $(/usr/bin/readlink /proc/$p/exe) >> /tmp/reset_helper_log
kill -9 $p
;;
*)
echo stopping $p $(/usr/bin/readlink /proc/$p/exe) >> /tmp/reset_helper_log
kill -STOP $p
;;
esac
done
echo done >> /tmp/reset_helper_log
sleep 0.5

emergency-chvt.sh

#!/bin/sh
/usr/bin/chvt 1
sleep 0.6
export DISPLAY=:0
for p in $(lsof -t /dev/dri/card0 /dev/dri/renderD128); do
echo $p
if [ $(cat /proc/$p/status|grep State:|cut  -f2 |cut -d ' ' -f1) = "T" ]
then echo T;for wid in $(/usr/bin/xdotool search --pid $p --onlyvisible); do /usr/bin/xdotool windowminimize $wid; done
fi
done

После gpu reset необязательные процессы вроде игор прибиваются, а все остальные останавливаются и по возможности сворачиваются.

Свёрнутые остановленные окна twin (из TDE) автоматически предалгает развернуть с SIGCONT.

После последних изменений в убиваемые приложения скорее всего добавится ещё и композитор.

★★★★★

Проверено: Dimez ()
Последнее исправление: dataman (всего исправлений: 23)
Ответ на: комментарий от mittorn

Я не так давно пробовал пробрасывать RX570 (единственный GPU в системе) в KVM, в macOS. Проброс был успешен, но вот карта далеко не всегда возвращалась хосту. Чаще всего это был тупо черный экран. Также читал про бажный GPU Reset у радеонов, даже какие-то патчи сторонние на ядро накатывал. Толку 0 было. Как я понимаю - даже самые новые радеоны этим страдают?

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

Я не помню ситуацию, чтобы reset не сработал и что-то зависло после того как убрал edid override. Но были ситуации, когда система мгновенно перезагружалась если во время reset продолжать использовать GPU.
Касательно edid_override - это баг связанный с btrfs и гибернацией. amdgpu пытается ерочитать edid как фирмварь из фс во время гибернации, а btrfs оказывается при этом зафриженным, что можеттпривести к дедлоку - вот после того, как его убрал - проблем не было.

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

А смысл? Сервер не портабельный и зависит от специфичного для Haiku функционала ядра. Если его использовать в качестве Wayland сервера, то существенная часть функционала вроде векторной графики останется не востребована.

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

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

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

А статьям он нужен?

Нужен. Особенно для тех, кто читает статьи со смартфона.

Посмотрел на другие статьи, вроде там не было.

Это последние несколько статей вывалили в таком виде.

И я не знаю, как переструктурировать статью, чтобы вынести часть под кат, для меня это сложно

Структура тривиальная, американская: Первый абзац: «В этой статье я расскажу вам о…» и одно-два-три предложения о том, что будет раскрываться ниже. Всё остальное — под кат.

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

отсальные врапперы

это опечатка!

на amdgpu mmap прсото падал

ещё одна.

nouveau работает даже хуже modesetting и не может в dri3

Ну у меня вроде как dri3 можно было на nvc0 включить, но cinelerra-gg артефачила с opengl выводом. На rx550/dri3 не артефачит.

Спасибо за статью и работу, пока моя новая rx550 не висла, но и месячных аптаймов на ней ещё не было ;)

Andrew-R ★★★★★
()

Пердолинг с 3д в линуксе, прям школьные годы вспомнил, хоть что-то не меняется

upcFrost ★★★★★
()
Ответ на: комментарий от Andrew-R

Я скорее всего не разобрался, как этот самый dri3 включить на nouveau. Артефачила она скорее всего из-за комбинации dri3+exa, которая на данный момент сломана. В любом случае, починка exa с dri3 (я не разбирался пока, как он реализован) - это ещё одна задача, которую в иксах надо решить, иначе фактически 2д ускорение недоступно на старых GPU.
А вот rx550 у меня как ни странно висла, но было это на винде.
Кстати говоря, после перехода на softdri3 я ни разу не ловил подобных зависаний на ровном месте. У меня есть подозрение, что виноват в нестабильности был баг в sdma, который в варианте с softdri3 не используется. В общем, amdgpu нужна реализация ускорения с dri3 без glamor, либо нативно на gpu командах, либо на vulkan

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

Увы, я в лучшем случае немного потестировать смогу, сам скорее задаю вопросы чем нахожу ответы. Вулкан вроде как считался более низкоуровневым чем OpenGL т.е. его наверное сложнее в такой отрисовке линий и прямоугольников использовать. Но м.б. сейчас всякие обёртки появились, упрощающие работу с vulkan context?

Edit: https://github.com/jpbruyere/vkvg

но это типа ближе к cairo чем к чему-то совсем низкоуровневому. И Вулкан 1.2 (на мобилках и 1.0 встречается)

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

У меня есть своя максимально тонкая обёртка, которая позволит с минимальным количеством кода запустить растеризатор.
Вот пример кода, рисующего imgui:
https://git.disroot.org/mittorn/vulkan-playground/src/commit/d221e70eac37c31d...
Тут ещё голову над архитектурой поломать. Например, вулкан позволяет заранее записать command buffer'ы и потом отправить их в GPU буквально одним вызовом ioctl. Если придумать, как это задействовать - получится максимально эффективный рендер

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

иногда с экрана ещё и читать надо (скриншотики/скринкасты).

Но да, архитектура даже в деле посылки команд на GPU и работе с паматью (все вот эти режимы кэширования и т д. - побуферно) важна.

Удачи!

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

С чтением с экрана проблем нет - экран это всегда dmabuf, отправляемый в drm, его можно шарить другим процессам.
Если читать непосредственно на cpu - обычно shadow buffer используется, либо можно посмотреть, как сделано в glamor.
Проблема есть с композитингом из-за недоделанного протокола:
Нужно чинить иксы
Тут без доработки протокола починить это без лишних копирований просто невозможно.
Так же по хорошему стоит разобраться, можно ли как-то починить связку exa+dri3, возможно будет достаточно реализовать exa, а не аналог glamor

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

Нужно чинить иксы

Ух сколько там понаписали. Но всё-таки апстрим xorg-а на freedesktop и наверное писать надо туда.

У меня пока rx550 не запустил в прошлом месяце пару дней сидел на встройке rs780L - там дри3 + exa запускалось на x server-е из git, но Opengl client валил сервер ;)

А зачем мне спрашивается дри3 на машине с одной видеокартой? А разработчики месы дефолт при сборке поменяли ..

Andrew-R ★★★★★
()

ttps://git.disroot.org/mittorn/xf86-video-modesetting/src/branch/softdri3-old

у меня кстати не собралось на xserver git commit 37b7ea8f8aaef3efa9d56fb9bc82adeccba02633

driver.c:278:64: error: invalid use of undefined type 'struct OdevAttributes'
  278 |         fd = xf86_platform_device_odev_attributes(platform_dev)->fd;
      |                                                                ^~                          driver.c: In function 'ms_platform_probe':                                                         driver.c:438:65: error: invalid use of undefined type 'struct OdevAttributes'
  438 |     const char *path = xf86_platform_device_odev_attributes(dev)->path;
      |                                                                 ^~

и ещё в этом роде. Но потом есть идея на более старой флэшке попробовать, с более древней Слакварью и Иксами.

Я так понимаю эта штука делает софтово (со стороны cpu) читаемый и записываемый основной буфер,с которого читает контроллер видеовывода на видеокарте, и который может пережить gpu reset - но в него опционально могут рендерить аппаратно через opengl/vilkan соотв. клиенты. Так?

Где-то там на втором винте живёт NetBSD но в ней мой «новый» rx550 не подхватился, хотя pci id вроде в ядре есть. Это я к тому, что по большому счёту Х он не только под Линуксом работает …. и вот как раз dmabuf на netbsd насколько я понимаю до сих пор нет. М.б. и будет когда-нибудь … сейчас там drm/modesetting код из Линукса 5.5 что ли, потом намечается из 6.6 Но dmabuf вроде как со всей vm подсистемой должен взаимодействовать, а то на-ДМА-ешь куда-нибудь мимо назначенного процесса ? И вот как там работает или не работает эта часть я не знаю. Вроде какой-то вариант Вэйланда там запускали, но это не апстрим даже в -current.

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

Там в гитовом xorg'е всё ломают постоянно. Иксы с апстрима литералли неюзабельны и небезопасны из-за use-after-free. Проще сделать нужное на даунстримную ветку, а потом уже с апстримом разбираться. Если кривой код попал в релиз (у меня в gentoo пока не попал) - значит пора заводить баги
На самом деле там читается всё не софтово, а через gbm, который так же работает с gpu. Просто то, как работает gbm, не настолько чувствительео к резету.
Если есть drm, то скорее всего есть и кернел-обжекты, которые по dri3 передаются. А что там под капотом - dmabuf или что-то ещё - не так важно, для юзерспейса это просто дескриптор

mittorn ★★★★★
() автор топика
Последнее исправление: mittorn (всего исправлений: 3)
Ответ на: комментарий от Andrew-R

dri2 плохо ложится на вулкановый свопчейн. Реализовать конечно можно, но костыльно и очень ограничено. Весь смысл в том, чтобы позволить приложению создавать текстуры и отправлять в композитор, а не отдавать весь этот процесс серверу. Я, например, могу со стороны приложения создать dumb buffer и отправлять его в иксы в виде gpu пиксмапы. С dri2 так не выйдет

mittorn ★★★★★
() автор топика

./configure –prefix /home/user/xf86-video-modesetting-prefix –with-xorg-module-dir=/home/user/xorg-modules

xf86-video-modesetting > ./autogen.sh 
autoreconf: export WARNINGS=
autoreconf: Entering directory '.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal -I m4
configure.ac:44: error: must install xorg-macros 1.8 or later before running autoconf/autogen
configure.ac:44: the top level
autom4te: error: /bin/m4 failed with exit status: 1
aclocal: error: /usr/bin/autom4te failed with exit status: 1
autoreconf: error: aclocal failed with exit status: 1

Это нормально? Арч, если что. В системе есть: autoconf, autom4te, autoreconf, automake.

P.S. В упор не вижу configure в директории.

P.P.S. Я нуб.

P.P.P.S. xorg-server-devel нннада?

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

configure тут должен пересоздаваться путем вызова autoreconf, надо смотреть, в чëм именно затык. Но у меня nvidia, а из amd есть только древнючий ноут с Radeon HD2600, 2007 г/в. 64-разрядный арч там ворочается, видно, что 4 ГиБ рамы и 256 МиБ видео ему маловато. Но, если и такое может помочь в тестировании, то…

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

да, devel надо. Я возможно скоро накидаю фиксов под разные версии xorg-server т.к драйвер сильно лезет в нестабильные апишки

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

Вряд ли, здесь же нет никакого ускорения, за исключением полноэкранного режима оно будет создавать тиринг и копировать текстуру на cpu не самым быстрым способом. Если бы не проблема с present, можно было бы использовать его вместе с композитором, но сейчас это тоже крайне неэффективно. Это скорее костыль для тех, кто работает с графикой и сталкивается с gpu reset достаточно часто - такой компромис между полноценно работающим ускорением и отсутствием его вообще

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

Боюсь, что с nouveau пока что всё плохо и лучшее что можно предложить (если не использовать несколько gpu) это ddx драйвер с exa ускорением и dri2.
Работоспособность exa с dri3 это отдельный вопрос:
Нужно чинить иксы (комментарий)
Из разрабов иксов никто не был сильно заинтересован в починке последние 6 лет, потому они скептически относятся к сохранению поддержки этого exa в принципе. Но думаю, если найти решение и заслать патч - всё будет. dri3+exa явно понадобится для вулкана на 700х невидиях, если его всё-таки реализуют.

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

Да, с моей 9500 GT только nouveau теперь, последний драйвер был 340.х, который уже давно не поддерживается. Хотя в Арче есть в AUR и даже работает со старыми ядрами и gcc пониже версии. Но новый жтк4 все больше ломает совместимость (выкинули поддержку EGL, как я понял, хз, не шарю в этом). Короче, даже старые OpenGL игрули с nouveau - это бедапечаль.

ddx драйвер с exa ускорением и dri2

Я хз, что это такое и как его едят :)

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

xf86-video-nouveau.
Но конечно с gtk4 это никак не поможет - его только софтово рисовать

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

Там не EGL, а GLX выкинули. Технически можно написать враппер, реализующий EGL поверх GLX. У проприетарного драйвера были с EGL проблемы.

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

Кстати, по ссылке всё работает с glx при соответствующием gdk рендере и проблема только во фэтпаке, в котором сломан nvidia драйвер (да, если конфигурация отличается от дефолтной, в том числе редкий проприетарный драйвер, flatpak работать не обязан и вероятно не будет)

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

Яснопонятно. Ну заморачиваться не стоит с врапперами. У меня на втором винте стоит необновляемый Арч уже с проприетарным блобом чисто погамать в кваку 1,2,3 и опенарену. Фиг с ним.

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

Но нуво это боль, конечно. Стоит запустить через вайн какую-нибудь старую Zuma Deluxe шарики пострелять, и процы такие оп и на полную лопатят. С блобом такого нет.

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

А ты точно используешь xf86-video-nouveau? nouveau пусть и не очень эффективен, но проц не должен грузить. Может быть, он там вообще не работает?

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

Смотреть в логи в /var/log/Xorg*.log

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

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

Где можно об этом почитать?

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

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

А чем это плохо? Когда-то и мп3 аппаратно декодировали. А потом это ото всюду выпилили, по тому, что и на проце норм. Сейчас с 2д то же самое происходит. А в чём тут проблема?

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

Ну как минимум в том, что кэш процессора не резиновый, а потребляет он при заливке треугодьников больше.
В общем, то, что на процессоре быстрая операция происходит ещё быстрее не показатель. Нагрузите все ядра процессора полезной нагрузкой, а потом уже сравнивайте производительность отрисовки прюмугольников и блита - результат вероятно поменяется.
Для gpu такое тоже справедливо. softdri3 полагается на gbm, который делает команды копирования. И пока gpu не нагружен - всё ок, но как только нагрузка gpu превышает 90% - иксы начинают тормозить нещадно.
Если бы gbm был реализован через sdma, такого бы вероятно не было. Аппаратные ускорители нужны не чтобы ускорить процеса, а чтобы разгрузить общезадачные процессора (cpu/gpu)

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

Аппаратные ускорители нужны не чтобы ускорить процеса, а чтобы разгрузить общезадачные процессора (cpu/gpu)

Но 2д рендеринг и так не должен особо сильно проц нагружать. К тому же в simd он умеет не хуже gpu.

Нагрузите все ядра процессора полезной нагрузкой, а потом уже сравнивайте производительность отрисовки прюмугольников и блита - результат вероятно поменяется.

Но зачем? Ведь как раз исходим из того, что у современного проца дофига ядер, и почему бы ни отдать 1 под 2д рендеринг? Если у вас весь проц и так уже чем-то занят под завязку, то понятное дело, что тогда это не подходит.

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

Сколько L2/L3 кэша в проце? А сколько места занимает полноэкранная пиксмапа? Вот и думай

и почему бы ни отдать 1 под 2д рендеринг?

А зачем отдавать если можно не отдавать?
Вопросы отпадут когда запустишь софт, который упирается в кэш или производительность памяти. Это тот ресурс, который вряд ли выйдет как-то нарастить.
Ещё напомню, что у большинства этих процов, у которых дофига ядер высокая singlecore произврдительность только при нагрузке на эти одно-два и когда ещё пара ядер нагрузятся 2д рендерингом - этот прирост тоже исчезнет.
Ещё хуже ситуация с мобильными устройствами, которые с их 4k+ дисплеями просто начнут греться, тормозить и быстро разряжать батарею

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

Сколько L2/L3 кэша в проце? А сколько места занимает полноэкранная пиксмапа? Вот и думай

Думаю, что в l3 она вполне поместится целиком.

А зачем отдавать если можно не отдавать?

По тому, что среднестатистическая 2д програмулька (например, игра) обычно все ядра всё равно не загружает. У неё, попросту, нет особо никаких больше рассчётов, кроме рендеринга.

Вопросы отпадут когда запустишь софт, который упирается в кэш или производительность памяти. Это тот ресурс, который вряд ли выйдет как-то нарастить.

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

Ещё хуже ситуация с мобильными устройствами, которые с их 4k+ дисплеями просто начнут греться, тормозить и быстро разряжать батарею

Да, аппаратные оптимизации, безусловно, нужны. Надеюсь, что 2д рендеринг на ЦПУ, со временем, будет ни чем не хуже любого другого, даже если сейчас пока проблемы ещё есть.

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

Думаю, что в l3 она вполне поместится целиком.

Но l2/l3 много не бывает и поместившись, она забьёт его большую часть, тем самым вытеснив другое полезное содержимое

По тому, что среднестатистическая 2д програмулька (например, игра) обычно все ядра всё равно не загружает. У неё, попросту, нет особо никаких больше рассчётов, кроме рендеринга.

Многие современные разработчики привыкли считать, что все ресурсы системы предназначены только для их королевы-программы и больше никому...

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

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

Надеюсь, что 2д рендеринг на ЦПУ, со временем, будет ни чем не хуже любого другого, даже если сейчас пока проблемы ещё есть.

И опять ты хочешь пихнуть всю кучу на один аппаратный юнит, который в итоге тогда и станет бутылочным горлышком...

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

Многие современные разработчики привыкли считать, что все ресурсы системы предназначены только для их королевы-программы и больше никому…

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

Существуют, да. Но ты ведь предлагаешь их не использовать, вместо этого отдав всё CPU…

Я как раз и предлагаю это использовать. То есть, выделенный регион оперативки, висящий на отдельном канале контроллера памяти, и на отдельном ядре проца. Чтобы никому не мешать. По л3 кэшу, наверное, всё равно будет мешать, но это терпимо.

но при этом не отказаться от юнитов, ускоряющих те или иные операции.

В проце и так уже есть симд-блоки.

Но в них всё равно есть отдельные transfer’блоки, потому что никто не хочет чтобы вычислительные ядра GPU были заняты копированием,

Так это может быть «сложное» копирование, с наложением масок и всего остального. Симд-блоки лучше подойдут. Мой поинт как раз в том, что современные процы уже располагают всем необходимым, ну а программировать их гораздо проще. К тому же не будет всех этих вопросов с хангом и ресетами. Понятно, что с 3д это не прокатит пока. А с 2д уже можно. А где «можно», там и «нужно».

И опять ты хочешь пихнуть всю кучу на один аппаратный юнит, который в итоге тогда и станет бутылочным горлышком…

А что такое 1 аппаратный юнит? Если по корпусу судить, то да. Но в этом юните много независимых ядер. Для меня, каждое из них - отдельный аппаратный юнит. А бывают и СМП-системы. И если создаётся бутылочное горлышко, так его надо просто устранять. А не говорить «ой, ну ладно, тогда дайте мне крутейший ГПУ для моего лажового 2д рендеринга».

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

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

Не надо применять хай-лоад там. где он не нужен

То есть, выделенный регион оперативки, висящий на отдельном канале контроллера памяти, и на отдельном ядре проца

Всё достаточно сильно взаимосвязанно. Например, заняв эффективное по турбобусту ядро 2д рендерингом ты лишишь его производительности другую задачу, когда этим мог бы заниматься отдельный блок, который к тому же ничего не жрёт.
Прекрасный показатель этого всего - машина с ограниченными ресурсами. Берёшь какой-нибудь комп с корой дуба со встройкой или atom N450 и вкорячиваешь туда windows 10, Он как раз перекидывает 2д композитинг на cpu потому что драйвер не умеет необходимую версию directx. В итоге он не может играть видео на ютюбе с качеством выше чем 360p, хотя на семёрке и под линуксом (с иксами, по крайней мере) всё работает.

В проце и так уже есть симд-блоки.

Мало ли что там ещё есть, это всё расчитано на полезную нагрузку, а не на рендеринг

Так это может быть «сложное» копирование, с наложением масок и всего остального. Симд-блоки лучше подойдут

А GPU не подойдёт? Вроде как он под это расчитан. Если конечно у тебя нет отдельного ускорителя конкретно этой операции. Но да, из-за отсутствия у amd такого блока и вопросов с хангами и резетами я тут как раз вынужден вытаскивать это на CPU. В качестве крайне неэффективного компромиссного решения. И производительность такого решения меня сейчас весьма не радует, но повторюсь, это как раз компромисс из-за проблемы с хангами и резетами, для которой в новое ядро скоро завезут решение, которое, надеюсь, уберёт необходимость подобных костылей...

А что такое 1 аппаратный юнит? Если по корпусу судить, то да. Но в этом юните много независимых ядер

И одно узкое место в виде кэш-когерентного контроллера памяти и общих каналов.
Кстати, даже в случае с APU это может создавать проблемы
Так что отдельный аппаратный юнит, на который можно было бы закинуть 2д команды может быть штукой очень полезной.
Конечно, наименее полезно это на десктопе, но наиболее полезно на каких-нибуль мобильных процессорах, у которых хоть и есть быстрый CPU, но при постоянной работе он начнёт троттлить - он расчитан на короткие нагрузки

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

Берёшь какой-нибудь комп с корой дуба со встройкой или atom N450 и вкорячиваешь туда windows 10,

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

А GPU не подойдёт?

Если речь про видео память - может и подойдёт. А когда речь про регион в оперативке (интегряхи так делали) - он ни чем не лучше проца.

Вроде как он под это расчитан.

Кто вам такое сказал? Ведь известно же, что выкидывают 2д пайплайны из ГПУ. Стало быть, не рассчитан больше. А когда и был рассчитан, то имел для этого отдельные пайплайны, которые у 3д место на кристалле отжерали.

Если конечно у тебя нет отдельного ускорителя конкретно этой операции.

Так есть же: симд-блок. Разумеется, когда речь про оперативку, а не про видео-память, к которой доступ у него не быстрый.

И производительность такого решения меня сейчас весьма не радует,

Вот как раз про это я бы и прочитал статью. Обоснуйте невозможность эффективного 2д рендеринга на проце. Опишите, где затыки, чего надо изменить, чтобы всё летало. Я давно уже гибридными вариантами пользуюсь: рендеринг на проце, но постпроцессинг с масштабированием и фильтрацией - можно на гпу, если он там есть, а нет - так и тоже на проце.

И одно узкое место в виде кэш-когерентного контроллера памяти и общих каналов.

Используйте unganged mode - не будет вам общих каналов. Что там за коллизии по л3 кэшу, и как сильно они влияют - это надо цифрами демонстрировать, а не словами.

но наиболее полезно на каких-нибуль мобильных процессорах, у которых хоть и есть быстрый CPU, но при постоянной работе он начнёт троттлить - он расчитан на короткие нагрузки

Почему у вас 2д рендеринг должен постоянно происходить? Если это гуй, то он рендерится редко. Если игра - ну чё делать, игры высаживают батарейку.

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

SDMA тоже можно перегрузить так что всё будет тормозить.

Там по-хорошему наверное надо делать автоматическое переключение на наиболее свободный вычислительный ресурс.

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

Да, возможно. Но сейчас mesa его практически не использует из-за нестабильности этого блока, где-то был коммит от работника amd, выключающий любые использования sdma.
Одна из причин резета возможно то, что я использовал старый radeonsi, в котором возможно sdma всё ещё используется. Но это надо проводить тесты и смотреть, как будет вести себя sdma, если его использовать для копирования.

mittorn ★★★★★
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.