风起提示:由于技术的发展风起云涌,需留意文章时效,2024-09-07。
回顾
前面我们已经介绍了CPU与GPU通信的基础设施:CPU侧内存、GPU侧显存、专用总线(NVLink/PCIe)、传输方式(显示复制/透明迁移)。有兴趣的同学可以更深入的了解下GPU架构,这里我们只要知道GPU擅长并行处理就行了。
有了这些基础设施后,我们就可以组织命令和数据,然后提交到GPU侧去运行了。如何组织命令和数据就需要我们清楚GPU的内部状态、渲染过程、以及对渲染过程的控制。
引入概念
内部状态(Internal State)
GPU的内部状态是指GPU在处理任务过程中需要维护的各种状态信息。
内部状态的具体实现
-
指针:
- 指向缓冲区的指针确实是内部状态的一部分。例如,顶点缓冲区指针指向顶点数据,索引缓冲区指针指向索引数据。
- 这些指针告诉GPU从哪里读取数据。
-
配置信息:
- 除了指针之外,内部状态还包括各种配置信息,如渲染状态中的混合模式、深度测试模式等。
- 这些配置信息告诉GPU如何处理数据。
-
寄存器状态:
- GPU内部有许多寄存器,用于存储临时数据和状态信息。
- 例如,着色器程序中的寄存器用于存储中间计算结果。
-
纹理和采样器状态:
- 纹理和采样器的状态信息也包含在内部状态中。
- 例如,纹理的滤波模式、采样器的地址模式等。
内部状态的管理和切换
-
状态配置:
- 在每个绘制调用之前,需要配置相应的内部状态。例如,设置顶点缓冲区、索引缓冲区、着色器程序等。
- 这些配置操作通常通过图形API(如OpenGL、Vulkan、DirectX)提供的函数来完成。
-
状态切换:
- 在不同的绘制调用之间,可能需要切换不同的内部状态。例如,从一个物体的绘制切换到另一个物体的绘制时,可能需要更改顶点缓冲区、着色器程序等。
- 频繁的状态切换会影响性能,因此需要优化状态切换。
-
状态保存与恢复:
- 在复杂的渲染场景中,可能需要保存和恢复内部状态,以便在不同的绘制调用之间快速切换。
- 这种机制可以帮助减少状态切换的开销。
渲染过程(Rendering Process)
渲染过程是一个宏观的流程,描述了从数据准备到最终输出的整个步骤。
主要步骤
-
数据准备:
- 准备好顶点数据、索引数据、纹理数据等。
- 分配和配置各种缓冲区(如顶点缓冲区、索引缓冲区、纹理缓冲区等)。
-
状态配置:
- 设置渲染状态,如颜色混合模式、深度测试模式、模板测试模式等。
- 绑定着色器程序、纹理、采样器等。
-
绘制调用:
- 发起绘制调用,告诉GPU渲染特定的图元(如三角形)。
- 每个绘制调用都会触发渲染管线的执行。
-
后期处理:
- 在绘制调用完成后,执行后期处理,如混合、抗锯齿等。
-
输出:
- 最终将渲染结果输出到屏幕或其他目标缓冲区。
渲染管线(Rendering Pipeline)
渲染管线在渲染过程中主要参与绘制阶段,主要负责处理每个绘制调用中的图元数据。
主要阶段
-
输入装配(Input Assembly):
- 读取顶点数据,并将顶点组装成基本图元(如点、线或三角形)。
-
顶点着色(Vertex Shader):
- 对每个顶点执行计算,如坐标变换、光照计算等。
-
几何着色(Geometry Shader)(可选):
- 生成新的几何图元,扩展或修改现有的几何结构。
-
裁剪(Clipping):
- 裁剪掉超出视口范围的图元。
-
光栅化(Rasterization):
- 将图元转换为屏幕上的像素(片段)。
-
片段着色(Fragment Shader):
- 对每个像素进行计算,确定其最终颜色、纹理等属性。
-
早期深度测试(Early Depth Test):
- 在片段着色之前进行深度测试,丢弃不可见的像素。
-
后期处理(Late Post-Processing):
- 执行混合、抗锯齿等后期处理。
-
输出合并(Output Merger):
- 将最终的像素颜色写入帧缓冲区(Framebuffer)。
内部状态、渲染过程、渲染管线的关系
- 渲染过程中,需要配置各种状态信息,如着色器、纹理、渲染状态等,这些状态统称为GPU内部状态。
- 渲染过程中,每次的绘制调用都会触发渲染管线的执行,GPU的内部状态会影响渲染管线中各个阶段的行为。
- 渲染过程是一个宏观流程,描述了从数据准备到最终输出的整个步骤,渲染管线主要负责绘制阶段对图元数据的处理。
更多精彩内容可关注风起的博客,微信公众号:听风说图