Bagaimana cara memperbarui buffer kedalaman di GPU?

10

Saat ini saya sedang mencoba mengimplementasikan semacam penyangga dalam perangkat lunak dan saya memiliki masalah besar ketika saya menulisnya. Memiliki satu mutex benar-benar berlebihan. Jadi saya membuat sejumlah mutex sama dengan jumlah utas. Saya mengunci mutex berdasarkan piksel saat ini (pixel_index% mutexes_number) dan ini berfungsi lebih baik, tetapi masih sangat sangat lambat. Dan saya ingin tahu bagaimana hal ini dilakukan dalam GPU nyata? Apakah ada algoritma atau perangkat keras yang pintar menanganinya?

nikitablack
sumber

Jawaban:

9

Perangkat keras yang sangat khusus menanganinya. Strategi tipikal adalah GPU rasterisasi ubin dan menyimpan informasi kedalaman dalam format terkompresi (misalnya persamaan z ketika poligon sepenuhnya menutupi ubin). Ini memungkinkan pengujian di seluruh ubin sekaligus; Trik HW keren lainnya termasuk pengujian kedalaman sebelum pixel shader dijalankan (dengan asumsi kondisi mengizinkan - shader tidak dapat menulis nilai kedalaman). Anda dapat mempertimbangkan sesuatu yang serupa dalam perangkat lunak, seperti memiliki setiap thread "memiliki" subset ubin dan berjalan masing-masing primitif secara mandiri, atau meniru strategi multi-gpu seperti bingkai alternatif atau garis raster alternatif.

Daniel M Gessel
sumber
11

Dalam GPU nyata, alih-alih memiliki beberapa inti yang mencoba membaca / menulis wilayah buffer kedalaman yang sama dan mencoba menyinkronkan keduanya, buffer kedalaman dibagi menjadi ubin (seperti 16 × 16 atau 32 × 32), dan masing-masing ubin ditugaskan untuk satu inti. Inti itu kemudian bertanggung jawab untuk semua rasterisasi di ubin itu: segala segitiga yang menyentuh ubin itu akan dirasterisasi (di dalam ubin itu) oleh inti yang memiliki. Kemudian tidak ada gangguan di antara core, dan tidak perlu bagi mereka untuk melakukan sinkronisasi ketika mengakses bagian dari framebuffer.

Ini menyiratkan bahwa segitiga yang menyentuh beberapa ubin perlu dirasterisasi oleh banyak inti. Jadi, ada langkah redistribusi kerja antara pemrosesan geometri (operasi pada simpul dan segitiga) dan pemrosesan piksel.

Pada tahap geometri, setiap inti dapat memproses sebagian input primitif; kemudian untuk setiap primitif, ia dapat dengan cepat menentukan ubin mana yang sentuhan primitif (ini disebut "rasterisasi kasar"), dan menambahkan primitif ke antrian untuk setiap inti yang memiliki salah satu ubin yang terpengaruh.

Kemudian, pada tahap piksel, masing-masing inti dapat membaca daftar primitif dalam antriannya, menghitung cakupan piksel untuk ubin yang dimiliki inti, dan melanjutkan ke pengujian mendalam, pewarnaan piksel, dan memperbarui framebuffer, tanpa perlu koordinasi lebih lanjut dengan core lainnya.

Nathan Reed
sumber