ทำไมรูปเรขาคณิตนี้ทำให้โปรแกรมของฉันช้าลงอย่างมาก?


27

ฉันมีโปรแกรม OpenGL และฉันแสดงภูมิประเทศ ฉันแทนที่จุดยอดในบัฟเฟอร์จุดสุดยอดและไม่ได้ระบายสีพวกมันใน shader ส่วนเลย ฉันกำลังเพิ่มรูปเรขาคณิตส่วนหนึ่งทีละส่วน

ก่อนที่ฉันจะเพิ่ม geometry shader เมื่อฉันเพิ่งจะเขียนโปรแกรมส่วนขั้นตอนการแรเงาและจุดยอดของท่อฉันได้รับ framerates ประมาณ 30+ พอฉันไม่สามารถสังเกตเห็นความไม่แน่นอนใด ๆ หลังจากเพิ่มรูปเรขาคณิตฉันได้รับประมาณ 5 เฟรมต่อวินาที ทำไม? นี่คือความสมบูรณ์ของเรขาคณิต shader:

#version 420

layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

void main()
{
    for (int i = 0; i < gl_in.length(); i++)
    {
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

นี่ไม่ใช่สิ่งที่ OpenGL ทำโดยไม่มี shader เรขาคณิตใช่ไหม

คำตอบ:


40

นี่ไม่ใช่สิ่งที่ OpenGL ทำโดยไม่มี shader เรขาคณิตใช่ไหม

ไม่มันไม่ใช่ GS เป็นขั้นตอนที่เลือกได้ไม่ใช่ขั้นตอนที่มีค่าเริ่มต้น

เพื่อให้ OpenGL สามารถเรียกใช้รูปทรงเรขาคณิตได้นั้นต้องดำเนินการสิ่งที่เรียกว่า " ชุดประกอบดั้งเดิม " เมื่อคุณสร้างชุดของรูปสามเหลี่ยมผ่านGL_TRIANGLE_STRIPOpenGL จะทำสิ่งต่าง ๆ ภายในเพื่อแปลงจุดยอดที่อยู่ติดกันทุก ๆ 3 จุดให้เป็นรูปสามเหลี่ยมแต่ละอัน

โดยปกติเมื่อไม่ได้ใช้ GS กระบวนการนี้จะดำเนินการเพียงครั้งเดียว เมื่อคุณใช้ GS อย่างไรก็ตามจะต้องดำเนินการก่อนที่ GS จะดำเนินการ แต่จะต้องดำเนินการหลังจาก GS เพราะ GS สามารถส่งออกประเภทดั้งเดิมที่แตกต่างกันโดยสิ้นเชิง

ดังนั้นตอนนี้คุณกำลังทำให้ระบบทำงานพิเศษเป็นพิเศษโดยไม่ทำอะไรเลย ท้ายที่สุดOpenGL ก็ไม่สามารถสรุปได้ว่า GS ของคุณไม่ได้ทำอะไรเลย

นอกจากนี้การปรับให้เหมาะสมจำนวนหนึ่งไม่ทำงานในที่ที่มี GS อีกต่อไป พิจารณาการเรนเดอร์ที่จัดทำดัชนี

แต่ละดัชนีจากบัฟเฟอร์อาร์เรย์องค์ประกอบจะสร้างผลลัพธ์เดียวกันจากจุดยอด ดังนั้น GPU มักจะแคชผลเหล่านี้ในการโพสต์-T & L แคช หากเห็นดัชนีที่อยู่ในแคชแล้ว VS จะไม่ทำงานอีกครั้ง มันจะดึงข้อมูลจากแคช

มันคืออะไร"? "มัน" คือ ... หน่วยการชุมนุมดั้งเดิม ใช่สิ่งที่ทำงานสองครั้งเมื่อคุณใช้ GS สิ่งที่แคชดัชนี? ใช้งานได้กับอินพุตของ GS เท่านั้น

แล้วจะเกิดอะไรขึ้นกับผลผลิตของ GS นั่นขึ้นอยู่กับฮาร์ดแวร์ แต่ต้องเข้าไปในบัฟเฟอร์หน่วยความจำบางชนิด ปัญหานั้นอยู่ที่บัฟเฟอร์นั้นไม่ได้จัดทำดัชนีเลย มันเหมือนกับสถานการณ์ของ glDrawArrays

ดังนั้นถ้าคุณส่งบัฟเฟอร์ของดัชนี 0, 1, 2, 0, 2, 3สิ่งนี้จะแปลเป็นจุดยอด 4 จุดในแคชโพสต์ - แอนด์แอล แต่ตอนนี้บัฟเฟอร์โพสต์ GS ของจุดยอดมี 6 จุดอยู่ในนั้น บัฟเฟอร์ post-GS ใช้พื้นที่มากขึ้น ดังนั้นหากคุณประสบปัญหาในการทำรายการหรือแถบสามเหลี่ยมที่ได้รับการปรับแต่งอย่างเหมาะสมหลังการโพสต์และ L และคุณพลิก GS แบบพาส - ทรูเช่นเดียวกับคุณ

มันไม่ได้ไร้ประโยชน์ แต่มันเจ็บ

การเพิ่มสิ่งนี้เป็นความจริงที่ว่า GPU GL 3.x-class หลายตัว (aka: DX10) มีบัฟเฟอร์ post-GS ค่อนข้างเล็ก ยิ่งบัฟเฟอร์มีขนาดเล็กเท่าใดการเรียกใช้ GS ที่น้อยลงก็จะสามารถทำงานได้พร้อมกัน ดังนั้นฮาร์ดแวร์ของคุณจึงมีปัญหาคอขวดบน GS เพราะtessellationเป็นคุณสมบัติใหญ่ของฮาร์ดแวร์ระดับ 4.x ฮาร์ดแวร์ดังกล่าวส่วนใหญ่มีบัฟเฟอร์เพียงพอที่จะทำให้ GS ที่ใช้งานหนักขึ้น

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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการชะลอตัว GS-เทพอ่านบทความนี้

นี่คือกฎพื้นฐานของหัวแม่มือเกี่ยวกับ GS ของ: ไม่เคยใช้ GS เพราะคุณคิดว่ามันจะทำให้การแสดงผลได้เร็วขึ้น คุณควรจะใช้มันเมื่อมันทำให้สิ่งที่คุณกำลังพยายามที่จะทำไปได้ หากสิ่งที่คุณพยายามทำคือการเพิ่มประสิทธิภาพให้ใช้อย่างอื่น

ข้อยกเว้นทั่วไปของสิ่งนี้คือ:


ฉันพยายามคำนวณความชันของรูปหลายเหลี่ยมแต่ละรูปด้วยการใช้ความสูงสูงสุดและลบความสูงต่ำสุด อย่างไรก็ตามถ้าจำนวนเรขาคณิตที่จะทำให้ฉันช้าลงด้วยจำนวนนี้ฉันคิดว่าฉันอาจจะสามารถทำมันได้อย่างสร้างสรรค์ในจุดสุดยอด
Avi

1
@Avi โปรดทราบว่าจุดสูงสุดและจุดต่ำสุดในรูปสามเหลี่ยมจะไม่ให้ความชันของคุณ คุณต้องการทั้งสามคะแนน
sam hocevar

2
โดยส่วนตัวแล้วฉันพบว่าการใช้อินสแตนซ์มีประโยชน์มากกว่าสำหรับสไปรต์แบบจุดเสมอ
Maximus Minimus

1
ข้อยกเว้นของการสไปรต์ชี้ให้เห็นถึงความแตกต่างlayout(points) in;หรือไม่ หรือมันเป็นขนาดเอาท์พุทคงที่? หรือบางทีทั้งคู่?
Philip
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.