Як OpenGL працює на найнижчому рівні? [зачинено]


84

Я розумію, як писати програми OpenGL / DirectX, і знаю математику та концептуальні матеріали, але це мені цікаво, як зв'язок GPU-CPU працює на низькому рівні.

Скажімо, у мене є програма OpenGL, написана на мові C, яка відображає трикутник і обертає камеру на 45 градусів. Коли я скомпілюю цю програму, чи буде вона перетворена на серію викликів ioctl, а драйвер gpu потім надішле відповідні команди в gpu, де вся логіка обертання трикутника та встановлення відповідних пікселів у відповідному кольорі буде підключена в? Або програма буде скомпільована в "програму gpu", яка завантажується в gpu і обчислює обертання тощо? Або щось зовсім інше?

Редагувати : Через кілька днів я знайшов цю серію статей, яка в основному відповідає на питання: http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part- 1 /


Специфікація OpenGL стверджує, що команди надсилаються в режимі клієнт / сервер. Специфікація занадто широка, щоб визначити конкретну технологію, що використовується реалізаціями OpenGL.
Luca

Відповіді:


86

На це питання майже неможливо відповісти, оскільки OpenGL сам по собі є лише інтерфейсним API, і доки реалізація дотримується специфікації, а результат відповідає цьому, це можна зробити будь-яким способом.

Можливо, запитання було: як працює драйвер OpenGL на найнижчому рівні? Зараз на це знову неможливо відповісти загалом, оскільки драйвер тісно пов’язаний з якоюсь апаратною частиною, яка може знову робити те, що розробник розробив.

Тож питання мало бути: "Як це виглядає в середньому за лаштунками OpenGL та графічної системи?". Давайте подивимось на це знизу вгору:

  1. На найнижчому рівні є якийсь графічний пристрій. На сьогоднішній день це графічні процесори, які забезпечують набір регістрів, що контролюють їх роботу (які регістри точно залежать від пристрою), мають деяку програмну пам'ять для шейдерів, об'ємну пам'ять для вхідних даних (вершини, текстури тощо) та канал вводу-виводу для решти системи, через яку він отримує / надсилає потоки даних та команд.

  2. Графічний драйвер відстежує стан графічних процесорів і всі прикладні програми, що використовують графічний процесор. Також він відповідає за перетворення або будь-яку іншу обробку даних, надісланих програмами (перетворення текстур у піксельний формат, що підтримується графічним процесором, компіляція шейдерів у машинному коді графічного процесора). Крім того, він надає деякий абстрактний, залежний від драйвера інтерфейс для прикладних програм.

  3. Потім є драйверна бібліотека / драйвер OpenGL клієнта. У Windows це завантажується через проксі через opengl32.dll, в системах Unix це знаходиться в двох місцях:

    • Модуль X11 GLX та драйвер GLX, що залежать від драйвера
    • та /usr/lib/libGL.so може містити деякі матеріали, що залежать від драйвера, для прямого візуалізації

    У MacOS X це "OpenGL Framework".

    Саме ця частина перекладає виклики OpenGL, як ви це робите, у виклики специфічних для драйвера функцій у частині драйвера, описаній у (2).

  4. Нарешті, фактична бібліотека API OpenGL, opengl32.dll в Windows та на Unix /usr/lib/libGL.so; це переважно просто передає команди власне реалізації OpenGL.

Те, як відбувається фактичне спілкування, не можна узагальнити:

У Unix підключення 3 <-> 4 може відбуватися або через сокети (так, може, і переходить через мережу, якщо ви цього хочете), або через спільну пам'ять. У Windows бібліотека інтерфейсу та клієнт драйвера завантажуються в адресний простір процесу, тому це не стільки спілкування, скільки прості виклики функцій та передача змінних / покажчиків. У MacOS X це схоже на Windows, тільки в тому, що між інтерфейсом OpenGL та клієнтом драйвера немає розділення (саме тому MacOS X так повільно йде в ногу з новими версіями OpenGL, що завжди потрібно повне оновлення операційної системи, щоб доставити нову рамки).

Зв'язок між 3 <-> 2 може проходити через ioctl, читати / писати або через відображення деякої пам'яті в адресний простір процесу та налаштування MMU для запуску деякого коду драйвера щоразу, коли вносяться зміни до цієї пам'яті. Це дуже схоже на будь-яку операційну систему, оскільки вам завжди потрібно переходити межу ядра / країни користувача: Зрештою, ви проходите певний системний виклик.

Зв'язок між системою та графічним процесором відбувається через периферійну шину та способи доступу, які вона визначає, отже, PCI, AGP, PCI-E тощо, які працюють через порти-входи / виходи, введені / виведені в пам'ять введення-виведення, DMA, IRQ.


1
Цей опис є, мабуть, занадто низьким рівнем і загальним, з дуже мало специфіки OpenGL. Це приблизно стосується будь-якого апаратного компонента, який присутній у комп’ютері.
в.шашенко

1
@ v.shashenko: Ну, звичайно. Незалежно від того, з яким апаратним компонентом ви розмовляєте, вона дотримується цієї загальної схеми. Але OpenGL - це не конкретна частина програмного забезпечення, це лише специфікація, і все, що відповідає специфікації, є допустимою реалізацією. І оскільки врешті-решт реалізація OpenGL розмовляє з графічним процесором, вона приблизно дотримуватиметься того самого сценарію, по якому реалізовані API, що стоять перед апаратним забезпеченням. Неможливо стати більш конкретним, ніж це, оскільки не існує реалізації OpenGL "THE ONE ". І кожна реалізація дещо відрізняється.
datenwolf

