Skip to content

Проброс видеокарты

Work In Progress

Этот раздел находится на стадии написания.

Пока что на этой странице рассмотрен только случай с 2 GPU от AMD.

Список задач по этой странице:

  • Начало
  • Проброс видеокарты
    • AMD
      • 2 ГП
      • 1 ГП
    • Nvidia
      • 2 ГП
      • 1 ГП
    • Intel
      • 2 ГП
      • 1 ГП
  • Финальные настройки для 2 ГП

Что это

Это когда виртуальная машина получает прямой доуступ к видеокарте. Если во время работы такой виртуалки подключить к проброшенной видеокарте HDMI кабель - можно будет увидеть экран виртуалки 🤯.

Зачем это надо

У тебя виртуалка будет юзать физичную видюху, это быстрее любой 3D-акселерации. Можно в игры играть хз.

Начало

Warning

Гайд написан с учетом, что ты юзаешь Grub в качестве загрузчика.

Проброс видеокарты возможен как и с двумя видеокартами, так и с одной. Для разных производителей чипа (Nvidia, AMD, Intel) инструкции будут немного отличатся.

  1. Проверка поддержки IOMMU

    Чтобы пробросить ГП, тебе нужно загуглить, поддерживает ли твоя материнская плата IOMMU. Если коротко, то IOMMU даёт возможность линуксу управлять PCI устройствами напрямую.

    Если твоя материнская плата поддерживает IOMMU - Включи её, в ином случае проброс видеокарты невозможен.

  2. Настройка загрузчика

    Открываем файл /etc/default/grub

    Дописываем аргументы для ядра в GRUB_CMDLINE_LINUX_DEFAULT:

    Для процессора AMD:

    1
    amd_iommu=on iommu=pt
    
    Для процессора Intel:
    1
    intel_iommu=on iommu=pt
    

    Seealso

    Так же можно дописать video=efifb:off - это может помочь некоторые проблемы, например, если после перезапуска виртуалки проброшенная видюха не хочет запускаться. Если видеокарта одна, то это может помочь вернуть линуксу доступ к ней, чтобы он мог использовать её для рендера.

    Билдим конфиг grub:

    1
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    

    Ребутимся.

  3. Проверка IOMMU групп

    Теперь нам нужно посмотреть группы IOMMU:

    1
    2
    3
    4
    5
    for d in $(find /sys/kernel/iommu_groups/ -type l | sort -n -k5 -t/); do 
        n=${d#*/iommu_groups/*}; n=${n%%/*}
        printf 'IOMMU Group %s ' "$n"
        lspci -nns "${d##*/}"
    done;
    

    Этот скрипт выдаст тонну IOMMU групп вида:

    1
    IOMMU Group 21 25:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Cape Verde XT [Radeon HD 7770/8760 / R7 250X] [1002:683d] (это моя видеокарта типо)
    

    Здесь надо будет найти видеокарту, которую будем пробрасывать и смотреть какие устройства находятся с ней в одной группе. У видеокарт может быть в одной группе 2 устройства - сама видеокарта и её звук (да, видеокарты умеют передавать звук под HDMI).

    Если в одной IOMMU группе с видеокартой есть ещё какие-то левые утройства - это проблема. Ведь при пробросе видеокарты нужно пробрасывать все устройства с одной IOMMU группы.

    Решение проблемы с левыми устройствами

    Чтобы решить эту проблему, у вас должно стоять ядро с поддержкой acs override patch(например, linux-zen)

    Добавляем в аргументы запуска ядра это:

    1
    pcie_acs_override=downstream,multifunction
    
    Этот аргумент заставит ядро разбить как можно сильнее IOMMU устройства на группы, так что лишние устройства будут в других группах.

    Warning

    Несмотря на то, что звук видеокарты и сама видеокарта теперь находятся в разных группах, эти 2 группы нужно будет пробросить

    Билдим конфиг grub:

    1
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    

    Ребутимся.

Дальше гайд для разных кейсов будет разный.

Проброс видеокарты

AMD

2 ГП

Далее нам надо запретить линуксу загружать дефолтный драйвер на нашу пробрасываемую видеокарту, поэтому мы заставим линукс загружать в неё "заглушку"(vfio-pci) 1. Устанавливаем gpu-passthrough-manager AUR

1
2
3
4
5
Запускаем его.

При первом запуске он сгенерирует какие-то конфиги и попросит ребутнутся - ребутимся.

После ребута запускаем его снова и выбираем из списка видеокарту, которую нужно пробросить, жмём `Load VFIO`, после снова соглашаемся на ребут.
  1. Открываем virt-manager, заходим в настройки своей виртуальной машины, жмём Добавить оборудование -> PCI-устройство узла -> ищем в списке свою видеокарту, добавляем её. Эти же манипуляции проводим с её звуком.

Готово!

1 ГП

🚧 WIP 🚧

Nvidia

🚧 WIP 🚧

Intel

🚧 WIP 🚧

Финальные шаги для кейса с 2 ГП

Когда видеокарта проброшена, нужно как-то выводить изображение с неё, для этого можно воспользоваться looking-glass AUR. Это такая штука, которая должна автоматически запускаться с виртуальной ОС, будет передавать изображение, а так же предостовлять управление.

Warning

В этой часте гайда будет совместима ТОЛЬКО с Windows. Linux Looking Glass пока адекватно не поддерживает.

Эта часть гайда буквально взята с сайта Looking Glass'a, мы просто немного перефразируем часть ихней документации и после кинем вас к ним xd

  1. Считаем объём памяти максимального желаемого разрешения по формуле:

    \[ \begin{align}\begin{aligned}\text{WIDTH} \times \text{HEIGHT} \times \text{BPP} \times 2 = \text{frame size in bytes}\\\text{frame size in bytes} \div 1024 \div 1024 = \text{ frame size in MiB}\\\text{frame size in MiB} + 10 = \text{ required size in MiB}\\2^{\lceil \log_2(\text {required size in MiB}) \rceil} = \text{ total MiB}\end{aligned}\end{align} \]

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

    Вот пример для FHD SDR:

    \[ \begin{align}\begin{aligned}1920 \times 1080 \times 4 \times 2 = 16,588,800 \text{ bytes}\\16,588,800 \div 1024 \div 1024 = 15.82 \text{ MiB}\\15.82 \text{ MiB} + 10 \text{ MiB} = 25.82 \text{ MiB}\\2^{\lceil \log_2(25.82) \rceil} = 32 \text { MiB}\end{aligned}\end{align} \]

    Вот таблица уже рассчитанных значений:

    Разрешение SDR HDR
    1920x1080 (1080p) 32 64
    1920x1200 (1200p) 32 64
    2560x1440 (1440p) 64 128
    3840x2160 (2160p/4K) 128 256
  2. в virt-manager открываем нашу виртуалку -> Обзор -> XML. В Тег <devices> дописываем:

    1
    2
    3
    4
    5
    <shmem name="looking-glass">
        <model type="ivshmem-plain"/>
        <size unit="M">КОЛИЧЕСТВО ПАМЯТИ ПОСЧИТАННОЕ РАНЕЕ</size>
        <address type="pci" domain="0x0000" bus="0x10" slot="0x01" function="0x0"/>
        </shmem>
    

  3. Дальше следуй официальным инструкциям