การปรับเปลี่ยนพื้นผิว (การวาดภาพบนภาพ) ถือว่าเป็นการ“ เปลี่ยนสถานะ” หรือไม่?


11

ข้อตกลงในกราฟิกคือการดำเนินการเปลี่ยนแปลงสถานะน้อยกว่าดีกว่าดำเนินการเปลี่ยนแปลงสถานะเพิ่มเติม (เปลี่ยน shaders บัฟเฟอร์รวมผูกพันพื้นผิวที่ผูก ฯลฯ ) สำหรับพื้นผิวจะเร็วกว่าในการเรนเดอร์รูปหลายเหลี่ยมโดยใช้แผนที่เดี่ยว (สำหรับการแสดงผลสไปรต์ / ข้อความ) แทนที่จะผูกกับพื้นผิวแบบใหม่สำหรับแต่ละรูปหลายเหลี่ยม

สิ่งนี้ถือเป็นจริงหรือไม่ถ้าฉันวาดภาพอย่างต่อเนื่องบนพื้นผิวผ่านglTexSubImage2D? ฉันมีกระแสข้อมูลที่เข้ามา (ผ่านเครือข่าย) ที่ผ่านการประมวลผลและถูกทาสีลงบนพื้นผิวทีละแถว ข้อมูลจะถูกแสดงด้วยการเลื่อนอย่างไม่มีที่สิ้นสุด

ฉันจะดีกว่าการวาดภาพเป็นพื้นผิวหนึ่งที่แสดงบนสี่เหลี่ยมขนาดใหญ่เดียว (เลื่อนข้อมูลที่ทาสีไปสู่มุมมอง) หรือไม่ ความคิดที่นี่คือฉันจะมีพื้นผิวหนึ่ง (หรือสอง) ผูกพันในเวลาที่กำหนดในขณะที่ฉันเพิ่งจะทาสีมัน

หรือฉันควรจะวาดรูปสี่เหลี่ยมเล็ก ๆ น้อย ๆ จำนวนมาก (เพียงเปิดเผยสี่เหลี่ยมผืนผ้าเมื่อเสร็จสิ้นการวาดภาพ)? ฉันคิดว่าฉันจะผูกหนึ่งพื้นผิวต่อสี่เหลี่ยม

คำตอบ:


11

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

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

สำหรับการปรับปรุง texture / buffer ในทางกลับกันค่าใช้จ่ายหลักอยู่ที่การถ่ายโอนข้อมูลเอง ในทางทฤษฎีแล้วถ้าคุณไม่ได้อ่านข้อมูลพื้นผิวกลับไปที่ CPU หลังการอัพเดตไม่ควรมีการซิงโครไนซ์หรือแผงลอยไปป์ไลน์ อย่างไรก็ตามควรพิจารณาอีกแง่มุมหนึ่ง: ค่าโสหุ้ย API แม้ว่าจำนวนข้อมูลที่คุณส่งไปยังอุปกรณ์กราฟิกนั้นมีขนาดเล็ก แต่ถ้าคุณทำบ่อยพอค่าใช้จ่ายในการสื่อสารกับไดรเวอร์ / อุปกรณ์ก็จะยิ่งสูงขึ้นตามไปด้วยค่าใช้จ่ายในการถ่ายโอนข้อมูล นั่นเป็นอีกเหตุผลหนึ่งว่าทำไมการแบทช์จึงมีความสำคัญเมื่อปรับแต่งโหมดเรนเดอร์ให้เหมาะสม

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

ขณะที่ทราบด้านการนำเสนอนี้โดย NVidia ยังมีความเกี่ยวข้องและให้มากของข้อมูลเชิงลึกที่ดี: ใกล้ศูนย์ขับรถค่าใช้จ่ายใน OpenGL


5
ฉันไม่ทราบแน่ชัด แต่ฉันสงสัยว่า glTexSubImage บนพื้นผิวที่แสดงในเฟรมสุดท้ายหรือสองครั้งจะทำให้ระบบไม่ทำงานเนื่องจากไดรเวอร์พีซีมักจะพยายามบัฟเฟอร์เฟรมหนึ่งหรือสองเฟรมและไม่น่าจะเป็นไปได้ เพื่อต้องการทำสำเนาของพื้นผิวทั้งหมดเนื่องจากมีการอัพเดทเพียงเล็กน้อย ดังนั้นฉันจึงคาดว่าจะต้องใช้พื้นผิว (หรือวัตถุบัฟเฟอร์พิกเซล) สองหรือสามเท่าเพื่อประสิทธิภาพสูงสุด
John Calsbeek
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.