我試圖在Apple A7 GPU上使用金屬API儘可能快地呈現大量非常小的二維四邊形。研究GPU的三角形吞吐量數字,例如here,並且蘋果在主題演示期間在屏幕上引用了> 1M個三角形,我希望能夠以60fps渲染每幀500,000個這樣的四邊形。或許少一點,因爲它們都可見(在屏幕上,沒有被z緩衝區隱藏)和微小(對於光柵化程序來說很棘手),所以這可能不是GPU超級優化的用例。也許蘋果的演示版運行速度爲30fps,所以我們假設〜200,000應該是可行的。當然是100,000 ...對不對?使用金屬渲染四邊形性能
但是,在我的測試應用程序中,最大值僅爲〜20,000 - 超過此值,並且iPad Air的幀率降至60以下。有100,000個四邊形時,它以14 fps運行,即以每秒2.8米的吞吐量(與AnandTech文章中引用的68.1M 屏幕三角形相比較!)。
即使我使用一個平凡的片段着色器使單個像素變小,性能也不會提高。所以我們可以假定這是頂點綁定的,並且Xcode中的GPU報告也是一致的(「Tiler」爲100%)。頂點着色器也是微不足道的,除了有點縮放和翻譯數學外什麼都沒做,所以我假設瓶頸是一些固定功能的舞臺......?
只是爲了獲得更多的背景信息,我使用一個實例繪製調用渲染所有幾何,每個實例一個四元組,即每個實例4個頂點。四邊形的位置從頂點着色器中由實例ID索引的單獨緩衝區應用。我也嘗試了其他一些方法(非實例化所有頂點預變換,實例化+索引等),但這並沒有幫助。沒有複雜的頂點屬性,緩衝區/表面格式,或者我能想到的任何其他東西,似乎可能會在驅動程序/ GPU中遇到緩慢的路徑(儘管我當然不能確定)。混合關閉。幾乎所有其他東西都處於默認狀態(如視口,剪刀,ztest,剔除等)。
的應用程序是用斯威夫特,但希望這沒關係;)
我試圖瞭解是否是我看到的渲染這樣的四邊形時(而不是預期的性能一個「適當」的3D場景),還是需要一些更先進的技術來達到接近廣告三角形吞吐量的地方。人們認爲什麼可能是這裏的限制瓶頸?另外,如果有人知道任何理由,爲什麼在OpenGL中這比在Metal中更快(我還沒有嘗試過,並且想不到任何理由),那麼我也很樂意聽到它。
感謝
編輯:添加着色器代碼。
vertex float4 vertex_shader(
const constant float2* vertex_array [[ buffer(0) ]],
const device QuadState* quads [[ buffer(1) ]],
constant const Parms& parms [[ buffer(2) ]],
unsigned int vid [[ vertex_id ]],
unsigned int iid [[ instance_id ]])
{
float2 v = vertex_array[vid]*0.5f;
v += quads[iid].position;
// ortho cam and projection transform
v += parms.cam.position;
v *= parms.cam.zoom * parms.proj.scaling;
return float4(v, 0, 1.0);
}
fragment half4 fragment_shader()
{
return half4(0.773,0.439,0.278,0.4);
}
你能告訴我們你的頂點佈局/描述符和你的着色器代碼嗎?在這裏的示例應用中,我可以在iPad mini 2上打開每幀150ktris,在iPhone 6上打開> 300ktris/frame。我的三角形平均覆蓋範圍爲2像素。 – warrenm 2015-01-19 22:18:14
當然,我在上面添加了着色器代碼。我沒有明確設置頂點佈局。我也注意到這對Tiler來說有很大的影響,屏幕有多少被四邊形覆蓋(我預計這對於片段舞臺來說很重要,但是很驚訝地發現它對頂點舞臺的影響非常大......這是一個瓷磚緩存效果)。也就是說,將所有四邊形集中在屏幕的一個小區域內,而不是將它們均勻地分佈在整個位置,從而提高性能,然後我可以打擊大於100k的三角形。也許這就是他們如何達到> 1M:具有非常高的三次數的小物件.. – lespalt 2015-01-20 11:47:33
是的,鋪磚者與它有很多關係。大多數這些微小的三角形只會碰到一個瓦片,並且需要移動到GPU上的瓦片越少,瓦楞紙板的開銷就越小。 FWIW,我沒有看到你的着色器有任何明顯的錯誤。 – warrenm 2015-01-20 23:56:50