美文网首页
OpenGL-ES 学习(8)---- GPU系统结构

OpenGL-ES 学习(8)---- GPU系统结构

作者: 特立独行的佩奇 | 来源:发表于2022-04-06 21:50 被阅读0次

    图形流水线

    一个图形应用是以流水线的方式运行,如下图所示:


    图形流水线.png

    CPU负责向GPU提交Render Operation,包括设置管线状态,准备渲染数据,提交绘制命令(也就是draw call)
    GPU 负责对渲染数据进行计算,对于不同的 Render pass,可以以流水线的方式并行执行
    OpenGL-ES 的渲染管线流程如下图所示:

    OpenGL-ES 图形管线.png

    顶点着色器:顶点着色器的输出称为可变变量(varing),顶点着色器还可以实现矩阵变换位置、计算照明公式来生成逐顶点颜色,生成或者变换纹理坐标等基于顶点的操作

    图元装配:图元是指三角形,线段,或者点等几何对象,图元的每个顶点被发送到顶点着色器的不同拷贝,在图元装配期间,这些顶点被装配成图元;每个图元,还需要确认图元是否位于视锥体内,如果没有完全位于,就需要进行裁剪,或者直接剔除,裁剪和剔除之后,顶点位置就被转换为屏幕坐标,传递给管线的下一阶段进行光栅化

    光栅化:光栅化是将一组图元转换为一组二维片段的过程,输出屏幕坐标,颜色,纹理坐标等然后,这些片段由片段着色器处理,这些二维片段代表着可以在屏幕上绘制的像素

    片段着色器:片段着色器输出一个颜色值

    渲染流程如下:
    首先图形应用输入顶点的值,再将这些顶点构成成基本图元(三角形);三角形的每个顶点经过Vertex Shader 处理,被变换到Clip space中,然后再做透视投影被投影到View space中,经过视锥裁剪被背面剔除之后,剩下的三角形都被Tiler 处理,得到每个Tiler 上的 polygon list(polygon:多边形),然后就是光栅化、early-Z、FPK、FragmentShader、z test、blend等一系列流程,执行完成之后就可以得到一个有用的 pixel,并且被写入FrameBuffer

    GPU顶层框架图

    Job Manager

    CPU 提交的绘制命令,会首先由JobManager 进一步拆分,将Vertex Shadre 和 Fragment Shader 分别提交到Non-FragmentSlot 和
    FragmentSlot 这两个队列中,绘制命令中也有可能包含Compute Shader, 同样也是进入Non-FragmentSlot中进行处理,然后ShaderCore 的FrontEnd 就会创建对应的 Wrap 来执行任务
    Wrap: 一组锁步执行的线程,在valhal 架构中,一个Wrap 包含十六个线程,Mali-G52 GPU 一个Wrap 包含8个线程

    Tiler

    Tiler 是TBR(Tiler based rendering)架构中固定的功能,用于将Framebuffer 切成小 tile,为每个Tile 生成相应的 polygon list. tile 是将一个完整的FB切分形成16x16 大小的小型FB,tiler 之后的操作都是在这个16x16 大小的Buffer 上进行的,直到这一帧所有的 tile 都绘制完成,原本的FB才会拼装完成,送到显示系统
    PC上常用的 IMR(Immediate Mode Rendering),流程如下


    IMR.png

    好处是基本数据被填充到FIFO里,随取随用,即使几何数据再多,也不会累计在片上内存,缺点也是显而易见的,这些几何数据可能被光栅化到FB的任何位置,所以在执行FragementShader 的时候读取FB容易造成cache 失效导致很大的 DDR带宽,比如blend,depth test,对于移动设备,访问DDR的代价是非常昂贵的
    TBR (tile based Rendering) 使用小型FB优化了这个过程


    TBR.png
    因为Tile 很小,可以在GPU上分点地方放它,对于FB的频繁访问,不再产生DDR带宽,而是变成了低时延,低功耗的 Tile 访问;同时在写出之前,对上次tile 中的结果进行CRC校验,使得相同的内容不再写,又可以节约更多的带宽
    ShaderCore

    Shader Core 是GPU中最核心的部分,是执行Shader 的器件,之前的GPU 部件,我们能编程控制的很少,但是Shader Core 基本完全掌握在我们手中,ShaderCore 包含在处理之前进行处理的Front-End,执行Shader 指令的ExcutionCore ,对FragmentShading结构做进一步操纵的Back-end 三个部件


    Shadecore1.png
    No-Fragment Front-end

    No-Fragment Front-end 负责处理非Fragment执行之前的操作,负责创建wrap, 包含 Vertex Shader 和 Compute Shader,创建 Wrap 的过程包含寄存器分配

    Fragment Front-end

    Fragment Front-end 的流程比较复杂,在Fragmentshader 执行之前,数据还是保存在DDR里的 polygon list,距离变成需要执行shader 的fragment,还需要经过下面流程


    ShaderCore.png

    首先必须从DDR 中将一个tile 对应的 polygon list 读取到GPU上,然后再进行光栅化,对三角形进行采样,以及对顶点属性继续插值。之后为了缓解overdraw(像素被之后的像素阻挡),进行了early-Z 和 FPK 对一些无效的Fragement 进行剔除,剩下的被Fragemnet Shader 处理

    ExcutionCore

    GPU最开始被发明出来就是用于图形加速的。在光栅化的渲染框架下,对顶点做变换以及对fragment着色是一种高度独立的任务。两个顶点或者像素之间谁都不需要关心对方的属性,并且它们之间的行为也几乎完全一致,比如说对一个三角形进行平移,则对它的每一个顶点加上相同的向量,区别只有输入:三个顶点的位置数据不同。如果对指令有一定了解的话,会发现这和SIMD(Single Instruction stream, Multiple Data stream)好像一模一样。事实上,GPU的Shader Core就是SIMD处理器

    Excution Core 的内部结构:


    ExcutionCore.png

    现在我们重点关注SIMD指令和操作数
    SIMD的特点就是,使用一条指令,完成多组数据的同一个运算。用一条伪指令来举例:ADD x, x, y 代表x = x+y。当ExcutioEngine中每一个线程对应的x,y寄存器(在Front-end中分配)都可以访问的时候,PU中的程序计数器取出ADD指令,并在每一个线程上执行,只不过对于不同的线程x,y的内容不同。

    Warp Manager

    Warp Manager从指令缓存中取出指令,并在数据准备完成的时候,提交给Excution engine执行,指令缓存就是之前说的,Job Manager分解CPU传来的Draw Call后放入的那两个队列;

    ExcutioEngine

    ExcutioEngine是SIMD指令的执行单元,每个ExcutioEngine包含1个程序计数器(以下简称PC),8/16个线程,每个线程可以使用32个bit寄存器

    Load Store unit

    负责所有非纹理采样的内存访问,包括数组,结构体,buffer,image等的读写(uniform buffer和编译器可以确定下标的小型数组访问,会被尽可能的优化为寄存器访问),以及寄存器溢出时,读写保存和加载溢出的寄存器。LS unit拥有自己的L1 Cache,compute shader中使用的shared memory 就来自这一部分。

    这里image的读写,是指imageLoad/Store这样的访问函数,和imageTexture这种类型的采样函数严格区分。读取图像的时候,使用texture unit的ImageTexture会更快。

    Varying Unit

    用于计算插值的固定功能单元

    Texture unit

    针对纹理采样优化的硬件,双线性采样具有很好的性能功耗。TU 拥有自己的L1 Cache,并且有专门为Texture优化的机制:优先缓存空间上邻近的像素,而不是地址上邻近的像素

    Fragment Back-end

    Back-end用于Fragment Shading完成后的操作,包括late z test、blend、把像素写到Tile Memory,当Tile Memory触发写回条件时,把它写回到DDR里。如果Tile内容和上一帧一样就抛弃,降低写出带宽。当所有的tile都处理完毕,一个完整的framebuffer就绘制完成了,可以用于显示

    Memory-port
    Memory.png

    CPU向GPU上传和更新数据,访问纹理,访问超大数组,buffer或者texture回读,访问SSBO等都需要用到MemoryPort 的读写

    参考文档

    移动CPU体系结构

    相关文章

      网友评论

          本文标题:OpenGL-ES 学习(8)---- GPU系统结构

          本文链接:https://www.haomeiwen.com/subject/fcudsrtx.html