ฉันจะรู้ได้อย่างไรว่าฉันสรุปกราฟิก APIs แน่นเกินไป


23

เมื่อสร้าง renderer ที่รองรับ API กราฟิกหลายตัวโดยทั่วไปคุณต้องการทำให้โค้ดของคุณในไลบรารีระดับต่ำที่เชื่อมโยงกับ API กราฟิกบางประเภทเช่น OpenGL, Vulkan, D3D11 และอื่น ๆ

พวกเขาทำงานแตกต่างกันมากดังนั้นการสร้าง API ทั่วไปที่ดีจึงเป็นสิ่งจำเป็น ฉันได้อ่านแล้วว่าโดยปกติคุณจะต้องการใช้ "แบ็คเอนด์" ที่ใช้ฟังก์ชั่นพื้นฐานสำหรับแต่ละ API ที่คุณต้องการสนับสนุนและ "ฟรอนต์เอนด์" ซึ่งเป็นสิ่งที่โปรแกรมเมอร์ใช้ในการวาดเนื้อหาบน จอภาพ

ฉันจะรู้ได้อย่างไรว่าฉันทำสิ่งที่เป็นนามธรรมมากเกินไป?


5
คุณแน่ใจ 100% ว่า wrapper + Vulkan หรือ D3D11 ของคุณเร็วกว่าการใช้ OpenGL หรือไม่
Mooing Duck

@Minging Duck หากใช้อย่างถูกต้องใช่
Gabriele Vierti

4
ฉันจะสงสัยอย่างจริงจังว่า ผลกำไรส่วนใหญ่ใน Vulkan มาจากการที่อยู่ในระดับต่ำมากและทำสิ่งต่าง ๆ ในรูปแบบเฉพาะเจาะจง บางสิ่งที่ธรรมดาพอที่จะทำเช่นเดียวกันได้อย่างราบรื่นใน OpenGL หรือ D3D แทบจะไม่สามารถทำได้ การนำสิ่งที่เหมือนกันกลับมาใช้ใหม่อย่างที่ OpenGL ทำ (เช่นเดียวกับการสอน Vulkan หลายอย่างที่ทำในเชิงประชดประชัน) ให้ผลการทำงานที่เหมือนกัน 99.99% โดยมีงาน 20 เท่า
Damon

@Damon นั้นถูกต้อง แต่ API ที่ใหม่กว่านั้นได้รับการออกแบบมาเป็นพิเศษ(และไม่ได้ดัดแปลงเช่น OpenGL) เพื่อทำงานกับ gpus สมัยใหม่ การพูดของ Vulkan คุณสามารถสวยมากใช้ API เดียวกันบนทุกแพลตฟอร์มที่สนับสนุนหัวรั้นไปใช้งาน OpenGL ที่คุณจำเป็นต้องใช้ "ระบบสมองกลฝังตัว" รุ่น นอกเหนือจากค่าใช้จ่ายซีพียูน้อยกว่าและคุณสมบัติแฟนซีเราไม่ได้มีมาก แต่ในอนาคตเราอาจมีเทคนิคที่น่าแปลกใจบางอย่างที่อาจทำงานได้เร็วขึ้นโดยใช้ Vk หรือ D3D12 แทนที่จะเป็น OGL หรือ D3D11
Gabriele Vierti

คำตอบ:


44

ก่อนอื่นให้พิจารณาว่ามันคุ้มค่าจริงหรือไม่ที่จะรองรับ API กราฟิกมากกว่าหนึ่ง เพียงแค่ใช้ OpenGL จะครอบคลุมแพลตฟอร์มส่วนใหญ่และจะ "ดีพอ" สำหรับทุกคน แต่เป็นโครงการที่ท้าทายความสามารถทางกราฟิคมากที่สุด ถ้าคุณทำงานสำหรับเกมสตูดิโอขนาดใหญ่มากซึ่งสามารถที่จะจมลงไปหลายพันคนชั่วโมงในการดำเนินการและการทดสอบแบ็กเอนด์การแสดงผลหลายและถ้ามีบาง DirectX หรือ Vulcan เฉพาะคุณสมบัติที่คุณจริงๆต้องการที่จะแสดงออกก็มักจะไม่คุ้มค่าการรบกวน . โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าคุณสามารถบันทึกงานจำนวนมากได้โดยใช้เลเยอร์สิ่งที่เป็นนามธรรมซึ่งบุคคลอื่นสร้างขึ้น (ไลบรารีบุคคลที่สามหรือเครื่องมือสร้างเกม)

