一:DX12 相较于 OpenGL 之类的旧 API 有什么优势#

核心优势:更底层、更显式、更加适配多线程与现代 GPU 架构。DX12 将旧 API 中许多底层工作交还给应用层,从而使得引擎能够自己控制资源、同步以及命令提交,减少了驱动带来的开销,也提升了程序的可预测性。

  • CPU 开销更低:

    • 在 OpenGL / DX11 中,诸如资源同步、内存管理、命令验证等操作都是由驱动自己完成的,而在 DX12 中需要自己手动地进行显式管理,比如 CPU 与 GPU 的 Fence 设置、使用 Descriptor Heap 绑定描述符、通过 Command List 录制命令等。
    • 这样使得驱动需要去猜的东西变少了,CPU 端的成本更加可控。
  • 多线程的命令录制更好:

    • OpenGL / DX11 的命令录制很容易集中在一个主线程上,DX12 支持同时利用多个线程进行命令录制,因此引擎可以将阴影 Pass、后处理、场景遍历等分配给多个线程生成 GPU 命令,降低 CPU 主线程的处理压力。
  • 资源与内存控制更加显式:

    • DX12 允许程序员对资源生命周期、堆内存分配等手动进行管理,而旧 API 都是由驱动自动进行管理。
  • 状态切换更加高效:

    • DX11 / OpenGL 都是传统的状态机模型,状态多、变化频繁,因此驱动需要不断地去进行验证;DX12 使用的是 PSO(Pipeline State Object),将大量管道状态预先打包,之后在运行期中只需要对创建好的 PSO 进行绑定即可,减少了运行期的状态切换与验证成本。
  • 同步更加可控:

    • 在旧 API 中,许多同步操作是隐式的,所以可能会出现“上一帧使用某个资源,下一帧又需要对其进行写入,于是驱动偷偷插入等待、重命名等操作来避免冲突”的情况。
    • DX12 的同步更加显式:
      • CPU / GPU 用 Fence。
      • GPU 内部资源状态用 ResourceBarrier。
      • 多 Queue 之间也要显式同步。

补充:缺点是现代 API 的代价是复杂度更高,DX12 把原本由驱动完成的工作交由程序员手动完成,如果处理不当,DX12 可能会比 DX11 等旧 API 还要慢。

二:DX12 是如何将一帧绘制到屏幕上的#

  • 获取当前的 Back Buffer:

    • Swap Chain 中包含多个缓冲区,当前帧需要绘制到其中一个 Back Buffer 上。
  • CPU 录制命令:

    • CPU 先重置 Command Allocator 和 Command List,再将绘制操作逐个录制。
  • 资源状态切换:

    • Back Buffer 初始通常处于 PRESENT 状态,需要使用 Resource Barrier 将其切换至 RENDER_TARGET 状态,这样 GPU 才能往里面写入颜色。
  • 设置渲染目标:

    • 为当前的 Back Buffer 绑定 RTV,如果需要深度测试,还要绑定 DSV。
  • 清屏:

    • 将当前颜色缓冲区与深度缓冲区清空。
  • 设置渲染管线:

    • 对 PSO、Root Signature、顶点缓冲 / 索引缓冲、常量缓冲、纹理、采样器、Viewport 等进行绑定。
  • 发出 Draw Call:

    • 之后 GPU 会经过顶点着色、光栅化、像素着色等操作,将结果写入 Back Buffer。
  • 资源状态切换:

    • 将 Back Buffer 从 RENDER_TARGET 切回 PRESENT,准备交给显示系统。
  • 提交命令至 GPU:

    • CPU 关闭 Command List,通过 Command Queue 将命令提交至 GPU 进行执行。
  • 显示:

    • 调用 SwapChain->Present(...),DXGI 会将渲染好的 Back Buffer 交给显示系统,最终显示在屏幕上。
  • Fence 同步:

    • CPU 通过 Fence 确认 GPU 已经绘制完成这一帧,此时才可以复用这一帧的 Back Buffer。

三:Command Queue 的三种类型#

DX12 将 GPU 工作拆成不同队列,方便图形、计算、拷贝异步执行,但队列之间仍需显式同步

Direct(Graphics) Queue:

最通用、最强大的队列

支持所有 GPU 操作,如 Draw(绘制)、Compute(计算)、Copy(资源转移)、Resource Barrier(资源状态转换)等

Compute Queue:

专用于高性能计算任务

主要支持 Compute Shader 指令和资源复制/转移操作,通常不支持绘制等图形相关指令(如光栅化);适用于物理模拟、GPU 粒子系统等

Copy Queue:

原笔记(优先级表述待复核)

优先级最高、开销最小的通道,用于数据传输

仅支持拷贝、填充、清空等简单的内存操作,用于主机到显存的资源上传、显存内的数据移动等

来源:语雀原笔记