godot computer shader 解析lifegame 后
前面只說了,如何和device取得通訊,以及他的大致簡要流程。
接下到了語言上面。
現(xiàn)在主流有3個,opencl,opengl-computer-shader,cuda。
收線cuda和opencl是專門用來并行運算的語言,那無論從理論上還是使用上面,都比opengl-cs方便很多,和先進很多。
一、cuda

Grid 當前GPU程序
Block 一個分組
thread 分組里面的成員
PS:因為thread是必須并行的,但是x*y*z是有限的。那就分Block,如果所有thread不能干并發(fā),可以一個Block一個Block的執(zhí)行。
shared memory在當前block里為高速全局變量
local memory? ? 在當前thread里面為批量低速全局變量
registers????????????在當前thread里面為高速全局變量
Global memory 和cpu互通的可定義struct的變量
constant memory 給GPU讀取的陣列數(shù)據(jù)
Texture? memory x*y*4的整列數(shù)據(jù)
不難發(fā)現(xiàn),global是gpu處理數(shù)據(jù)唯一能夠output的方式。
如果我是處理粒子,那么粒子的?
大小:就可以定義為constant,thread不用修改他,直接返回就是了。
坐標:就定義為Global,可以和cpu互通,同時thread可以寫入
不變的顏色:constant
可變的顏色:global
我們稍微看一下代碼

清晰明了,很多事情在cuda 環(huán)境做了,這也就非常的清晰了,環(huán)境都不需要搭建(沒有皮衣哥的卡和驅(qū)動,當然不需要掃描了,直接物理報錯)
二、opengl
原理如下

看起來比皮衣哥的簡單多了,實則不然。
在GPU中有三種內(nèi)存。
靜態(tài)內(nèi)存:只用來讀,寫入滿,但是讀取超快
可動內(nèi)存:1幀就該里面幾個值,多了就很慢了。
動態(tài)內(nèi)存:每1幀,數(shù)據(jù)都要全部清空重寫。
在制造這三種內(nèi)存在制造成本上面就是不一樣。
皮衣哥的:
global內(nèi)存就是全是 dynamic。
constant 和 texture 全用 static來保存。
那么其余的零時變量自動分配可動內(nèi)存。
在opengl中也可以看到

我需要一個buffer,上傳內(nèi)容的同時需要告知這個數(shù)據(jù)用來干嘛,這里的static draw就是不會改變它,之用來繪制。
usage的說明

如果為draw就會綁定到填色著色器。
read 可讀。
copy 開啟可以高效復制。
這種越是open的,那么就需要自己和設備簽訂契約
那我們看看啊opencl的契約簽訂代碼
源碼連接
https://github.com/rsnemmen/OpenCL-examples/blob/master/Hello_World/hello.c
1、調(diào)用庫 跳過
2、申請設備列表,建立社管的context(連接,中文翻譯為上下文,就是tm的傻逼),命令列表,編譯GPU程序,創(chuàng)建管線

3、我刪除了error的處理

emmm,這妥妥的增加新人的門檻。哈哈哈哈哈
實際上就是那么管理操作,這里還刪掉了錯誤處理。哈哈哈哈
當然這些都不重要,有億點時間可以把它封裝了。不封裝水能用啊。
4、看看他的gpu程序

其實和cuda的區(qū)別不大,不能是一模一樣,只能說孿生兄弟。
三、opengl-computer-shader
我們接下來需要把人頭接到狗身上,不能說有點難,只能說非常麻煩。
我們在前面看到的語言里面都在名片,然后叫人去提貨。
然而 opengl沒有名片,也就是指針這個概念,沒有指針概念。異步執(zhí)行沒有指針,于是opengl用了一個特定的玩意,bufferID。
真是操蛋了。
四、解釋opengl的內(nèi)存
1、如果我要在c上面分配一個內(nèi)存,哈哈哈 mem1保存了一個在系統(tǒng)虛擬內(nèi)存池里面的1024個int大小內(nèi)存的首地址,如果用就用&(point+offset)或者 mem1[10]這樣的運算符

2、opengl說,我不。
????我現(xiàn)在只有64個倉庫,這個倉庫分別對于一個id,你拿著那個id,去找我的倉庫管理員,他給你提貨,你要是像自己去,不要意思,你連倉庫管理員都看不到。
????這也就成了

你滴,自己準備一個記事本,那你申請的東西我會打電話給你,而且你必須告訴我你要用來干嘛,不然你放在哪里都不知道。
????然后在把上面的point color texcoords分割成三段

然后在用一個自己準備的VAO記住。
????不是我說opengl在設計語言的失敗,只能解釋時候沒普及指針這個概念。
? ??所以放到現(xiàn)在,opengl是一個非常討人厭的數(shù)據(jù)傳入方式。
????我直接上傳struct不好嗎?我在傳入的時候用_steam_read_ vec3 color 傳入不好嗎?
????當然不好,畢竟opengl沒有收入,寫那么好的驅(qū)動也不會擴大占比。如果要反賽博朋克的巨型企業(yè),那這些麻煩都吃不了,還能干啥。
五、opencl的語言特征
1、

標志位計算做色器
版本4.5
默認執(zhí)行網(wǎng)絡為 8*8*1,這里的local_size_z = 1 被省略了。
在godot源碼里面

反正64最合適。
2、

這里的binding就是在godot中綁定過的,倉庫編號,


當然還是指針方便。這里就像,int* a = 10;?
收線我們要脫褲子放屁一樣麻煩:
? ? ?????????? 1、申請一個sizeof(int)大小的內(nèi)存,內(nèi)存用來可讀,不可寫,放到高度讀取內(nèi)存中
?? ? ? ? ? ? ? 2、申請一個sizeof(int*)大小的內(nèi)存
? ? ? ? ? ? ? ?3、第二個內(nèi)存存儲第一個內(nèi)存的地質(zhì)
到了opengl就要更麻煩,還要說我到時候計算的時候在程序的第0號參數(shù)上面?;蠲撁摰挠忻 ?/p>
3、set


4、一些和uv或者coord相關的關鍵詞

這里用了gl_globaleinvocationid invocation:當前調(diào)用。也就是當前uv。
這個坐標有些操作

不過一般情況只用gl_globaleinvocationid 就夠了。

5、并行運算

這里返回的unit不需要說也知道是一個x*y大小的陣列
保存到cells_out里面

ps作者這里的uv取名教gidx,真的有毛病,這里的gidx是 一個ivec2,他里面有兩個int,我不推薦這個取名,gid就好了,或者gid_xy都好。
總結(jié):還是 cuda好啊,最次也是opencl,用opengl_CS,非常的嗎,麻煩。