D3D12DDI_DEVICE_FUNCS_VIDEO_0082_0 D3D12DDI_COMMAND_LIST_FUNCS_VIDEO_DECODE_0088 D3D12DDI_COMMAND_LIST_FUNCS_VIDEO_PROCESS_0088 D3D12DDI_COMMAND_QUEUE_FUNCS_VIDEO中需要注册很多callback函数,这些视频函数表定义了大量回调,它们的注册和调用遵循着清晰的两阶段流程:"能力查询与创建" 阶段和**"录制与执行"** 阶段。
🏗️ 驱动架构与流程概览
在深入细节前,先用一张图来总览整个生命周期:

1. 设备层 (D3D12DDI_DEVICE_FUNCS_VIDEO_0082_0) ------ 资源的"工厂"
这个函数表是视频功能的根对象 ,由驱动在 CreateDevice 时填充。它就像一家工厂,负责创建所有视频相关的核心"机器"(解码器、处理器、编码器等)和进行能力查询。
| 回调函数 | 必要性 | 调用顺序/说明 |
|---|---|---|
pfnGetCaps |
必须 | 第1步:最先被调用。运行时用来查询驱动支持哪些视频功能,如解码格式、编码能力等。 |
pfnCalcPrivate...Size 系列 |
必须 | 第2步 :在创建具体对象前调用。运行时让驱动计算其私有数据所需的内存大小,以进行精确的内存分配。 |
pfnCreateVideo... 系列 |
必须 | 第3步 :在实际分配内存后调用,用于创建具体的视频对象句柄。 |
pfnDestroyVideo... 系列 |
必须 | 最后一步 :在应用销毁对象时调用,用于清理驱动侧分配的资源,防止内存泄漏。 |
核心流程 :pfnGetCaps (查能力) -> pfnCalcPrivate...Size (算大小) -> pfnCreateVideo... (建对象) -> ... 使用 ... -> pfnDestroyVideo... (销毁)。
2. 命令队列层 (D3D12DDI_COMMAND_QUEUE_FUNCS_VIDEO)
命令队列是GPU执行命令的通道。
| 回调函数 | 必要性 | 调用顺序/说明 |
|---|---|---|
pfnExecuteCommandLists |
必须 | 运行时调用此函数将填充好的命令列表提交到GPU的命令队列中执行。 |
| 同步相关回调 | 视功能而定 | 例如 pfnSignal、pfnWait,用于处理队列间的同步和GPU/CPU的协调工作。 |
3. 命令列表层 (以解码/处理为例)
命令列表负责录制具体的GPU操作。
A. 视频解码 (D3D12DDI_COMMAND_LIST_FUNCS_VIDEO_DECODE_0088)
| 回调函数 | 必要性 | 调用顺序/说明 |
|---|---|---|
pfnDecodeFrame |
必须 | 核心录制函数 。在应用调用 DecodeFrame 时被调用,驱动将此帧的解码操作录制到命令列表中。 |
B. 视频处理 (D3D12DDI_COMMAND_LIST_FUNCS_VIDEO_PROCESS_0088)
| 回调函数 | 必要性 | 调用顺序/说明 |
|---|---|---|
pfnProcessFrame |
必须 | 核心录制函数 。在应用调用 ProcessFrame 时被调用,驱动将色彩转换、缩放等视频处理操作录制到命令列表中。 |
特别说明 :编码命令的录制流程更复杂,除了核心的
pfnEncodeFrame外,还必须 调用pfnEncodeResolveOutputMetadata来解析编码后的元数据,这是一个不可或缺的步骤。
📝 总结与标准工作流
将这些碎片拼凑起来,一个典型的视频解码工作流如下:
-
初始化 :运行时调用
pfnGetCaps查询解码能力。 -
创建对象 :调用
pfnCalcPrivateVideoDecoderSize和pfnCreateVideoDecoder创建解码器对象。 -
准备录制:创建命令队列和命令列表。
-
录制命令 :应用调用 API,运行时调用命令列表的
pfnDecodeFrame将解码操作录制下来。 -
执行 :应用调用
ExecuteCommandLists,运行时的pfnExecuteCommandLists将命令提交给 GPU。
这个流程中,pfnGetCaps 是所有功能的前提,pfnCalcPrivate...Size 和 pfnCreateVideo... 是每类对象创建的必需对,而各种 ...Frame 函数则是驱动完成实际工作的核心。