แต่สมมติว่าคุณได้ประเมินทางเลือกของคุณแล้วและได้ข้อสรุปว่ามันเป็นไปได้และคุ้มค่ากับเวลาที่คุณจะใช้เอง

จากนั้นผู้ตัดสินหลักของสถาปัตยกรรมซอฟต์แวร์ของเลเยอร์นามธรรมของคุณคือโปรแกรมเมอร์ส่วนหน้าของคุณ

  • พวกเขาสามารถใช้ระบบเกมที่พวกเขาต้องการนำไปใช้โดยไม่ต้องสงสัยเกี่ยวกับรายละเอียดระดับต่ำหรือไม่?
  • พวกเขาสามารถเพิกเฉยได้อย่างสมบูรณ์ว่ามี API กราฟิกมากกว่าหนึ่งรายการหรือไม่
  • มันจะเป็นไปได้ในทางทฤษฎีหรือไม่ที่จะเพิ่มแบ็กเอนด์การเรนเดอร์ตัวอื่นโดยไม่ต้องเปลี่ยนรหัสส่วนหน้า?

ถ้าเป็นเช่นนั้นคุณประสบความสำเร็จ


2
ข้อเสนอแนะเพิ่มเติมหนึ่งข้อ: มันคุ้มค่าหรือไม่ที่เน้นว่าเป้าหมายคือการบรรลุเป้าหมายในสัญลักษณ์แสดงหัวข้อย่อยด้วยระดับความพยายามน้อยที่สุด - เพียงแค่ไปถึงเป้าหมายและไม่ไปต่อ ไม่เช่นนั้นแต่ละคนสามารถกลายเป็นหลุมกระต่ายสำหรับนักพัฒนาทั่วไปที่ (รวมตัวเอง) มักจะไม่รู้ว่าเมื่อใดที่ต้องออกจากตัวคนเดียวที่ดีพอ :) และวิธีเดียวที่เชื่อถือได้ในการตัดสินความสำเร็จคือการพัฒนาและทดสอบ API ซ้ำ ๆ กับผู้ใช้จริง มันเป็นไปไม่ได้ที่จะคาดเดาได้อย่างถูกต้องและนำไปสู่สถานการณ์จำลองของหลุมกระต่ายเกี่ยวกับงานด้านวิศวกรรม
บ๊อบ

5
ฉันจะเพิ่มว่าถ้าคุณจริงๆไม่ได้ให้การสนับสนุนห้องสมุดกราฟิกหลายมีเกือบแน่นอนปิด -the-shelf หนึ่งที่ทำทุกอย่างที่คุณจำเป็นต้องดังนั้นแม้แล้วคุณจริงๆไม่ควรม้วนของคุณเอง (แน่นอนว่ามีข้อยกเว้น แต่ถ้าคุณไม่มีประสบการณ์เพียงพอที่จะถามว่า "ฉันควรทำนามธรรมให้รัดกุมแค่ไหน" คุณอาจไม่ได้ทำงานในโครงการที่กำหนดให้คุณต้องทำ)
คดีของกองทุนโมนิก้า

ฉันไม่ใช่นักพัฒนากราฟิก แต่มองที่กรอบความเข้ากันได้จากประวัติของฐานข้อมูลและระบบปฏิบัติการฉันจะเพิ่มว่ามันไม่คุ้มค่าเลยที่จะสร้างกรอบงานทั่วไปของคุณเอง กรอบจะต้องเสียสละประสิทธิภาพเพื่อความเข้ากันได้ซึ่งอาจหมายความว่าคุณไม่สามารถทำอะไรกับคุณสมบัติพิเศษเหล่านั้นได้มากนัก เฟรมเวิร์กที่มีอยู่เกือบจะแน่ใจว่าจะจัดการกับปัญหาเหล่านั้นได้ดีขึ้นเนื่องจากการใช้งานที่กว้างขึ้น ทีนี้ถ้าคุณมีงบประมาณมหาศาลคุณต้องอธิบายและต้องการสร้างเฟรมเวิร์กเฉพาะ (พูดสำหรับเกมหรือซีรีส์หนึ่ง) นั่นอาจเป็นไปได้มากกว่า
jpmc26

