admin管理员组文章数量:1516870
创建D3DDDIERR_APPLICATIONERROR错误代码以允许驱动程序参与验证,而 Direct3D 版本 11 API 未参与验证。 以前,如果驱动程序返回E_INVALIDARG错误代码,则会导致 API 引发异常。 调试层的存在将导致调试输出,并指示驱动程序已返回内部错误。 调试输出会向开发人员建议驱动程序存在 bug。 如果驱动程序返回D3DDDIERR_APPLICATIONERROR,调试层将确定应用程序出现故障。
1. 错误代码语义与使用场景
| 错误代码 | 含义 | 适用场景 |
|---|---|---|
D3DDDIERR_APPLICATIONERROR
| 应用程序传入非法参数或违反API规则,责任在应用层。 | 参数验证失败(如无效句柄、越界值)、资源状态冲突等。 |
E_INVALIDARG
| 驱动内部验证失败,可能暗示驱动逻辑缺陷。 | 驱动检测到无法解释的硬件状态异常、内部数据结构损坏等。 |
DXGI_ERROR_DEVICE_REMOVED
| 硬件设备丢失(如TDR事件),通常非应用直接导致。 | GPU超时、驱动崩溃、电源管理事件等。 |
2. 驱动实现规范
应返回 D3DDDIERR_APPLICATIONERROR 的典型场景
HRESULT APIENTRY CreateResource(
D3D10DDI_HDEVICE hDevice,
D3D10DDIARG_CREATERESOURCE* pArgs
) {
// 场景1:验证资源尺寸超出硬件限制
if (pArgs->pMipInfoList[0].Width > MAX_TEXTURE_SIZE) {
return D3DDDIERR_APPLICATIONERROR; // 应用请求了不支持的尺寸
}
// 场景2:无效格式绑定
if (!IsFormatSupported(pArgs->Format, pArgs->BindFlags)) {
return D3DDDIERR_APPLICATIONERROR; // 应用使用了非法格式组合
}
// 正常创建逻辑
return S_OK;
}应返回 E_INVALIDARG 的典型场景
HRESULT APIENTRY DrawIndexed(
D3D10DDI_HDEVICE hDevice,
UINT IndexCount,
UINT StartIndexLocation,
INT BaseVertexLocation
) {
// 内部状态不一致(如未绑定的顶点缓冲区)
if (!pDevice->pCurrentVB) {
LogInternalError("Vertex buffer not bound");
return E_INVALIDARG; // 驱动未正确处理状态绑定
}
// 正常绘制逻辑
return S_OK;
}3. 调试层行为对比
当驱动返回 D3DDDIERR_APPLICATIONERROR
调试输出示例:
[D3D11 DEBUG] APPLICATION ERROR: ID3D11Device::CreateBuffer failed.
Reason: Invalid buffer size (requested=16384, max=8192).
Check application parameters.开发者反应:检查调用参数是否符合API文档要求。
当驱动返回 E_INVALIDARG
调试输出示例:
[D3D11 DEBUG] DRIVER ERROR: Internal validation failed in DrawIndexed.
Vertex buffer missing. Contact driver vendor.开发者反应:更新驱动或报告驱动厂商。
4. 错误处理最佳实践
驱动开发准则
- 参数验证前置:在函数入口处验证所有输入参数,尽早返回 D3DDDIERR_APPLICATIONERROR。
- 内部状态保护:若检测到不可恢复的驱动状态错误(如内存损坏),返回 E_INVALIDARG 并记录详细日志。
- 错误信息丰富化:通过 pfnSetErrorCb 回调附加错误描述(调试构建下):
pDevice->pKTCallbacks->pfnSetErrorCb(
hDevice,
D3DDDIERR_APPLICATIONERROR,
L"Invalid UAV binding: Format R32_UINT required for atomic operations."
);应用开发建议
- 调试层集成:始终在开发中启用 D3D11_CREATE_DEVICE_DEBUG 捕获应用错误。
- 错误恢复:
hr = pDevice->CreateBuffer(&desc, NULL, &pBuffer);
if (hr == D3DDDIERR_APPLICATIONERROR) {
// 显示用户友好错误,提示检查参数
ShowError("Invalid buffer creation parameters. See debug output.");
}5. 兼容性与版本控制
- Windows 7+ 专属:D3DDDIERR_APPLICATIONERROR 仅在D3D11 DDI及更高版本有效。
- 向下兼容:若驱动同时支持D3D10 DDI,仍需处理 E_INVALIDARG 的旧有行为。
总结
明确责任划分:
- D3DDDIERR_APPLICATIONERROR → 应用层错误。
- E_INVALIDARG → 驱动层错误。
调试友好性:通过调试层精准定位问题责任方。
健壮性提升:驱动应优先使用 D3DDDIERR_APPLICATIONERROR 避免误判驱动缺陷。
版权声明:本文标题:从零开始解读DDI:D3D DDIs开发中的那些小秘密与大挑战 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/web/1770514218a3255464.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论