TBR架构的一些理解

  1. 现在移动侧的GPU渲染架构(Bifrost、valhall)是按照job的方式来进行的,共有3类job:vs-job、tile-job、fs-job;它们都是在shader core中执行的;tile-job主要负责把图元加到Tile-list中(由于三角形众多,所以这也是个大规模并行任务);
  2. G77采用的是valhall架构:
    a. 一个shader-core可以执行1024个threads (注:thread可以理解为streaming processor(sp): 最基本的处理单元),但它们不是同时执行的,而是将其分成64个warp, 每个warp有16个threads(16-wide warps),shader-core同时只能执行2个warp,如果某个warp在执行时阻塞了,调度单元就会先去执行其它warp,类似于CPU中线程调度的概念;
    b. 每个warp中的threads它们才是并发执行的,所以每个shader-core真正能并发执行的thread是32个,(一个job可能被拆分执行,因为每个thread的寄存器数量有限32个,如果是过于复杂的vs可能要占用很多寄存器所以只能拆开执行);
  3. 执行时以4个cycles为基本单位,在这4个cycle里能同时执行加、减、乘等运算;
  4. CPU和GPU真正传输的是寄存器的配置信号(相互通知交互),数据部分如ibo/vbo/texture这些数据都是存在共享内存(动态内存,如4+128的4)里,它有唯一的物理地址,CPU和GPU都通过虚拟地址来映射到它;它不需要做真正的数据传输;
  5. 在VS结束后,会根据三角形的大小及在屏幕空间的位置,将屏幕空间分成三类大小不同的tile-bins,这是为了减少从DDR中加载数据到GPU时读写带宽开销,渲染时以pass为单位进行渲染,可以想象很多pass在渲染时某些tile根本没有三角形需要绘制,这样就不需要读取相关的纹理数据啥的了;但注意最终渲染的时候的Tile大小是固定的为16x16的像素点,加入tile之前会做背面裁剪、视椎体裁剪等大颗粒的裁剪动作;
  6. 在执行真正的FS之前,有一个Fragment Front-End阶段,这里面除了Early-Z(以像素为单位),还有个FPK流程(Forward pixel kill,采用FIFO队列之后的数据按该队列顺序执行FS),它是对Early-Z的互补,假设图元A和图元B都覆盖同一个Quad,当A先于B提交,如果A的深度小于B则由early-z将B剔除,如果A的深度大于B则由FPK将A剔除;

其它补充:(源自针对移动端TBDR架构GPU特性的渲染优化,https://www.likecs.com/show-203322391.html)
7. TBR架构下什么时候真正对Tile进行渲染
TBR一般的实现策略是对于cpu过来的commandbuffer,只对他们做vetex process,然后对vs产生的结果暂时保存(对当前Tile渲染有关的三角形保存至Tiling list或者Framedata),等待非得刷新整个FrameBuffer的时候,才真正的随这批绘制做光栅化,做tile-based-rendering。什么是非得刷新整个FrameBuffer的时候?比如Swap Back and Front Buffer,glflush,glfinish,glreadpixels,glcopytexiamge,glbitframebuffer,queryingocclusion,unbind the framebuffer。

  1. 不使用Framebuffer的时候clear或者discard
    glclear操作是可以把当前的framedata清空的;比如你一直往一个Rendertexture上绘制,过了一会当你不再使用这张rendertexture的时候(即unbind)也会触发这些framedata的绘制,如果在你不再使用这张图之前能够调用一次clear,那么unbind的时候framedata就是清空的,可以减少很多不必要的绘制;因为如果不clear,那么每个tile在初始化的时候都要从dram上的framebuffer把那一块的内容完整拷贝过来,而clear后这个初始化就变得非常简单了,

  2. 不要在一帧里面频繁的切换framebuffer
    须知每次切换都意味着一次全量的Tile Rending;

  3. 避免大量的drawcall和顶点量
    若顶点数量太大,可能会导致framedata爆炸,framedata暂时被移到其它地方存储,严重影响效率,一般百万以上的顶点量不管drawcall多少,无论shader多简单,大部分机器都肯定会触发这个瓶颈。

  4. Alpha Test 和 Alpha Blending区别
    Alpha Test就是在执行FS的时候,需要从一个类似Alpha Texture上读当前像素做采样对比,如果比较不过则直接discard,不会写Depth;因此如果存在AlphaTest会导致FrameData失效(无法提前缓存准确的z值),最终AlphaTest之前保存的FrameData无法进行early-z,整个early-z失效;
    AlphaBlending不会修改深度值,所以不影响early-z,但是它会增加对FB的读操作。

你可能感兴趣的:(ue4,游戏引擎)