1. Draw Call 的基本概念
Draw Call:
Draw Call 是指应用程序向 GPU 发出的绘制命令,通常用于渲染图形对象。每个 Draw Call 通常会涉及到多个状态设置和数据绑定操作。
2. CPU 和 GPU 交互的开销
内核空间与用户空间:
GPU 工作在内核空间,应用程序通过图形 API(如 DirectX、OpenGL、Vulkan)与 GPU 进行交互。这一过程涉及从用户空间到内核空间的转换,增加了 CPU 和 GPU 之间的通信开销。
Draw Call 的传递过程:
以 DirectX 为例,Draw Call 的传递过程包括多个步骤:应用程序 -> DirectX 运行时 -> 用户模式驱动 -> dxgkrnl -> 内核模式驱动 -> GPU。这一系列的中转会导致显著的性能开销,尤其是在频繁发出 Draw Call 时。
3. Draw Call 的开销来源
绑定数据的开销:
Draw Call 附带的绑定数据(如 Vertex Buffer、Index Buffer、Texture、Shader 等)会增加额外的开销。每次绑定数据时,GPU 需要进行状态切换,这会导致性能下降。
RenderDoc 的分析:
使用工具如 RenderDoc,可以看到一个 Draw Call 实际上可能会涉及多条命令,这些命令的执行会增加 CPU 的负担。
4. Unity 中的 Draw Call 管理
Batching:
在 Unity 中,绑定 Vertex Buffer 被称为一个 Batch。Unity 通过 Static Batching 和 Dynamic Batching 来减少 Draw Call 的数量,尽量一次性传输大量数据,而不是频繁传输少量数据。
SetPassCalls:
材质切换被称为 SetPassCalls,这一过程涉及大量的状态同步、Shader 编译和绑定、纹理绑定等操作。现代引擎通过对物体进行排序,确保相同渲染状态的物体连续绘制,以减少这些开销。
5. CPU 瓶颈与 Draw Call
小物体的绘制:
当绘制大量小物体时,CPU 和 GPU 之间的交互可能会成为性能瓶颈。虽然 GPU 本身的负载可能不高,但频繁的 Draw Call 会导致 CPU 处理时间增加,从而影响整体性能。
优化策略:
为了减少 Draw Call 的数量,开发者可以考虑以下策略:
合并小物体:将多个小物体合并为一个大物体,减少 Draw Call 的数量。
使用 Instancing:对于相同的物体,使用实例化技术来减少 Draw Call。
合理使用材质:尽量减少材质切换,使用相同材质的物体进行批量绘制。
总结
Draw Call 的数量对 GPU 性能有显著影响,尤其是在 CPU 和 GPU 交互频繁的情况下。理解 Draw Call 的开销来源以及如何有效管理 Draw Call 是优化图形性能的关键。通过合理的设计和优化策略,可以显著提高渲染效率和整体性能。
版权声明:本文为CSDN博主「你一身傲骨怎能输」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33060405/article/details/147155958





