Як оновлення буфера глибини працює в GPU?


10

Зараз я намагаюся реалізувати якийсь буфер глибини в програмному забезпеченні, і у мене є величезна проблема, коли я пишу на це. Наявність одного мютексу - це абсолютна надмірна кількість. Так я створив кількість мутексів, рівних кількості потоків. Я блокую мутекс на основі поточного пікселя (pixel_index% mutexes_number), і це працює краще, але все ще дуже повільно. І мені цікаво, як це робиться в реальному GPU? Чи є розумний алгоритм чи апаратне забезпечення справляється з ним?

Відповіді:


9

Високоспеціалізоване обладнання обробляє це. Типова стратегія полягає в тому, щоб графічний графічний процесор розрізував плитки та зберігав інформацію про глибину у стислих форматах (наприклад, z-рівняння, коли багатокутник повністю покриває плитку). Це дозволяє перевірити одразу всю плитку; інші круті хитрості HW включають тестування глибини перед запуском піксельної шейдера (якщо умови дозволяють - шейдер не може записати значення глибини). Ви можете розглянути щось подібне в програмному забезпеченні, наприклад, щоб кожен потік "мав" підмножину плиток і ходив кожен примітив самостійно, або імітував стратегії мульти-gpu, такі як альтернативні кадри або альтернативні растрові лінії.


11

У реальному графічному процесорі, замість того, щоб мати декілька ядер, які намагаються читати / записувати одну і ту ж область буфера глибини і намагатися синхронізуватись між ними, буфер глибини поділяється на плитки (наприклад, 16 × 16 або 32 × 32), і кожен плитка присвоюється одному ядру. Тоді це ядро ​​відповідає за всю растерізацію в цій плитці: будь-які трикутники, які торкаються цієї плитки, будуть растеризовані (в межах цієї плитки) власним ядром. Тоді між ядрами немає перешкод і немає необхідності синхронізувати їх при доступі до їх частини фреймбуфера.

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

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

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

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