您的位置:首页 > 其它

GPGPU入门第一步

2009-05-25 15:05 162 查看
GPGPU(General Purpose Computing on GPUs)的核心理念是将数组映射到纹理中,然后使用纹理来利用GPU进行并行计算,从而实现加速的作用。

首先,需要创建一个离屏渲染缓冲区(Frame Buffer Object),这样做的目的是将渲染(Render)工作放在后台,而不是渲染到常规的帧缓冲中,自然也就和显示没有任何关系,因为我们的目标是纯粹的利用GPU进行数值计算。

注:当然,所使用的显卡以及相应的显卡驱动程序必须支持shading language等扩展,具体的可以通过glview这个软件进行查看。

FBO的创建代码:

//glut及glew初始化:
glutInit (&argc, argv);
glutCreateWindow("TEST1");
glewInit();
//确定一个2d的渲染视口
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,texSize,0.0,texSize);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,texSize,texSize);

// 生成并绑定一个FBO
GLuint fb;
glGenFramebuffersEXT(1,&fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fb);


接下来生成一个纹理,并对纹理进行简单的设置:

GLuint tex,fboTex;
glGenTextures (1, &fboTex);
//绑定纹理
glBindTexture(GL_TEXTURE_RECTANGLE_ARB,fboTex);
// 设定纹理参数
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_T, GL_CLAMP);
// 这里在显卡上分配FBO纹理的存储空间,每个元素的初始值是0
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_RGBA32F_ARB,texSize,texSize,0,GL_RGBA,GL_FLOAT,0);


然后将FBO对象和FBO纹理绑定在一起:

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_RECTANGLE_ARB,fboTex,0);


开始将数据传入纹理中:

//创建渲染对象,从GL_COLOR_ATTACHMENT0_EXT开始,可以使用GL_COLOR_ATTACHMENT1_EXT等等:
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
//位图绘制起始点
glRasterPos2i(0,0);
//传入数据,data是一个预先定义好的数组,存储了4*texSize*texSize个数据,前面要乘以4,是因为使用了GRBA的颜色设置,每一个像素使用4个颜色分量,GPU能够对这四个分量进行优化的并行处理:
glDrawPixels(texSize,texSize,GL_RGBA,GL_FLOAT,data);


为了确认数据确实传入了GPU内存单元中,我们再将刚才传进去的数据读取出来,看看和原来的输入数据(也就是data数组)是否一样:

//选择从那个缓冲区中读取数据,因为刚才我们将data数据传入了ATTACHMENT0,所以这里我们也同样需要从这里将数据取出来:
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
//开始读数据,并将其存入一个result数组中,可以将result和data数组进行对比验证:
glReadPixels(0,0,texSize,texSize,GL_RGBA,GL_FLOAT,result);


至此,完成了GPGPU的第一步:将数组数据传送到显卡内存中,再从显卡内存中将数据读取出来。代码看上去比较麻烦,但是单机并行计算的诱惑是非常大的,拿我的GTX275显卡为例,240个流处理器,用来做并行计算是何等的强悍!

下面总结一下:

1.创建一个FBO

2.创建纹理,用于存储数据

3.用“glFramebufferTexture2DEXT”函数将FBO和纹理进行绑定。这里可以这样理解:FBO是一个大厅,这个大厅有很多门,具体的每一个门就是一个“GL_COLOR_ATTACHMENT0_EXT”(ATTACHMENT后面的数字就是每一个门的门牌号)。然后使用“glDrawBuffer”函数来确定我们的数据到底从哪一个门通过。

4.全部确定好以后,使用“glDrawPixels”函数来进行从数组到纹理的数据传递过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: