Bagaimana saya tahu jika saya abstrak API grafik terlalu erat?

23

Saat membuat renderer yang mendukung banyak API grafik, Anda biasanya ingin mengabstraksikan kode Anda di semacam perpustakaan tingkat rendah yang diikat dengan beberapa API grafik seperti OpenGL, Vulkan, D3D11 dan sebagainya;

Mereka bekerja sangat berbeda satu sama lain, sehingga membuat API generik yang baik menjadi penting; Saya telah membaca bahwa Anda biasanya ingin menggunakan "back-end" yang mengimplementasikan fungsionalitas dasar untuk setiap API yang ingin Anda dukung, dan "front-end" yang digunakan oleh programmer untuk menggambar hal-hal di layar.

Bagaimana saya tahu kalau saya membuat abstraksi yang terlalu ketat?

Gabriele Vierti
sumber
5
Apakah Anda 100% yakin bahwa pembungkus Anda + Vulkan atau D3D11 lebih cepat daripada hanya menggunakan OpenGL?
Mooing Duck
@Moing Duck jika digunakan dengan benar, ya.
Gabriele Vierti
4
Saya akan sangat meragukannya. Sebagian besar keuntungan dalam Vulkan berasal dari tingkat yang sangat rendah dan melakukan berbagai hal dengan cara yang sangat khusus dan spesifik. Sesuatu yang cukup umum untuk melakukan hal yang sama dengan mulus di OpenGL atau D3D hampir pasti tidak dapat melakukannya. Mengimplementasikan kembali hal-hal yang sama seperti yang dilakukan OpenGL (seperti banyak tutorial Vulkan, ironisnya) menghasilkan 99,99% kinerja yang sama, dengan 20 kali pekerjaan.
Damon
@Damon benar, tetapi API yang lebih baru dirancang secara khusus (dan tidak diadaptasi seperti OpenGL) untuk bekerja pada GPU modern; berbicara tentang Vulkan, Anda dapat cukup banyak menggunakan API yang sama pada setiap platform yang didukung, sebaliknya untuk OpenGL, di mana Anda perlu menggunakan "Sistem Tertanam" versi. Selain lebih sedikit cpu overhead dan fitur mewah, kami tidak memiliki banyak, tetapi di masa depan kami mungkin memiliki beberapa teknik yang cukup mengejutkan yang dapat berjalan lebih cepat menggunakan Vk atau D3D12 daripada OGL atau D3D11
Gabriele Vierti

Jawaban:

44

Pertama-tama, pertimbangkan apakah benar-benar layak untuk mendukung lebih dari satu API grafik. Hanya menggunakan OpenGL akan mencakup sebagian besar platform dan akan "cukup baik" untuk semua kecuali proyek yang paling ambisius secara grafis. Kecuali jika Anda bekerja untuk studio game yang sangat besar yang mampu menenggelamkan beberapa ribu orang-jam ke dalam implementasi dan pengujian beberapa rendering backend dan kecuali ada beberapa fitur spesifik DirectX atau Vulcan yang benar - benar ingin Anda pamerkan, biasanya tidak sepadan dengan kerumitannya. . Terutama mengingat bahwa Anda dapat menyimpan banyak pekerjaan dengan menggunakan lapisan abstraksi yang dibuat orang lain (perpustakaan pihak ke-3 atau mesin game).

Tapi mari kita asumsikan bahwa Anda sudah mengevaluasi opsi Anda dan sampai pada kesimpulan bahwa itu layak dan layak waktu untuk menggulung pilihan Anda.

Lalu juri utama arsitektur perangkat lunak lapisan abstraksi Anda adalah programmer front-end Anda.

  • Apakah mereka dapat mengimplementasikan sistem game yang ingin mereka terapkan tanpa harus bertanya-tanya tentang detail level rendah?
  • Apakah mereka dapat sepenuhnya mengabaikan bahwa ada lebih dari satu API grafis?
  • Apakah secara teori dimungkinkan untuk menambahkan backend rendering lain tanpa mengubah salah satu kode front-end?

Jika demikian, Anda berhasil.

Philipp
sumber
2
Satu saran tambahan: apakah perlu menekankan bahwa tujuannya adalah untuk mencapai tujuan di poin-poin dengan tingkat upaya minimal - untuk mencapai target dan tidak melangkah lebih jauh? Kalau tidak, masing-masing dari ini dapat berubah menjadi lubang kelinci untuk pengembang khas yang (termasuk saya) sering tidak tahu kapan harus meninggalkan cukup baik sendirian. :) Dan juga bahwa satu-satunya cara yang dapat diandalkan untuk menilai kesuksesan adalah dengan mengembangkan dan menguji API secara berulang dengan pengguna yang sebenarnya ; tidak mungkin untuk menebak secara akurat, dan mengarah ke skenario lubang kelinci rekayasa berlebihan.
bob
5
Saya akan menambahkan bahwa, jika Anda benar-benar harus mendukung banyak pustaka grafis, hampir pasti ada pustaka yang dapat melakukan semua yang Anda butuhkan, jadi meskipun demikian Anda benar - benar tidak boleh membuat pustaka Anda sendiri. (Tentu saja, ada pengecualian, tetapi jika Anda tidak cukup berpengalaman untuk bertanya "seberapa ketat abstraksi yang harus saya buat" Anda mungkin tidak mengerjakan proyek yang mengharuskan Anda melakukannya)
Mendanai Gugatan
Saya bukan pengembang grafis, tetapi melihat kerangka kompatibilitas dari sejarah database dan OS, saya akan menambahkan bahwa hampir pasti tidak layak untuk membuat kerangka umum Anda sendiri . Kerangka kerja ini hampir pasti harus mengorbankan kinerja untuk kompatibilitas, yang mungkin berarti Anda tidak bisa berbuat banyak dengan fitur-fitur khusus itu. Kerangka kerja yang ada hampir pasti untuk menangani masalah-masalah itu dengan lebih baik karena penggunaan yang lebih luas. Sekarang, jika Anda memiliki anggaran besar yang Anda uraikan dan ingin membangun kerangka kerja khusus (misalnya untuk satu game atau seri), itu mungkin lebih bisa dilakukan.
jpmc26
6

Mulailah dengan mengidentifikasi apa yang sebenarnya Anda butuhkan dari bagian "wrapper" dari API. Ini umumnya sangat, sangat sederhana: Anda memerlukan sumber daya dasar (buffer, shader, tekstur, keadaan pipa) dan cara untuk menggunakan sumber daya tersebut untuk membangun bingkai dengan mengirimkan beberapa panggilan draw.

Cobalah untuk menjaga logika tingkat tinggi apa pun dari bagian pembungkus API. Jika Anda menerapkan teknik penyisihan adegan pintar di bagian API ini, nah sekarang Anda berada di hook untuk menduplikasi logika itu di semua implementasi backend. Itu banyak usaha ekstra, jadi tetap sederhana. Manajemen adegan harus menjadi bagian dari bagian API tingkat tinggi yang menggunakan bungkus daripada menjadi bagian dari bungkus itu sendiri.

Pilih target yang akan Anda dukung dan pahami. Sulit untuk menulis pembungkus yang layak untuk "segalanya," dan Anda mungkin tidak perlu (bisa dibilang Anda tidak perlu menulis satu bungkus pun, seperti yang disebutkan dalam jawaban Philipp ). Hampir tidak mungkin untuk menulis pembungkus yang layak jika Anda tidak tahu API yang akan Anda bungkus.

Evaluasi keadaan API Anda secara teratur. Seharusnya secara umum memiliki area permukaan yang lebih kecil daripada API yang dibungkus di bawahnya; jika Anda menemukan diri Anda membuat jenis pembungkus satu-ke-satu untuk setiap struktur D3D atau setiap panggilan fungsi OpenGL Anda mungkin membelok di luar jalur.

Lihatlah pekerjaan apa yang telah terjadi sebelumnya. Sokol dan BGFX adalah API yang menyediakan tingkat agnostisisme yang mungkin berguna bagi Anda, dan relatif mudah dipahami (terutama yang pertama).

Josh
sumber
3

Poin lain yang belum disebutkan yang harus Anda pertimbangkan adalah apa tujuan kinerja Anda. Jika tujuan Anda adalah memiliki pustaka grafis yang akan menghasilkan kinerja yang baik dari platform perangkat keras yang murah, tetapi juga dapat digunakan pada berbagai platform yang jauh lebih kuat tetapi menggunakan API yang berbeda, mungkin masuk akal untuk merancang API Anda di sekitar abstraksi apa pun yang digunakan secara asli pada platform di mana kinerja merupakan masalah. Bahkan jika hal ini menyebabkan penurunan kecepatan 50% pada platform yang lebih kuat, mungkin layak jika memungkinkan peningkatan kecepatan 20% pada platform di mana kinerja paling penting.

supercat
sumber