提公升先進OpenGL(一) Multi Bind

2022-05-19 14:59:26 字數 3369 閱讀 6306

**請註明:

為了更好的閱讀體驗,這裡提供了pdf版本。

導言opengl是乙個狀態機,在渲染過程中有許多的bind操作,尤其是對於紋理這類開銷很大的物件,每次對texture unit進行繫結操作會消耗非常多的cpu time。對此opengl 4.4推出了gl_arb_multi_bind擴充套件,用來解決這個在渲染中消耗過多cpu time的問題。

描述opengl是乙個狀態機,在渲染過程中有許多的bind操作,尤其是對於紋理這類開銷很大的物件,每次對texture unit進行繫結操作會消耗非常多的cpu time。對此opengl 4.4推出了gl_arb_multi_bind擴充套件,用來解決這個在渲染中消耗過多cpu time的問題。首先讓我們來看看,在opengl 3時代,應用程式如何上傳紋理:

//

bind textures to texture unit.

for(...)

//update the uniform sampler.

for(...)

在一幀渲染過程中,應用程式必須重複呼叫這些api,在不同的渲染批次中頻繁地呼叫這些api,將導致非常多的cpu time消耗在呼叫圖形api上。如果一幀中有多個渲染批次,每個渲染批次繫結許多的問題,渲染的幀率可能會變得很低。對此opengl提公升的方法,仍然是從api上著手,既然一次次地繫結texture,我們就一次性繫結就好了!gl_arb_multi_bind則因此誕生,這個擴充套件提供了對buffer object,texture object和sampler object繫結的優化:

//

uniform buffer object和transform feedback object繫結buffer object使用的

void bindbuffersbase(enum target, uint first, sizei count, const

uint *buffers);

void bindbuffersrange(enum target, uint first, sizei count, const

uint *buffers, const intptr *offsets, const sizeiptr *sizes);

//texture unit繫結texture和sampler使用的

void bindtextures(uint first, sizei count, const

uint *textures);

void bindsamplers(uint first, sizei count, const

uint *samplers);

void bindimagetextures(uint first, sizei count, const

uint *textures);

//vertex array object繫結buffer object使用的

void bindvertexbuffers(uint first, sizei count, const

uint *buffers, const intptr *offsets, const sizei *strides);

這些函式在功能上等價於以下偽**:

//

bindbuffersbase is equivalent to:

for (i = 0; i < count; i++)

else}//

bindbuffersrange is equivalent to:

for (i = 0; i < count; i++)

else

} //

bindtextures is equivalent to

for (i = 0; i < count; i++)

else

activetexture(texture0 + first +i);

if (texture != 0

)

else

}}// bindsamplers is equivalent to:

for (i = 0; i < count; i++)

else

}

也就是說,這個擴充套件通過單獨的乙個函式呼叫,將過去多次分開呼叫的開銷平攤起來,達到了減少cpu time的目的。在這裡我們對texture做了簡要的測試,測試的硬體則是nvidia gtx 650(geforce 332.21 driver),intel core i3-4130 cpu @ 3.40ghz 3.40ghz,ddr3 1600 4g,windows 7 sp1 x64,總共建立了192個紋理,使用了192個紋理單元,下面的每段**執行了一萬次,使用time.h裡的clock來計時(由於nsight暫時只支援到opengl 4.2 core,所以暫時沒法使用tracker)。

// 

**段1

glbindtextures(0, 192

, tex);

// **段2

for(int i = 0; i < 192; i ++)

// **段3

for(int i = 0; i < 192; i ++)

測試的結果如下:

glbindtextures

glactivetexture + glbindtexture

gluniform1i

第一次3

2816

第二次3

2415

第三次3

2716平均3

2615

也就是平均情況下,使用gl_arb_multi_bind擴充套件所需要的時間是3+15=18,而傳統情況下需要消耗26+15=41!通過這個簡單的測試,可以看出gl_arb_multi_bind所提公升的效率非常的明顯。當然這裡還想說乙個擴充套件就是gl_arb_bindless_texture,在這個擴充套件中可以獲得texture和sampler的handle,作為bindless texture直接上傳handle的值,讓shader通過handle來訪問紋理資料,而取消了texture unit的限制——這個擴充套件的好處更加明顯,首先沒有了texture unit的限制,shader直接通過虛位址訪問紋理,受到的限制更加的少,只需要gluniform1i的開銷即可。在opengl 4.4發布的時候,gl_arb_bindless_texture也一同發布了,遺憾的是這個擴充套件並不是core profile,但是gtx 6xx以上的顯示卡都支援了,讓我們期待一下這個擴充套件能否成為核心。

還有乙個值得提到的是,這個擴充套件的介面和d3d11的介面完全的相似,而opengl 4.4的重點就是方便d3d程式移植到opengl上來,可以看得出khonros group還在創造「directgl」,不過誰讓direct3d和opengl都是為類似的硬體跑腿的呢!

OpenGL學習(一) OpenGL簡介

opengl是乙個開放式的 與硬體無關的圖形軟體包。opengl是乙個專業的 功能強大 呼叫方便的底層三圍圖形函式庫。opengl是乙個圖形與硬體的介面。建模變換 著色光照處理和材質設定 位圖顯示 影象增強和紋理對映 雙快取動畫 根據基本圖形單元 點 線 多邊形 影象和點陣圖 建立景物模型,並且對所...

OpenGL學習筆記(一)初識OpenGL

早期的opengl使用立即渲染模式 immediate mode,也就是固定渲染管線 從opengl3.2開始,規範文件開始廢棄立即渲染模式,並鼓勵開發者在opengl的核心模式 core profile 下進行開發。opengl的一大特性就是對擴充套件 extension 的支援。opengl自身...

OpenGL學習筆記(一)

opengl是一種在計算機上進行2d 3d圖形繪製的技術規範,嚴格上來說不能算作一種具體技術。不過,現在有opengl庫來提供了對這種規範的封裝,於是也演變為今天對opengl api的使用。opengl需要硬體支援的,就如同對微軟directx的支援一樣。上層應用軟體都是通過opengl的庫介面,...