Microsoft Direct3D 运行时调用用户模式显示驱动程序的 Blt 函数,将深度模具值从视频内存复制到系统内存,反之亦然。 驱动程序和硬件必须从或转换到驱动程序支持的所有不透明深度模具格式 (,即 D3DDDIFORMAT 枚举类型定义的所有格式(D3DDDIFMT_D*_LOCKABLE) 以下任何格式除外)执行格式转换:
- D3DDDIFMT_D16_LOCKABLE
- D3DDDIFMT_D32_LOCKABLE
- D3DDDIFMT_D32F_LOCKABLE
- D3DDDIFMT_S8_LOCKABLE
驱动程序放弃任何通道 (深度或模具) 以源格式存在,但不存在于目标格式。 运行时不允许在不共享任何常见通道类型的深度模具图面之间进行复制。
驱动程序首先将源深度值转换为 32 位无符号整数值,然后从 32 位无符号整数值转换为目标表示形式。 以下规则适用于这两种转换:
- 如果源深度值为浮点值,则会应用 [0,1] 的固定值,并将结果乘以_MAX_UINT。
- 如果源为整型,而目标为精度较低的整数,则会删除最右侧的额外位。
- 如果源为整型,目标为更高精度整数,则会从最左侧有效位复制最右侧的额外位。
- 如果源为整型,目标为浮点值,则将 32 位整数转换为浮点值,结果将除以_MAX_UINT。
驱动程序不需要为非均匀分布深度值提供特殊处理。
驱动程序将源模具值扩展到 8 位整数 (即,驱动程序将源模具值填充在左侧) 零。 如果目标表示形式使用较低的精度,则驱动程序应放弃最重要的位来执行转换。
用户模式显示驱动程序必须支持任意子实体的深度模具副本。 但是,在深度模具复制期间,驱动程序不需要执行镜像、拉伸或颜色键操作。 深度模具复制期间隐式需要点采样。
1. 核心功能要求
驱动程序必须通过 Blt 函数实现以下深度/模板(Depth/Stencil)操作:
- 视频内存 ↔ 系统内存 的深度/模板数据复制。
- 格式转换:支持所有不透明深度/模板格式(D3DDDIFMT_D*_LOCKABLE)的相互转换,但以下格式除外:
- D3DDDIFMT_D16_LOCKABLE
- D3DDDIFMT_D32_LOCKABLE
- D3DDDIFMT_D32F_LOCKABLE
- D3DDDIFMT_S8_LOCKABLE
2. 格式转换规则
(1) 深度值转换流程
步骤1:源 → 32位无符号整数
浮点源(如 D3DDDIFMT_D32F_LOCKABLE):
\text{uint32\_value} = \text{clamp}(float\_value, 0, 1) \times 2^{32} - 1
整型源(如 D3DDDIFMT_D24_UNORM_S8_UINT):直接扩展为 32 位(高位补零)。
步骤2:32位无符号整数 → 目标格式
- 目标为整型(如 D3DDDIFMT_D16_UNORM):截断低位(保留高位)或复制高位到低位(精度提升)。
- 目标为浮点(如 D3DDDIFMT_D32F):
float\_value = \frac{uint32\_value}{2^{32} - 1}
(2) 模板值转换规则
- 源 → 8位无符号整数:低位补零扩展(如 4 位模板 0b1011 → 0b00001011)。
- 目标精度更低时:丢弃高位(如 8 位模板 0b11001011 → 4 位 0b1011)。
3. 驱动实现要求
(1) 必须支持的功能
功能 | 说明 |
---|---|
子矩形复制 | 支持复制深度/模板表面的任意区域(无需支持拉伸/镜像)。 |
点采样 | 隐式要求(禁止插值或过滤)。 |
通道丢弃 | 若目标格式无对应通道(如仅深度→仅模板),丢弃无关数据。 |
(2) 禁止支持的功能
功能 | 原因 |
---|---|
颜色键(Color Key) | 深度/模板数据不适用。 |
拉伸/镜像 | 仅允许 1:1 像素映射。 |
(3) 代码示例
HRESULT APIENTRY Blt(D3D10DDI_HDEVICE hDevice,CONST D3D10DDIARG_BLT* pBlt
) {// 检查深度/模板格式兼容性if (!IsValidDepthStencilCopy(pBlt->SrcFormat, pBlt->DstFormat)) {return E_INVALIDARG;}// 执行格式转换与复制ConvertDepthStencil(pBlt->pSrcData, pBlt->SrcFormat,pBlt->pDstData, pBlt->DstFormat,pBlt->SrcBox, pBlt->DstPoint);return S_OK;
}
4. 格式兼容性规则
运行时强制要求:
- 源和目标格式必须至少共享一个通道类型(深度或模板)。
- 例如:D3DDDIFMT_D24_UNORM_S8_UINT 可与 D3DDDIFMT_D32_FLOAT 互转(共享深度通道),但不能与 D3DDDIFMT_S8_UINT 互转(无共享通道)。
5. 性能优化建议
- 硬件加速路径:优先使用 GPU 专用指令(如 MOV_DEPTH_STENCIL)而非 CPU 转换。
- 批量复制:合并多个子矩形操作为单次 Blt 调用。
- 缓存友好布局:确保深度/模板内存布局符合硬件访问模式(如 Tile-Based Rendering)。
6. WHCK 认证测试项
测试项 | 验证目标 |
---|---|
Device.Graphics.D3D10.DepthStencilBlt | 深度/模板复制与格式转换功能正确性。 |
Device.Graphics.D3D10.DepthStencilSubRect | 子矩形复制支持。 |
7. 调试与问题排查
常见错误:
- 通道不匹配:检查源和目标格式是否共享至少一个通道。
- 精度丢失:验证浮点→整型转换的舍入方式。
工具推荐:
- PIX on Windows:捕获 Blt 操作前后的深度/模板数据。
- DirectX Debug Layer:启用调试输出检测非法格式组合。
8. 总结
关键点:
- 驱动需实现深度/模板的精确格式转换,遵循位精度规则。
- 子矩形复制为必需功能,但无需支持复杂变形。
硬件协作:利用 GPU 固定功能单元加速转换(如存在)