การจำลอง GS ของ PlayStation 2 – พรมแดนสุดท้ายของการจำลองด้วย Vulkan Compute
- ในปี 2020 ได้เขียน paraLLEl-RDP เพื่อทำ RDP ของ N64 บน Vulkan Compute ซึ่งทั้งเร็วมาก แม่นยำมาก และยังเพิ่มการรองรับการอัปสเกลด้วย
- จากนั้นจึงเริ่มวางแนวคิดโครงการลักษณะเดียวกันสำหรับ PlayStation 2 โดยจนถึงตอนนี้ GSdx เป็นมาตรฐานมาแล้ว 20 ปี
- paraLLEl-GS ไม่ใช่อิมพลีเมนเทชันแบบ compute ตัวแรกของ PS2 GS เพราะเคยมีความพยายามด้วย OpenCL ในปี 2014 แต่ไม่เสร็จสมบูรณ์
ภาพรวมพื้นฐานของ GS
GS คือสัตว์ประหลาดด้านการประมวลผลพิกเซล
- GS มีชื่อเสียงด้าน fillrate และแบนด์วิดท์ระดับมหาศาล ในปี 2000 มันสามารถประมวลผลได้มากกว่า 1 พันล้านพิกเซลต่อวินาที
- VRAM มีขนาดเล็ก แต่ถูกออกแบบให้สตรีมอย่างต่อเนื่องด้วยเอนจิน DMA หลากหลายแบบ
พิกเซลไปป์ไลน์ของ GS พื้นฐานแต่แปลกเฉพาะตัว
- GS เรียบง่ายกว่า N64 RDP โดยมีเท็กซ์เจอร์หนึ่งชุดและคอมไบเนอร์แบบรอบเดียว
- การเบลนด์สามารถเกิน 1.0 ได้ โดย 0x80 จะถูกมองเป็น 1.0 และไปได้สูงสุดถึง 0xff
- มีฟีเจอร์เฉพาะทางหลายอย่าง เช่น destination alpha test, conditional blending และ alpha correction
กฎการแรสเตอร์แบบ D3D9
- primitive จะถูกส่งมาในรูปแบบง่าย ๆ ใน clip space โดยยูนิต VU1 จะจัดการการแปลงและการ clipping
- X/Y: fixed-point 12.4, Z: uint 24 บิตหรือ 32 บิต, FOG: uint 8 บิต, RGBA: 8 บิต, STQ: เท็กซ์เจอร์แบบ perspective ด้วยพิกัดที่ normalized
คิวเวอร์เท็กซ์
- GS ให้ความรู้สึกคล้าย OpenGL 1.0 และรองรับ TRIANGLE_FAN
- การเขียนรีจิสเตอร์ XYZ จะล็อกสถานะเวอร์เท็กซ์และเลื่อนคิวต่อไป
ฟอร์แมตการสวิซเซิลที่น่าสนใจ
- เมื่อเรนเดอร์ด้วยสีหรือความลึก 24 บิต จะสามารถใช้ 8 บิตบนสุดเป็นเท็กซ์เจอร์ได้
- พิกัดพิกเซลถูกจัดเรียงเป็น "page" โดยแต่ละ page มีขนาด 8 KiB และแบ่งย่อยเป็น 32 บล็อก
แคชเฟรมบัฟเฟอร์และแคชเท็กซ์เจอร์
- มีแคชเฉพาะสำหรับการเรนเดอร์ลงเฟรมบัฟเฟอร์และสำหรับเท็กซ์เจอร์ โดยเกมมักทำ feedback loop อยู่บ่อยครั้ง
การทำเท็กซ์เจอร์
- ระบบเท็กซ์เจอร์ทั้งคุ้นเคยและลึกลับไปพร้อมกัน โดยศูนย์กลางของ texel อยู่ที่ครึ่งพิกเซล
- มีโหมดกำหนดแอดเดรสพิเศษ เช่น REGION_CLAMP และ REGION_REPEAT
CLUT
- มีแคชขนาด 1 KiB สำหรับเก็บพาเลตปัจจุบัน และต้องมีขั้นตอนคัดลอกอย่างชัดเจนจาก VRAM ไปยังแคช CLUT
TEXFLUSH
- มีคำสั่งสำหรับซิงก์และล้างค่าแคชเท็กซ์เจอร์ โดยเลือกเพิกเฉยต่อ TEXFLUSH และใช้การแคชให้น้อยที่สุดแทน
การจัดการรีจิสเตอร์ผ่าน GIF
- โต้ตอบกับฮาร์ดแวร์ GS ผ่าน GIF โดยเฮดเดอร์ของแพ็กเก็ต GIF จะกำหนดรีจิสเตอร์ปลายทางและจำนวนลูปสำหรับการเขียน
Trongle – GS
- เป็น API สำหรับคนที่คิดถึงความเรียบง่ายของ OpenGL 1.0
- ได้เพิ่มเครื่องมือที่สร้างฟอร์แมตดัมป์ .gs สำหรับใช้ในการทดสอบ
รายละเอียดการอิมพลีเมนต์
เรนเดอร์ไปป์ไลน์
- ซิงก์ข้อมูลจาก CPU ไปยัง VRAM, อัปโหลดข้อมูลไปยัง VRAM, อัปเดตแคช CLUT, unswizzle จาก VRAM ไปยัง VkImages, เรนเดอร์ และซิงก์ VRAM จาก GPU กลับไปยัง CPU
ตัวติดตาม page
- แบ่ง VRAM ออกเป็นหน่วย page เพื่อใช้ติดตาม โดยติดตามสถานะของแต่ละ page เพื่อจัดการ hazard ที่อาจเกิดขึ้น
การแคชเท็กซ์เจอร์
- แต่ละ page จะมีรายการ VkImages ที่เกี่ยวข้อง เมื่อเท็กซ์เจอร์ของ page นั้นถูกทำให้ใช้ไม่ได้ image จะถูกทำลายและ unswizzle ใหม่จาก VRAM
การอัปเดต CLUT
- เพื่อแบตช์การอัปโหลดเท็กซ์เจอร์ จึงแบตช์การอัปโหลด CLUT ไปด้วย โดยใช้สแนปช็อต CLUT จำนวน 1024 ชุด
การ unswizzle เท็กซ์เจอร์จาก VRAM
- ใช้ Vulkan เพื่อจัดสรร VkImage ใหม่ และประมวลผลด้วย compute shader
การตั้งค่าสามเหลี่ยมและการทำ binning
- เช่นเดียวกับ paraLLEl-RDP นี่คือ tile-based renderer โดยมีการจัดเตรียมอาร์เรย์ของแอตทริบิวต์สำหรับการตั้งค่าสามเหลี่ยม
สรุปโดย GN⁺
- บทความนี้กล่าวถึงการจำลอง GS ของ PlayStation 2 โดยเน้นเป็นพิเศษที่การอิมพลีเมนต์ด้วย Vulkan compute shader
- PS2 GS จำลองได้ยากเนื่องจากมีพิกเซลไปป์ไลน์ที่ซับซ้อนและฟีเจอร์เฉพาะตัวจำนวนมาก
- โครงการนี้อธิบายทั้งการทำความเข้าใจคุณลักษณะหลากหลายของ GS และแนวทางเชิงเทคนิคต่าง ๆ ที่ใช้เพื่อจำลองมัน
- เหมาะสำหรับผู้ที่สนใจการจำลอง PS2 โดยเฉพาะผู้ที่ต้องการมุมมองเชิงลึกเกี่ยวกับการจำลองประสิทธิภาพสูงด้วย Vulkan
1 ความคิดเห็น
ความเห็นจาก Hacker News