2015-01-11 44 views
0

我讀過,優化OpenGL 2(尤其是ES)中非透明對象渲染順序的最佳方法是優先避免上下文排序中的上下文更改(綁定不同的緩衝區,着色器程序等)。正在調用glBindBuffer,glUseProgram等與以前相同的值效率低下?

如果您使用已綁定的緩衝區調用glBindBuffer,或使用已經是當前程序等的着色器程序執行glUseProgram等操作,它們是否仍會導致低效的管線刷新,或者庫是否足夠靈巧以識別他們作爲NOOPs?如果我可以在需要時綁定所有內容而無需跟蹤已綁定的內容並檢查它,它將使我的代碼更簡單。

回答

2

也許吧。這實際上不能一般回答。它完全依賴於實現。

司機是否應該檢查冗餘的狀態變化是一個有點哲學的討論,你不會找到共識。因此,您應該期望不同的供應商以不同的方式處理它,而且我甚至不一定會假設它在同一個驅動程序中針對所有狀態一致地進行處理。

如果您針對的是特定平臺,則應該對其進行測量。幸運的是,這很容易進行基準測試。如果你想覆蓋廣泛的平臺/供應商,我會盡量減少冗餘的狀態變化。至少如果你可以選擇相對便宜的話。如果你爲此增加了很多開銷,你可能會造成更多的傷害。

對此有不同看法的主要原因是檢查冗餘狀態變化並非完全免費。如果司機這樣做,則開銷適用於每個人。如此寫得好的應用程序(不會造成不必要的狀態更改)會爲優化寫入不好的應用程序而付出代價。你可以爭論的是非常不公平的。

實際上,這些檢查通常都會完成,特別是如果狀態更改本身相當昂貴。當然,如果狀態變化非常便宜,不值得添加檢查。這些檢查通常由重要應用/遊戲基準測試的性能優化推動。不幸的是,許多應用程序/遊戲使用OpenGL的效率非常低,驅動程序必須爲重要的基準測試產生最佳結果。在這些情況下過濾掉冗餘狀態更改是一種常見的優化。

0

我們的每個glBindBuffer或glUseProgram等調用都會在隊列中創建一個命令對象。此隊列將在一段時間後在gpu上執行。這裏有2個瓶頸。 1)要在隊列中創建命令對象,我們的代碼必須轉移到內核模式驅動程序。通常這種操作有一些滯後。 2)GPU將逐個執行我們的命令,並檢查已經綁定的緩衝區,GPU必須讀取並解碼命令。

要避免第二個驅動程序必須跟蹤當前狀態,我認爲,opengl驅動程序不這樣做。