1
@ v.shashenko: Якщо ви хочете отримати більше деталей, то вам доведеться запитати про конкретну реалізацію. Наприклад, скажімо, X11 + GLX + DRI → Mesa / AMDGPU → Linux-KMS + DRM (Direct Rendering Manager). І кожен із цих компонентів - досить складний звір із такою кількістю деталей, що ви можете заповнити книги деталями того, як працює кожен компонент. Але це описує реалізацію Linux-AMDGPU. Але Linux + NVidia - це зовсім інший звір. А в Windows знову інакше.
datenwolf

Ви пам'ятаєте, як ми спілкувались довгі кілька днів тому, я просто хотів знати, як з вами зв'язатися, якщо я хочу щось знати.?
Suraj Jain

Те, чого ви навчали того дня, очистило багато моїх сумнівів, зробило і щось нове, але загалом зараз я не вважаю магією те, що ми малюємо вікна та піктограми на екрані.
Suraj Jain

23

Коли я скомпілюю цю програму, чи буде вона перетворена на серію викликів ioctl, а драйвер gpu потім надішле відповідні команди в gpu, де вся логіка обертання трикутника та встановлення відповідних пікселів у відповідному кольорі буде підключена в? Або програма буде скомпільована в "програму gpu", яка завантажується в gpu і обчислює обертання тощо?

Ти не за горами. Ваша програма викликає інсталяційний драйвер клієнта (який насправді не є драйвером, це спільна бібліотека користувацького простору). Це використовуватиме ioctl або подібний механізм для передачі даних драйверу ядра.

Для наступної частини це залежить від обладнання. Старі відеокарти мали так званий "конвеєр із фіксованою функцією". На відеокарті були виділені місця для пам'яті для матриць та спеціальне обладнання для пошуку текстур, змішування тощо. Драйвер відео завантажував би правильні дані та прапори для кожного з цих блоків, а потім встановлював DMA для передачі даних вершин (положення) , колір, координати текстури тощо).

Нове обладнання має процесорні ядра ("шейдери") всередині відеокарти, які відрізняються від вашого центрального процесора тим, що кожен працює набагато повільніше, але їх набагато більше працює паралельно. Для цих відеокарт драйвер готує двійкові програми для запуску на шейдерах графічного процесора.


20

Ваша програма не складена для будь-якого конкретного графічного процесора; він просто динамічно пов'язаний з бібліотекою, яка реалізує OpenGL. Фактична реалізація може передбачати надсилання команд OpenGL на графічний процесор, запуск резервних програмних програм, компіляцію шейдерів та надсилання їх на графічний процесор або навіть використання резервних шейдерів для команд OpenGL. Графічний пейзаж досить складний. На щастя, посилання ізолює вас від більшості складності водіїв, дозволяючи розробникам драйверів вільно використовувати будь-які техніки, які вважають за потрібне.


18

Компілятори / компонувальники C / C ++ роблять рівно одне: вони перетворюють текстові файли в серію кодів операційних кодів, що працюють на центральному процесорі. OpenGL і Direct3D - це просто API C / C ++; вони не можуть магічно перетворити ваш компілятор / компонувальник C / C ++ у компілятор / компонувальник для графічного процесора.

Кожен рядок коду C / C ++, який ви пишете, буде виконаний на центральному процесорі. Дзвінки до OpenGL / Direct3D будуть надходити у бібліотеки C / C ++, статичні чи динамічні, залежно від обставин.

Єдине місце, коли "програма gpu" може увійти в дію, це якщо ваш код явно створює шейдери. Тобто, якщо ви здійснюєте виклики API у OpenGL / D3D, які спричиняють компіляцію та зв'язування шейдерів. Для цього ви (під час виконання, а не під час компіляції C / C ++) або генеруєте, або завантажуєте рядки, які представляють шейдери на певній мові шейдерів. Потім ви просуваєте їх через компілятор шейдерів і отримуєте назад об’єкт у цьому API, який представляє цей шейдер. Потім ви застосовуєте один або кілька шейдерів до певної команди візуалізації. Кожен із цих кроків відбувається явно за вказівкою вашого коду C / C ++, який, як було зазначено раніше, працює на центральному процесорі.

Багато мов шейдерів використовують синтаксис, подібний до C / C ++. Але це не робить їх еквівалентними C / C ++.


Я пізно вивчав opengl і здивувався, чому я бачу всі ці "шейдерні програми" в коді, на який я розглядаю написані як літеральні рядки. Як ви вже сказали, вони компілюються під час виконання. Я бачив кілька прикладів у коді Android opengl es. Потім я побачив також код для iphone. Очевидно, iPhone має чотири векторні процесори, які здатні робити математику з плаваючою комою набагато швидше, ніж це може робити процесор iPhone, - тому ви можете писати ASM як буквальні рядки, щоб їх компілювати під час роботи, щоб використовувати ці процесори замість основного процесора.
eggie5,

1
Більша частина "конвеєра з фіксованою функцією" тепер реалізована набором програм шейдерів за замовчуванням. Вам не потрібно явно просити шейдер, щоб отримати його.
Ben Voigt

1
@Ben Voigt: Правда, але якби вам ніхто не сказав, ви не змогли б відрізнити різницю.
Nicol Bolas

1
Яке може бути розумне ставлення, якби це питання стосувалося не прихованих деталей.
Ben Voigt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.