使用gl函数读取位置访问冲突_使用compute shader进行通用计算及示例

本文介绍了OpenGL计算着色器(compute shader)的基础知识,包括工作组的执行、如何获取工作组位置、通信和同步。通过示例展示了如何使用compute shader对2D图像进行并行计算,实现数据的加法操作。
摘要由CSDN通过智能技术生成

3f1d35c585e465af2f4a0b37c4478b01.png

1.工作组及其执行

compute shader是在OpenGL4.3(Opengl es 3.1)以后引入的一种专门用于并行计算的着色器。在计算着色器中,任务以组为单位进行执行,我们称之为工作组(work group)。拥有邻居的工作组被称为本地工作组(local workgroup), 这些组可以组成更大的组,称为全局工作组(global workgroup),而其通常作为执行命令的一个单位。

计算着色器会被每个本地工作组中的每个单元调用一次。工作组的每一个单元称为工作项(work item),每次调用称为一次执行。执行的单元之间可以通过变量和显存进行通信,且可以通过执行同步操作保持一致性。图12-1显示了一个全局工作组。这个全局工作组包括16个本地工作组,每个本地工作组又包括16个执行单元,排成4X4的网格,每个执行单元拥有一个二维向量表示的索引值。尽管图示中,全局和本地工作组都是2维的,而事实上它们都是3维的,为了适应1维、2维的任务,只需把额外的2维或1维设为0即可。计算着色器的每个执行单元本质是相互独立的,可以并行地在支持OpenGL地GPU上执行。

b98e4a68199218876497a5ab125d935d.png

大部分OpenGL硬件会将这些执行单元打包成较小地集合(lockstep),然后将这些小集合拼成本地工作组。本地工作组的大小在计算着色器的代码中输入布局限定符莱设置。全局工作组的大小则是本地工作组大小的整数倍。当计算着色器执行时,它可以通过内置变量来知道当前在本地工作组中的相对坐标、本地工作组的大小,及本地工作组在全局工作组中的相对坐标。基于这些还能进一步获得执行单元在全局工作组红的坐标。着色器根据这些变量来决定应该负责计算任务中的哪些部分,同时也能知道一个工作组中的其他执行单元,以便共享数据。

通过布局限定符在计算着色器中声明本地工作组的大小,分别使用local_size_x,local_size_y,local_size_z,它们的默认值为1.如忽略local_size_z,就会创建一个NXM的2维组。如声明一个本地工作组大小为16x16的着色器。

#version 430 core
layout (local_size_x = 16, local_size_y = 16) in;
void main(void){
    ...
}

当创建并链接一个计算着色器后,就可以通过glUseProgram将它设置为当前要执行的程序,然后用glDispatchCompute将工作组发送到计算管线上。

void glDispatchCompute(GLuint num_group_x, GLuint num_group_y, GLuint num_group_z);

在3个维度上分发执行计算工作组,num_group_x、num_group_y和num_group_z分别设置工作组在X、Y、Z维度上的数量。

每个参数均需大于0,小于或等于一个与设备相关的常量数组GL_MAX_COMPUTE_WORK_GROUP_SIZE的对应元素。

2.知道工作组的位置

当执行计算着色器时,它可能需要对输入数组的多个单元赋值,或者需要读取输入数组的特定位置的数据。因此计算着色器需要知道当前处于本地和全局工作组的具体位置。这是坐标是通过OpenGL的一组内置变量获得的。

gl_WorkGroupSize是一个用于存储本地工作组大小的常数

gl_NumWorkGroups是一个向量,它包含传给glDispatchCompute的参数(num_group_x、num_group_y、num_group_z)

gl_LocalInvocationID表示当前执行单元在本地工作组中的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值