6

เริ่มต้นด้วยการระบุสิ่งที่คุณต้องการจากส่วน "wrapper" ของ API โดยทั่วไปแล้วง่ายมาก: คุณต้องการทรัพยากรพื้นฐาน (บัฟเฟอร์, เงา, พื้นผิว, สถานะไปป์ไลน์) และวิธีการใช้ทรัพยากรเหล่านี้เพื่อสร้างเฟรมโดยส่งการเรียกวาดบางอย่าง

พยายามป้องกันตรรกะระดับสูงออกจากส่วนที่ห่อหุ้มของ API หากคุณใช้เทคนิคการคัดสรรฉากที่ชาญฉลาดในส่วนนี้ของ API ตอนนี้คุณก็พร้อมที่จะทำซ้ำตรรกะนั้นในการปรับใช้แบ็กเอนด์ทั้งหมด นั่นเป็นความพยายามพิเศษมากมายดังนั้นโปรดทำให้ง่าย การจัดการฉากควรเป็นส่วนหนึ่งของส่วนระดับสูงของ API ที่ใช้ wrapper แทนที่จะเป็นส่วนหนึ่งของ wrapper

เลือกเป้าหมายที่คุณจะสนับสนุนและเข้าใจพวกเขา มันยากที่จะเขียนคำว่า "ทุกอย่าง" ที่ดีและคุณอาจไม่จำเป็นต้องทำ (คุณไม่จำเป็นต้องเขียนกระดาษห่อเดียวอย่างใดอย่างหนึ่งตามที่ระบุไว้ในคำตอบของฟิลิปป์ ) แทบเป็นไปไม่ได้ที่จะเขียน wrapper ที่เหมาะสมถ้าคุณไม่รู้ APIs ที่คุณกำลังจะทำการตัดคำ

ประเมินสถานะของ API ของคุณเป็นประจำ โดยทั่วไปควรมีพื้นที่ผิวที่เล็กกว่า API แบบพันรอบ หากคุณพบว่าคุณกำลังสร้างประเภท wrapper แบบหนึ่งต่อหนึ่งสำหรับทุกโครงสร้าง D3D หรือทุกฟังก์ชั่นการโทร OpenGL คุณอาจกำลังออกนอกเส้นทาง

ดูสิ่งที่ทำงานก่อนหน้านี้ Sokol และ BGFX เป็น API ที่ให้ระดับของการไม่เชื่อเรื่องพระเจ้าซึ่งอาจเป็นประโยชน์กับคุณและค่อนข้างง่ายที่จะเข้าใจ (โดยเฉพาะอย่างยิ่งในอดีต)


3

อีกประเด็นที่ยังไม่ได้กล่าวถึงซึ่งคุณควรพิจารณาคือเป้าหมายการปฏิบัติงานของคุณคืออะไร หากเป้าหมายของคุณคือการมีไลบรารีกราฟิกที่จะให้ประสิทธิภาพที่ดีจากแพลตฟอร์มฮาร์ดแวร์ราคาถูก แต่ยังสามารถใช้งานได้บนแพลตฟอร์มที่หลากหลายซึ่งมีประสิทธิภาพมากกว่า แต่ใช้ API ที่แตกต่างกันมันอาจสมเหตุสมผลในการออกแบบ API ของคุณ สิ่งที่เป็นนามธรรมถูกนำมาใช้อย่างเป็นธรรมชาติบนแพลตฟอร์มที่ประสิทธิภาพเป็นปัญหา แม้ว่าสิ่งนี้จะทำให้การลดความเร็วลง 50% สำหรับแพลตฟอร์มที่มีประสิทธิภาพยิ่งขึ้น แต่ก็อาจคุ้มค่าหากสามารถปรับปรุงความเร็วได้ 20% บนแพลตฟอร์มที่ประสิทธิภาพมีความสำคัญที่สุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.