關於openGl與CUDA協作的具體實現

2021-06-06 16:00:25 字數 3116 閱讀 5140

關於opengl與cuda協作的具體實現

共享緩衝區的使用:

乙個在空白opengl螢幕中繪製的例子:

先宣告兩個全域性變數:

//緩衝區物件的id, 另乙個用於儲存gl_pixel_unpack_buffer(傳遞給opengl的)資料

gluintbuffer;

//接下來是cuda對共享緩衝區的「名字」

cudagraphicsresource*resource;

在初始化時的操作:

//為cuda執行時使用opengl驅動程式做準備

cudaglsetgldevice(裝置識別符號);

//接下分配cuda的裝置記憶體,用於啟動kernel函式,執行你自己的操作

cudamalloc((void**)&src,bitmap_width*bitmap_height*3);

cudamemcpy(src,bitmap.buffer,bitmap_width*bitmap_height*3,cudamemcpyhosttodevice);

注意:分配cuda裝置記憶體時,要在opengl建立了視窗之後才進行,我就因為這個問題糾結了很久。

接下來要產生opengl的緩衝區物件

glewinit();

glgenbuffers(1,buffer);

glbindbuffer(gl_pixel_unpack_buffer,buffer);

glbufferdata(gl_pixel_unpack_buffer,bitmap_height*bitmap_width*3,0,gl_dynamic_draw);

//為opengl緩衝區buffer註冊乙個圖形資源

cudagraphicsglregisterbuffer(&resource,buffer,cudagraphicsmapflagsnone);

ps: 在隨後的opengl呼叫中我們將通過buffer來引用這個共享緩衝區,而在cuda執行時呼叫中,則通過resource指標來引用這個緩衝區。

//告訴cuda執行時對映這個共享資源

cudagraphicsmapresources(1,&resource,null);

//請求乙個指向被對映資源的指標,devptr是你自己宣告定義的指標

接下來呼叫kernel<<>>( devptr,……)利用cuda處理

注意:在opengl中使用gldrawpixels繪製時,要先取消對映的呼叫:

cudagraphicsunmapresources(1,&resource,null);

最後在opengl中繪製:  glbindbuffer(gl_pixel_unpack_buffer,buffer);

gldrawpixels();

程式結束時,別忘了釋放:

cudagraphicsunregisterresource(resource);

glbindbuffer(gl_pixel_unpack_buffer)

gldeletebuffers(1,&buffer);

乙個在opengl螢幕擷取矩形畫素來操作後,再次繪製的例子:

//緩衝區物件的id, 另乙個用於儲存gl_pixel_pack_buffer(從opengl獲取的)資料

gluintbuffer;

初始化的操作:

//為cuda執行時使用opengl驅動程式做準備

cudaglsetgldevice(裝置識別符號);

glbindbuffer(gl_pixel_pack_buffer,buffer);

glbufferdata(gl_pixel_pack_buffer,分配的大小(位元組),0,gl_dynamic_draw);

//將opengl緩衝物件註冊到cuda

cudaglregisterbufferobject(buffer);

在opengl中:

glbindbuffer(gl_pixel_pack_buffer,buffer);

//讀取螢幕上的畫素矩形

glreadpixels(recordx,recordy,width,height,format,type,0);

//對映緩衝物件

cudaglmapbufferobject((void**)&temp,buffer);  

ps:temp是你自己定義的指標,用來操作從opengl螢幕擷取的矩形畫素

kernel<<>>(temp,……);

//解除對映,繪製到螢幕之前要先解除對映,不然,後果將……(你自己試試)

cudaglunmapbufferobject(buffer);

glbindbuffer(gl_pixel_unpack_buffer,buffer);

gldrawpixels();

最後,釋放:

cudaglunregisterbufferobject(buffer);

gldeletebuffers(1,&buffer);

後記:

感覺自己嘗試寫opengl和cuda的協作時,由於接觸opengl不多,然後cuda也是剛學不久,所以都是懵懵懂懂,到處試試,最後還是試出來了,寫這篇文章是因為很難找到一篇能有比較完整的opengl和cuda的實現過程的文章,所以我想寫出來和大家分享一下,也能讓大家少些除錯改錯的時間(你知道除錯動不動就是幾個小時的活),最後那些opengl的函式我假設大家已經對opengl的緩衝區物件有了解了,理解起來不難,如果有什麼錯誤或寫錯的地方,歡迎提出。好吧,就說到這裡。

cuda與opengl互操作之VBO

opengl的緩衝區可以對映到cuda的位址空間,當做global memory被訪問。這樣做可以使計算得到的資料直接視覺化,提公升速度。因為資料儲存在裝置端,沒有裝置端到主機端的傳輸耗費,不論計算還是可是化都相當的快。具體使用步驟 1 建立vbo glgenbuffers 1,vbo glbind...

GPU 高效能程式設計 CUDA 執行緒協作

並行執行緒塊的分解 在向量加法中,為向量中的每乙個元素都啟動乙個執行緒塊 add dev a,dev b,dev c 尖括號中的第乙個引數建立的執行緒塊的數量,第二個引數表示每個執行緒塊中建立的執行緒數量,所以上述啟動的執行緒數量為 n n 1 使用執行緒實現 gpu 上的向量求和 需要修改兩個地方...

執行緒 角色與協作

多執行緒使用場景 主 控 執行緒召喚了幾個小弟來解決主 控 執行緒不方便處理的問題 召喚乙個小弟或召喚一群小弟,各有分工,協同完成任務。普通的程式塊通過if else等流控來控制業務流程 執行緒通過執行緒變數來控制 與人類社會 公司組織 類似,執行緒程式設計的主要思想是任務分解 分離與匯報機制 執行...