GPGPU基础(三):GPGPU的理念

上一篇:GPGPU基础(二):GPGPU需要用到的OpenGL概念

使用OpenGL进行通用计算需要解决几个问题

1. 计算流水线的终点是帧缓存或显示器,而科学计算的结果一般需要写入存储器,这是怎么做到的?

使用纹理缓存。

GPGPU基础

2. 图形流水线处理的是坐标信息和像素信息,怎么才能使它处理通用数据?

使用正对投影平面的正交投影。

3. OpenGL提供的有限数量的图形处理函数对数据处理效果非常单一,而且都是针对三维模型和像素值的函数,如何制定科学计算所需的算法?

GPGPU的计算过程:

1)将数据数据保存为纹理图

用户可以将数据放置在二维数组或三维数组中。因为纹理元最多只能有RGBA四个颜色通道,所以在存为三维数组时,第三维不能大于4。

2)将数据加载到纹理缓存

传输前注意显存大小,以及所支持的最大单张纹理图尺寸。超出限制,可对数据分批进行计算。

3)使用正对投影平面的正交投影

在常规的OpenGL三维图形显示原理中,投影的过程常常伴随着对原来对象整体的放大或缩小(比如透视投影),以及在某一个方向上的尺寸缩放(如将一个略有侧转的平面正交投影到投影平面后,虽然物体整体尺寸未变,但在侧转方向上的投影图形略有缩短)。在GPGPU中,每个像素对用户来说都是一个数据,在整个投影过程中应保证这个像素不被缩短(遮挡),也不被拉长(或复制),即应避免任何次尺寸的变化。这要求投影必须是正交投影,且对象(用于纹理映射的表面)是正对投影平面放置的(对象与投影平面平行)。对象的放置和摄像机(观察点)的位置对投影效果都有影响。因此,对象被绘制得正对投影平面这一条件,与从正对对象得方向观察对象这一条件是需要被同时满足得。最简单得方法就是将对象绘制得与坐标轴垂直,然后顺着坐标轴得方向观察对象。

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, unWidth, 0.0, unHeight);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

此处对象指一个用于纹理映射得表面。在纹理映射过程中,纹理图会贴在该表面上。既然该表面必须正对投影平面,即它是与投影方向垂直的,那么这个表面一定是一个平面。事实上,为了与矩形纹理图配合,绘制的表面也是一个与纹理图等大的矩形。

4)设置视口和纹理图尺寸

视口选择与原点对齐,然后将视口尺寸设置成对象的尺寸

GPGPU基础

5)绘制一个与纹理图等大的矩形

“用绘制来调用”的关键步骤是:需要绘制一个与纹理图等大的矩形来作为纹理映射的对象,因为该对象的表面与纹理图的尺寸完全相同,纹理映射就可以保证覆盖纹理图的每个纹理元,且映射比例为1:1.实际上,这样映射就是数据的复制。纹理元被读取并复制到流水线的入口,进入顶点着色器。根据1:1的纹理坐标,矩形对象上的每个片段(或像素)都会被赋予对应位置纹理元的像素值。

    // set render destination
    glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
    // Hit all texels in quad.
    glPolygonMode(GL_FRONT, GL_FILL);
    // render quad with unnormalized texcoords
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex2f(0.0, 0.0);
    glTexCoord2f(unWidth, 0.0);
    glVertex2f(unWidth, 0.0);
    glTexCoord2f(unWidth, unHeight);
    glVertex2f(unWidth, unHeight);
    glTexCoord2f(0.0, unHeight);
    glVertex2f(0.0, unHeight);
    glEnd();

上面代码中设定纹理坐标时使用了非单位化的坐标值,这是因为使用的纹理种类为GL_TEXTURE_RECTANGLE_ARB,而GL_TEXTURE_2D要求单位化坐标。

6)将纹理图映射至矩形对象

7)读回数据

void transferFromTexture(float *data) {
    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    glReadPixels(0, 0, unWidth, unHeight, textureParameters.texFormat, GL_FLOAT, data);
}

乒乓技术

当算法有多个步骤时,一个步骤的计算结果是下一个步骤的输入数据时,就需要用到乒乓技术。这时。多块纹理缓存需要被分配。它们充当不同阶段的输入、输出缓存。

版权声明:本文为CSDN博主「koibiki」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/koibiki/article/details/80353346

最新文章