由于 Direct3D 版本 11 设备必须支持从任何支持扫描的格式进行演示,因此用户模式显示驱动程序需要通过其显示微型端口驱动程序 (内核模式驱动程序) 字段演示操作,这些驱动程序要求将颜色从任何扫描输出格式转换为任何其他扫描输出格式,以及标准 GDI 扫描输出格式。 这些扫描输出格式通过DXGI_FORMAT枚举中的以下值知道:
- DXGI_FORMAT_B5G6R5_UNORM
- DXGI_FORMAT_B5G5R5A1_UNORM
- DXGI_FORMAT_B8G8R8A8_UNORM
- DXGI_FORMAT_B8G8R8X8_UNORM
Direct3D 版本 11 DDI 存在后台缓冲区限制。 如果设置了从 DXGI_USAGE 枚举) DXGI_USAGE_BACKBUFFER (,则仅允许以下其他 DXGI 用法:
- DXGI_USAGE_SHADERINPUT,映射到 D3D11_BIND_SHADER_RESOURCE
- DXGI_USAGE_RENDER_TARGET_OUTPUT,映射到 D3D11_BIND_RENDER_TARGET
请注意,不允许后端缓冲区使用 CPU 访问标志。
1. 扫描输出格式支持要求
强制支持的格式列表
驱动程序必须实现以下 DXGI_FORMAT 的扫描输出(Scan-out)与相互转换能力:
DXGI 格式 | 位深度 | 颜色空间 | 典型用途 |
---|---|---|---|
DXGI_FORMAT_B5G6R5_UNORM |
16-bit | RGB | 低功耗移动设备 |
DXGI_FORMAT_B5G5R5A1_UNORM |
16-bit | RGBA | 带1-bit Alpha的旧硬件 |
DXGI_FORMAT_B8G8R8A8_UNORM |
32-bit | RGBA | 标准HDR/广色域显示 |
DXGI_FORMAT_B8G8R8X8_UNORM |
32-bit | RGB | 无Alpha通道的桌面应用 |
颜色转换规则
硬件加速:驱动需通过显示引擎(Display Engine)或专用色彩空间转换单元(CSC)实现实时转换。
精度保留:
- B5G6R5 → B8G8R8A8:通过插值扩展位深度(如 R5 → R8 = (R5 << 3) | (R5 >> 2))。
- Alpha处理:B5G5R5A1 转换时,Alpha通道默认为 0x00(透明)或 0xFF(不透明)。
寄存器配置示例
void ConfigureColorConversion(DXGI_FORMAT srcFormat, DXGI_FORMAT dstFormat) {
switch (srcFormat) {
case DXGI_FORMAT_B5G6R5_UNORM:
WriteRegister(DISPLAY_CSC_MODE, RGB565_TO_RGBA8888);
break;
case DXGI_FORMAT_B8G8R8X8_UNORM:
WriteRegister(DISPLAY_CSC_MODE, RGBX8888_TO_RGBA8888);
WriteRegister(DISPLAY_ALPHA_FILL, 0xFF); // 填充Alpha为1.0
break;
// 其他转换模式...
}
}
2. 后台缓冲区的严格限制
允许的绑定组合
当资源标记为 DXGI_USAGE_BACKBUFFER 时,仅允许 以下附加标志
DXGI 使用标志 | 对应 D3D11 绑定标志 | 用途 |
---|---|---|
DXGI_USAGE_SHADER_INPUT |
D3D11_BIND_SHADER_RESOURCE |
允许在着色器中采样(如后处理) |
DXGI_USAGE_RENDER_TARGET_OUTPUT |
D3D11_BIND_RENDER_TARGET |
允许作为渲染目标输出 |
明确禁止的行为
CPU 访问:
后台缓冲区 不可 设置以下标志:
D3D11_CPU_ACCESS_READ // 禁止CPU读取
D3D11_CPU_ACCESS_WRITE // 禁止CPU写入
非法绑定:
禁止以下绑定组合,驱动需在 CreateResource 中验证:
if (desc.Usage == DXGI_USAGE_BACKBUFFER) {
if (desc.BindFlags & ~(D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)) {
return E_INVALIDARG; // 例如禁止D3D11_BIND_UNORDERED_ACCESS
}
}
3. 驱动实现验证
格式转换测试用例
跨格式呈现测试:
创建 B5G6R5 后台缓冲区,输出到 B8G8R8A8 显示器,验证颜色精度损失 ≤5%。
Alpha通道处理:
B5G5R5A1 转换为 B8G8R8A8 时,检查 Alpha 值为 0x00 或 0xFF。
后台缓冲区错误注入
非法操作 | 预期驱动行为 |
---|---|
设置 D3D11_CPU_ACCESS_READ |
返回 E_INVALIDARG ,调试层输出警告。 |
绑定 D3D11_BIND_DEPTH_STENCIL |
拒绝创建,返回 DXGI_ERROR_UNSUPPORTED 。 |
4. 性能优化建议
硬件寄存器预配置:
为常见格式转换(如 B8G8R8A8 ↔ B5G6R5)预加载硬件查找表(LUT),减少动态配置开销。
内存布局优化:
后台缓冲区优先使用 线性布局(D3D11_TEXTURE_LAYOUT_LINEAR),确保扫描输出引擎高效访问。
5. 调试与兼容性
调试层检查
格式转换警告:
若驱动未实现某格式转换,调试层输出:
[D3D11 DEBUG] SCANOUT CONVERSION UNSUPPORTED: %s → %s
后台缓冲区误用:
检测非法CPU访问尝试,触发设备移除(DXGI_ERROR_DEVICE_REMOVED)。
多厂商适配
格式支持查询:
通过 CheckFormatSupport 动态报告扫描输出能力:
D3D11_FEATURE_DATA_FORMAT_SUPPORT formatSupport = { DXGI_FORMAT_B5G6R5_UNORM };
pDevice->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &formatSupport, sizeof(formatSupport));
assert(formatSupport.Support1 & D3D11_FORMAT_SUPPORT_DISPLAY);
6. 总结
全格式扫描输出:驱动必须支持4种指定格式的实时转换,确保显示兼容性。
后台缓冲区约束:严格限制绑定组合,禁止CPU访问,保障呈现性能。
硬件加速优先:利用显示引擎固定功能单元,最小化转换开销。