godot computer shader 解析lifegame 后
前面只说了,如何和device取得通讯,以及他的大致简要流程。
接下到了语言上面。
现在主流有3个,opencl,opengl-computer-shader,cuda。
收线cuda和opencl是专门用来并行运算的语言,那无论从理论上还是使用上面,都比opengl-cs方便很多,和先进很多。
一、cuda

Grid 当前GPU程序
Block 一个分组
thread 分组里面的成员
PS:因为thread是必须并行的,但是x*y*z是有限的。那就分Block,如果所有thread不能干并发,可以一个Block一个Block的执行。
shared memory在当前block里为高速全局变量
local memory 在当前thread里面为批量低速全局变量
registers 在当前thread里面为高速全局变量
Global memory 和cpu互通的可定义struct的变量
constant memory 给GPU读取的阵列数据
Texture memory x*y*4的整列数据
不难发现,global是gpu处理数据唯一能够output的方式。
如果我是处理粒子,那么粒子的
大小:就可以定义为constant,thread不用修改他,直接返回就是了。
坐标:就定义为Global,可以和cpu互通,同时thread可以写入
不变的颜色:constant
可变的颜色:global
我们稍微看一下代码

清晰明了,很多事情在cuda 环境做了,这也就非常的清晰了,环境都不需要搭建(没有皮衣哥的卡和驱动,当然不需要扫描了,直接物理报错)
二、opengl
原理如下

看起来比皮衣哥的简单多了,实则不然。
在GPU中有三种内存。
静态内存:只用来读,写入满,但是读取超快
可动内存:1帧就该里面几个值,多了就很慢了。
动态内存:每1帧,数据都要全部清空重写。
在制造这三种内存在制造成本上面就是不一样。
皮衣哥的:
global内存就是全是 dynamic。
constant 和 texture 全用 static来保存。
那么其余的零时变量自动分配可动内存。
在opengl中也可以看到

我需要一个buffer,上传内容的同时需要告知这个数据用来干嘛,这里的static draw就是不会改变它,之用来绘制。
usage的说明

如果为draw就会绑定到填色着色器。
read 可读。
copy 开启可以高效复制。
这种越是open的,那么就需要自己和设备签订契约
那我们看看啊opencl的契约签订代码
源码连接
https://github.com/rsnemmen/OpenCL-examples/blob/master/Hello_World/hello.c
1、调用库 跳过
2、申请设备列表,建立社管的context(连接,中文翻译为上下文,就是tm的傻逼),命令列表,编译GPU程序,创建管线

3、我删除了error的处理

emmm,这妥妥的增加新人的门槛。哈哈哈哈哈
实际上就是那么管理操作,这里还删掉了错误处理。哈哈哈哈
当然这些都不重要,有亿点时间可以把它封装了。不封装水能用啊。
4、看看他的gpu程序

其实和cuda的区别不大,不能是一模一样,只能说孪生兄弟。
三、opengl-computer-shader
我们接下来需要把人头接到狗身上,不能说有点难,只能说非常麻烦。
我们在前面看到的语言里面都在名片,然后叫人去提货。
然而 opengl没有名片,也就是指针这个概念,没有指针概念。异步执行没有指针,于是opengl用了一个特定的玩意,bufferID。
真是操蛋了。
四、解释opengl的内存
1、如果我要在c上面分配一个内存,哈哈哈 mem1保存了一个在系统虚拟内存池里面的1024个int大小内存的首地址,如果用就用&(point+offset)或者 mem1[10]这样的运算符

2、opengl说,我不。
我现在只有64个仓库,这个仓库分别对于一个id,你拿着那个id,去找我的仓库管理员,他给你提货,你要是像自己去,不要意思,你连仓库管理员都看不到。
这也就成了

你滴,自己准备一个记事本,那你申请的东西我会打电话给你,而且你必须告诉我你要用来干嘛,不然你放在哪里都不知道。
然后在把上面的point color texcoords分割成三段

然后在用一个自己准备的VAO记住。
不是我说opengl在设计语言的失败,只能解释时候没普及指针这个概念。
所以放到现在,opengl是一个非常讨人厌的数据传入方式。
我直接上传struct不好吗?我在传入的时候用_steam_read_ vec3 color 传入不好吗?
当然不好,毕竟opengl没有收入,写那么好的驱动也不会扩大占比。如果要反赛博朋克的巨型企业,那这些麻烦都吃不了,还能干啥。
五、opencl的语言特征
1、

标志位计算做色器
版本4.5
默认执行网络为 8*8*1,这里的local_size_z = 1 被省略了。
在godot源码里面

反正64最合适。
2、

这里的binding就是在godot中绑定过的,仓库编号,


当然还是指针方便。这里就像,int* a = 10;
收线我们要脱裤子放屁一样麻烦:
1、申请一个sizeof(int)大小的内存,内存用来可读,不可写,放到高度读取内存中
2、申请一个sizeof(int*)大小的内存
3、第二个内存存储第一个内存的地质
到了opengl就要更麻烦,还要说我到时候计算的时候在程序的第0号参数上面。活脱脱的有毛病。
3、set


4、一些和uv或者coord相关的关键词

这里用了gl_globaleinvocationid invocation:当前调用。也就是当前uv。
这个坐标有些操作

不过一般情况只用gl_globaleinvocationid 就够了。

5、并行运算

这里返回的unit不需要说也知道是一个x*y大小的阵列
保存到cells_out里面

ps作者这里的uv取名教gidx,真的有毛病,这里的gidx是 一个ivec2,他里面有两个int,我不推荐这个取名,gid就好了,或者gid_xy都好。
总结:还是 cuda好啊,最次也是opencl,用opengl_CS,非常的吗,麻烦。