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. 错误处理最佳实践

驱动开发准则

  1. 参数验证前置:在函数入口处验证所有输入参数,尽早返回 D3DDDIERR_APPLICATIONERROR。
  2. 内部状态保护:若检测到不可恢复的驱动状态错误(如内存损坏),返回 E_INVALIDARG 并记录详细日志。
  3. 错误信息丰富化:通过 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 避免误判驱动缺陷。

本文标签: 调试输出编程错误代码