对共享表面的纹理格式支持
驱动程序应支持共享资源和可共享的后台缓冲区,以使用 DXGI_FORMAT 枚举中的这些附加纹理格式:
- DXGI_FORMAT_A8_UNORM
- DXGI_FORMAT_R8_UNORM
- DXGI_FORMAT_R8G8_UNORM
- DXGI_FORMAT_BC1_TYPELESS\*
- DXGI_FORMAT_BC1_UNORM
- DXGI_FORMAT_BC1_UNORM_SRGB
- DXGI_FORMAT_BC2_TYPELESS\*
- DXGI_FORMAT_BC2_UNORM
- DXGI_FORMAT_BC2_UNORM_SRGB
- DXGI_FORMAT_BC3_TYPELESS\*
- DXGI_FORMAT_BC3_UNORM
- DXGI_FORMAT_BC3_UNORM_SRGB
此外,如果驱动程序在 Direct3D 功能级别 9 硬件上支持 Microsoft Direct3D 11 及更高版本,则应支持 DXGI_FORMAT_L8_UNORM 占位符格式。 DXGI_FORMAT_L8_UNORM 在功能上等效于 D3DDDIFMT_L8 格式。
驱动程序还应支持 来自 D3DDDIFORMAT 枚举的其他纹理格式:
- D3DDDIFMT_G8R8
- D3DDDIFMT_R8
1. 核心支持格式列表
WDDM 驱动程序必须为 共享资源 和 可交换的后台缓冲区 支持以下纹理格式:
(1) DXGI 格式(Direct3D 10/11/12)
格式 | 描述 | 典型用途 |
---|---|---|
DXGI_FORMAT_A8_UNORM |
8-bit 单通道 Alpha(无类型) | UI 蒙版、字体渲染 |
DXGI_FORMAT_R8_UNORM |
8-bit 单通道 Red | 灰度图像、高度图 |
DXGI_FORMAT_R8G8_UNORM |
16-bit 双通道(Red+Green) | 法线贴图、矢量场 |
DXGI_FORMAT_BC1_* |
BC1 压缩格式(DXT1) | 不透明/1-bit Alpha 纹理压缩 |
DXGI_FORMAT_BC2_* |
BC2 压缩格式(DXT3) | 带显式 Alpha 的纹理压缩 |
DXGI_FORMAT_BC3_* |
BC3 压缩格式(DXT5) | 带插值 Alpha 的纹理压缩 |
注:标有
*_TYPELESS
的格式需支持类型转换(如BC1_TYPELESS
→BC1_UNORM
)。
注:标有 *_TYPELESS 的格式需支持类型转换(如 BC1_TYPELESS → BC1_UNORM)。
(2) D3DDDI 格式(Direct3D 9 兼容性)
格式 | 等效 DXGI 格式 | 描述 |
---|---|---|
D3DDDIFMT_L8_UNORM |
DXGI_FORMAT_R8_UNORM |
8-bit 灰度(Direct3D 9 遗留) |
D3DDDIFMT_G8R8 |
DXGI_FORMAT_R8G8_UNORM |
16-bit Green+Red |
D3DDDIFMT_R8 |
DXGI_FORMAT_R8_UNORM |
8-bit Red |
2. 驱动实现要求
(1) 格式声明
在 D3D10DDI_D3D11_OPTIONS 或 DXGI_DDI_BASE_ARGS 中声明支持:
DXGI_DDI_BASE_ARGS BaseArgs = {0};
BaseArgs.DDIVersion = DXGI_DDI_VERSION_1_3;
BaseArgs.SupportedFormats.R8_UNORM = TRUE; // 示例:启用 R8_UNORM
(2) 共享资源创建
处理 D3D11_DDI_RESOURCE_MISC_SHARED 标志的资源分配:
HRESULT CreateSharedResource(
D3D10DDI_HDEVICE hDevice,
CONST D3D11DDIARG_CREATERESOURCE* pArgs
) {
if (pArgs->MiscFlags & D3D11_DDI_RESOURCE_MISC_SHARED) {
ValidateFormat(pArgs->Format); // 检查是否为支持的共享格式
}
// 正常创建资源...
}
(3) 跨 API 兼容性
Direct3D 9 → Direct3D 11 共享:
- 将 D3DDDIFMT_L8_UNORM 映射为 DXGI_FORMAT_R8_UNORM。
- 确保 D3DDDIFMT_G8R8 与 DXGI_FORMAT_R8G8_UNORM 数据布局一致。
3. 特殊场景处理
(1) Direct3D 9 硬件的 D3D11 支持
若硬件仅支持 Direct3D 9 功能级别,仍需通过占位符格式 DXGI_FORMAT_L8_UNORM 提供灰度支持:
// 在 GetCaps 中响应查询
if (Type == D3DDDICAPS_GET_FORMAT_SUPPORT) {
if (pArgs->Format == DXGI_FORMAT_L8_UNORM) {
*(BOOL*)pData = TRUE; // 声明支持
}
}
(2) 压缩纹理的共享
BCn 压缩格式需保证跨进程/设备可访问:
- 内存对齐:BC1/BC2/BC3 的块大小为 4x4 像素。
- 禁止格式转换(除非显式指定 TYPELESS)。
4. WHCK 认证测试项
测试项 | 验证目标 | 方法 |
---|---|---|
Device.Graphics.WDDM13.Format.Shared |
共享资源的格式支持正确性。 | 创建共享表面并跨进程读写验证。 |
Device.Graphics.WDDM13.Format.BCn |
BC 压缩纹理的共享与渲染一致性。 | PIX 捕获压缩纹理数据。 |
Device.Graphics.WDDM13.Format.D3D9Compat |
D3D9 遗留格式(如 L8_UNORM )的兼容性。 |
D3D9 与 D3D11 互操作测试。 |
5. 调试与问题排查
常见问题:
- 共享失败:检查格式是否在 SupportedFormats 中声明。
- 数据错乱:验证 D3DDDIFMT_G8R8 与 DXGI_FORMAT_R8G8_UNORM 的通道顺序是否一致(G=R, R=G)。
工具推荐:
- PIX on Windows:捕获共享表面的内存布局。
- DirectX Caps Viewer:检查驱动声明的格式支持。
6. 性能优化建议
- 压缩纹理优先:对共享的静态纹理(如 UI 素材)使用 BCn 压缩以减少内存带宽。
- 灰度优化:R8_UNORM/L8_UNORM 格式适合单通道数据(如遮罩),节省 75% 内存。
- 内存对齐:共享表面按 4KB 对齐,避免跨进程访问的性能惩罚。
7. 总结
强制要求:WDDM 1.3+ 驱动必须支持上述格式以实现跨 API/进程资源共享。
关键点:
- 正确处理 D3DDDIFMT_* 与 DXGI_FORMAT_* 的映射关系。
- 压缩纹理(BCn)需保证共享时的数据一致性。
兼容性:Direct3D 9 硬件需通过 L8_UNORM 提供灰度支持。