Головна » як » Як процесор і GPU взаємодіють з комп'ютерною графікою?

    Як процесор і GPU взаємодіють з комп'ютерною графікою?

    Центральний процесор (ЦП) комп'ютера та графічний процесор (GPU) взаємодіють кожен момент часу, коли ви використовуєте комп'ютер, щоб забезпечити чіткий та чуйний візуальний інтерфейс. Прочитайте, щоб краще зрозуміти, як вони працюють разом.

    Фото: sskennel.

    Сьогоднішня сесія запитань та відповідей приходить до нас люб'язно від SuperUser - підрозділу Stack Exchange, групування спільноти веб-сайтів з запитань та відповідей.

    Питання

    Читач SuperUser Sathya поставив питання:

    Тут ви можете побачити скріншот невеликої програми C ++ під назвою Triangle.exe з обертовим трикутником на основі OpenGL API.

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

    Мені було просто цікаво і хотілося дізнатися весь процес від подвійного натискання на Triangle.exe під Windows XP, поки я не побачу трикутник, що обертається на моніторі. Що відбувається, як взаємодіють CPU (який перший обробляє .exe) і GPU (який нарешті виводить трикутник на екрані)?

    Я вважаю, що при відображенні цього обертаючого трикутника в основному використовуються наступні апаратні засоби / програмне забезпечення:

    Устаткування

    • HDD
    • Системна пам'ять (ОЗУ)
    • ЦП
    • Відеопам'ять
    • GPU
    • РК-дисплей

    Програмне забезпечення

    • Операційна система
    • API DirectX / OpenGL
    • Драйвер Nvidia

    Хто-небудь може пояснити процес, можливо, з деякою схемою для ілюстрації?

    Це не повинно бути складним поясненням, яке охоплює кожний крок (припустіть, що виходить за рамки), але пояснення про проміжного ІТ-парень може слідувати.

    Я впевнений, що багато людей, які навіть називають себе ІТ-фахівцями, не могли правильно описати цей процес.

    Відповідь

    Хоча на запитання відповіли декілька членів спільноти, Олівер Зальцбург пішов на додаткову милю і відповів не тільки детальною реакцією, але й відмінною супровідною графікою..

    Зображення від JasonC, доступне як шпалери тут.

    Він пише:

    Я вирішив написати трохи про аспект програмування і про те, як компоненти спілкуються один з одним. Можливо, це проллє світло на певні ділянки.

    Презентація

    Що потрібно, щоб навіть мати одне зображення, яке ви розмістили у своєму питанні, намальованому на екрані?

    Існує багато способів намалювати трикутник на екрані. Для простоти припустимо, що не використовувалися вершинні буфери. (A вершинний буфер- це область пам'яті, в якій зберігаються координати.) Припустимо, що програма просто розповіла конвеєру обробки графіки про кожну одну вершину (вершина - це просто координата в просторі) підряд.

    Але, перш ніж ми можемо намалювати що-небудь, ми спочатку повинні запустити деякі ліси. Ми побачимо чому пізніше:

    // Очистити екран і буфер глибини glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Скидання поточної матриці вигляду моделі glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Малювання за допомогою трикутників glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // Top Of Triangle (Фронт) glVertex3f (0.0f, 1.0f, 0.0f); // Зелений glColor3f (0.0f, 1.0f, 0.0f); // Ліворуч від трикутника (фронт) glVertex3f (-1.0f, -1.0f, 1.0f); // Blue glColor3f (0.0f, 0.0f, 1.0f); // Право з трикутника (фронт) glVertex3f (1.0f, -1.0f, 1.0f); // Виконано малювання glEnd ();

    Так що ж це роблять?

    Коли ви пишете програму, яка хоче використовувати відеокарту, ви зазвичай вибираєте певний інтерфейс для драйвера. Деякі відомі інтерфейси для драйвера:

    • OpenGL
    • Direct3D
    • CUDA

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

    Цей інтерфейс обов'язково дасть вам певні відомості інструменти. Ці інструменти мають форму API, яку можна викликати з вашої програми.

    Цей API - це те, що ми використовуємо у наведеному вище прикладі. Давайте ближче подивимося.

    Ліси

    Перш ніж реально виконати будь-який реальний малюнок, вам доведеться виконати a налаштування. Ви повинні визначити свій вікно перегляду (область, яка буде насправді візуалізована), вашу перспективу ( камери у ваш світ), яке згладжування ви будете використовувати (щоб згладити край вашого трикутника) ...

    Але ми не будемо дивитися на це. Ми просто подивимося на те, що вам доведеться зробити кожен кадр. Люблю:

    Очищення екрана

    Графічний конвеєр не збирається очищати екран для вас кожного кадру. Ви повинні це сказати. Чому? Ось чому:

    Якщо ви не очистите екран, ви просто перетягнути це кожен кадр. Тому ми і називаємо glClear зGL_COLOR_BUFFER_BIT набір. Інший біт (GL_DEPTH_BUFFER_BIT) повідомляє OpenGL, щоб очистити глибинубуфер. Цей буфер використовується, щоб визначити, які пікселі знаходяться перед іншими (або позаду) іншими пікселями.

    Трансформація


    Джерело зображення

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

    Далі ми застосовуємо нашу матрицю Проекція. Це переміщує всі координати таким чином, що вони правильно стоять перед нашою камерою.

    Тепер ми ще раз перетворимося з нашою матрицею Viewport. Ми робимо це для того, щоб масштабувати наше моделі до розміру нашого монітора. Тепер у нас є набір вершин, які готові до візуалізації!

    Ми повернемося до трансформації трохи пізніше.

    Малюнок

    Щоб намалювати трикутник, ми можемо просто наказати OpenGL почати нове список трикутників по телефону glBegin з GL_TRIANGLES постійна.
    Є й інші форми, які ви можете намалювати. Як трикутник або трикутник вентилятора. Це в першу чергу оптимізація, оскільки вони вимагають менше зв'язку між процесором і GPU, щоб намалювати однакову кількість трикутників.

    Після цього ми можемо надати список наборів з трьох вершин, які повинні складати кожен трикутник. Кожен трикутник використовує 3 координати (як ми знаходимося в 3D-просторі). Крім того, я також надаю a колір для кожної вершини, за допомогою викликуglColor3f раніше виклику glVertex3f.

    Відтінок між 3 вершинами (3 кути трикутника) обчислюється OpenGLавтоматично. Він буде інтерполювати колір по всьому лицю багатокутника.

    Взаємодія

    Тепер, коли ви натиснете на вікно. Програма має лише захопити вікно повідомлення, яке сигналізує клік. Потім ви можете запустити будь-яку дію у вашій програмі.

    Це отримує багато важче, якщо ви хочете почати взаємодіяти зі своєю 3D-сценою.

    Спочатку потрібно чітко знати, на якому пікселі користувач натиснув вікно. Потім візьміть свій перспективуз урахуванням, ви можете обчислити напрямок променя, з точки миші клацання миші на вашу сцену. Потім можна обчислити, чи є якийсь об'єкт у вашій сцені перетинається з цим променем. Тепер ви знаєте, якщо користувач натиснув об'єкт.

    Отже, як ви робите це обертання?

    Трансформація

    Мені відомі два типи перетворень, які зазвичай застосовуються:

    • Матрична трансформація
    • Перетворення на основі кістки

    Різниця в тому, що кісток впливають на сингл вершин. Матриці завжди впливають на всі намальовані вершини таким же чином. Давайте розглянемо приклад.

    Приклад

    Раніше ми завантажували наші ідентичність матриці перед нанесенням нашого трикутника. Тотожною матрицею є та, яка просто надає немає трансформації зовсім. Отже, що б я не малював, це впливає лише на мою перспективу. Отже, трикутник взагалі не буде обертатися.

    Якщо я хочу повернути його зараз, я можу або самостійно виконати математику (на процесорі) і просто зателефонувати glVertex3f сінший координати (повертаються). Або я можу дозволити GPU зробити всю роботу, подзвонивши glRotatefперед кресленням:

    // Обертати трикутник на осі Y glRotatef (кількість, 0.0f, 1.0f, 0.0f); 

    суми це, звичайно, просто фіксована величина. Якщо ти хочеш анімувати, вам доведеться відстежувати сумиі збільшуйте його в кожному кадрі.

    Отже, почекайте, що сталося з усіма матричними розмовами раніше?

    У цьому простому прикладі нам не потрібно дбати про матриці. Ми просто називаємо glRotatef і це піклується про все, що для нас.

    glRotate виробляє обертання кут градусів навколо вектора x y z. Поточна матриця (seeglMatrixMode) множиться на матрицю обертання з продуктом, що замінює поточну матрицю, так як ifglMultMatrix було названо з наступною матрицею як аргумент:

    x 2 - 1 - c + cx ⁢ y - 1 - c - z ⁢ sx ⁢ z ⁡ 1 - c + y ⁢ s 0 y ⁡ x - 1 - c + z ⁢ sy 2 - 1 - c + cy ⁢ z 1 - c - x 0 s 0 x ⁢ z ⁡ 1 - c - y ⁢ sy ⁢ z ⁡ 1 - c + x z sz 2 - 1 - c + c 0 0 0 0 1

    Добре, спасибі за це!

    Висновок

    Те, що стає очевидним, - це багато розмов до OpenGL. Але це не говорить нас нічого. Де знаходиться зв'язок?

    Єдине, що нам розповідає OpenGL у цьому прикладі: коли це зроблено. Кожна операція займе певний час. Деякі операції тривають неймовірно довго, інші - надзвичайно швидкі.

    Надсилання вершини до GPU буде так швидко, я б навіть не знав, як це висловити. Надсилання тисяч вершин з центрального процесора до GPU, кожного окремого кадру, швидше за все, не є проблемою.

    Очищення екрана може зайняти мілісекунду або ще гірше (майте на увазі, ви, як правило, маєте лише 16 мілісекунд часу, щоб намалювати кожний кадр), залежно від того, наскільки великим є ваш вигляд. Щоб очистити його, OpenGL має намалювати кожний піксель у кольорі, який потрібно очистити, а це може бути мільйон пікселів.

    Крім цього, ми можемо лише попросити OpenGL про можливості нашого графічного адаптера (максимальна роздільна здатність, максимальне згладжування, максимальна глибина кольору,…).

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

    Потім ми можемо «вивести» результат нашого обчислення (у вигляді нових кольорів) на нову текстуру.

    Ось так ви можете зробити GPU для вас іншими способами. Я припускаю, що CUDA виконує подібний аспект, але я ніколи не мав можливості працювати з ним.

    Ми дійсно лише трохи торкнулися всієї теми. Програмування 3D-графіки - це пекло звіра.


    Джерело зображення


    Маєте щось додати до пояснення? Звучить в коментарях. Хочете прочитати більше відповідей від інших технологічних користувачів Stack Exchange? Перегляньте повний потік обговорення тут.