GPGPU基礎(三):GPGPU的理念

使用OpenGL進行通用計算需要解決幾個問題

1.計算流水線的終點是幀緩存或顯示器,而科學計算的結果一般需要寫入存儲器,這是怎麼做到的?

使用紋理緩存。



2.圖形流水線處理的是座標信息和像素信息,怎麼才能使它處理通用數據?

使用正對投影平面的正交投影。

3.OpenGL提供的有限數量的圖形處理函數對數據處理效果非常單一,而且都是針對三維模型和像素值的函數,如何制定科學計算所需的算法?

GPGPU的計算過程:

1)將數據數據保存爲紋理圖

用戶可以將數據放置在二維數組或三維數組中。因爲紋理元最多只能有RGBA四個顏色通道,所以在存爲三維數組時,第三維不能大於4。

2)將數據加載到紋理緩存

傳輸前注意顯存大小,以及所支持的最大單張紋理圖尺寸。超出限制,可對數據分批進行計算。

3)使用正對投影平面的正交投影

在常規的OpenGL三維圖形顯示原理中,投影的過程常常伴隨着對原來對象整體的放大或縮小(比如透視投影),以及在某一個方向上的尺寸縮放(如將一個略有側轉的平面正交投影到投影平面後,雖然物體整體尺寸未變,但在側轉方向上的投影圖形略有縮短)。在GPGPU中,每個像素對用戶來說都是一個數據,在整個投影過程中應保證這個像素不被縮短(遮擋),也不被拉長(或複製),即應避免任何次尺寸的變化。這要求投影必須是正交投影,且對象(用於紋理映射的表面)是正對投影平面放置的(對象與投影平面平行)。對象的放置和攝像機(觀察點)的位置對投影效果都有影響。因此,對象被繪製得正對投影平面這一條件,與從正對對象得方向觀察對象這一條件是需要被同時滿足得。最簡單得方法就是將對象繪製得與座標軸垂直,然後順着座標軸得方向觀察對象。

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, unWidth, 0.0, unHeight);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

此處對象指一個用於紋理映射得表面。在紋理映射過程中,紋理圖會貼在該表面上。既然該表面必須正對投影平面,即它是與投影方向垂直的,那麼這個表面一定是一個平面。事實上,爲了與矩形紋理圖配合,繪製的表面也是一個與紋理圖等大的矩形。

4)設置視口和紋理圖尺寸

視口選擇與原點對齊,然後將視口尺寸設置成對象的尺寸


5)繪製一個與紋理圖等大的矩形

“用繪製來調用”的關鍵步驟是:需要繪製一個與紋理圖等大的矩形來作爲紋理映射的對象,因爲該對象的表面與紋理圖的尺寸完全相同,紋理映射就可以保證覆蓋紋理圖的每個紋理元,且映射比例爲1:1.實際上,這樣映射就是數據的複製。紋理元被讀取並複製到流水線的入口,進入頂點着色器。根據1:1的紋理座標,矩形對象上的每個片段(或像素)都會被賦予對應位置紋理元的像素值。

    // set render destination
    glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
    // Hit all texels in quad.
    glPolygonMode(GL_FRONT, GL_FILL);
    // render quad with unnormalized texcoords
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex2f(0.0, 0.0);
    glTexCoord2f(unWidth, 0.0);
    glVertex2f(unWidth, 0.0);
    glTexCoord2f(unWidth, unHeight);
    glVertex2f(unWidth, unHeight);
    glTexCoord2f(0.0, unHeight);
    glVertex2f(0.0, unHeight);
    glEnd();

上面代碼中設定紋理座標時使用了非單位化的座標值,這是因爲使用的紋理種類爲GL_TEXTURE_RECTANGLE_ARB,而GL_TEXTURE_2D要求單位化座標。

6)將紋理圖映射至矩形對象

7)讀回數據

void transferFromTexture(float *data) {
    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    glReadPixels(0, 0, unWidth, unHeight, textureParameters.texFormat, GL_FLOAT, data);
}

乒乓技術

當算法有多個步驟時,一個步驟的計算結果是下一個步驟的輸入數據時,就需要用到乒乓技術。這時。多塊紋理緩存需要被分配。它們充當不同階段的輸入、輸出緩存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章