You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用ID3D12Device::CreateCommittedResource时触发KernelBase.dll未处理异常

DX12 CreateCommittedResource抛出未处理异常但返回S_OK的排查与解决

问题背景

我用CMake 3.24.0搭配VS 2022搭建DX12渲染器,在通过UpdateBufferResource函数向GPU上传顶点数据时,调用CreateCommittedResource会触发未处理异常,但程序仍能继续执行,且该方法返回的HRESULT为S_OK。目前尝试渲染立方体,不清楚异常的成因及解决办法。

异常信息

Unhandled exception at 0x00007FFF69654FFC (KernelBase.dll) in Tutorial2.exe: 0x0000087A (parameters: 0x0000000000000002, 0x0000001291FDBED0, 0x0000001291FDDCA0).

相关代码

void Tutorial2::UpdateBufferResource(
    ComPtr<ID3D12GraphicsCommandList2> commandList,
    ID3D12Resource** pDestinationResource,
    ID3D12Resource** pIntermediateResource,
    size_t numElements, size_t elementSize, const void* bufferData,
    D3D12_RESOURCE_FLAGS flags)
{
    //ID3D12Device2
    auto device = Application::Get().GetDevice();

    size_t bufferSize = numElements * elementSize;

    // Create a committed resource for the GPU resource in a default heap.
    ThrowIfFailed(device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
        D3D12_HEAP_FLAG_NONE,
        &CD3DX12_RESOURCE_DESC::Buffer(bufferSize, flags),
        D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr,
        IID_PPV_ARGS(pDestinationResource)));

    // Some more bufferData upload....

}

可能的成因与解决办法

  • DX调试层配置问题:错误码0x87A属于DX12调试层相关错误,大概率是调试层未正确启用或组件缺失。先确认VS 2022已安装“Windows SDK调试工具”(通过「工具->获取工具和功能」检查),然后在设备初始化时添加调试层启用代码:
    ComPtr<ID3D12Debug> debugController;
    if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
    {
        debugController->EnableDebugLayer();
    }
    
  • 资源大小未对齐:DX12默认堆的缓冲区需要满足设备要求的对齐规则(通常是64KB,或通过device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)获取具体值)。计算缓冲区大小时要向上对齐:
    UINT64 requiredAlignment = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
    bufferSize = (bufferSize + requiredAlignment - 1) & ~(requiredAlignment - 1);
    
  • 指针参数异常:检查pDestinationResource是否为有效指针,调用函数前确保它指向的是nullptr,避免重复创建资源导致的内存冲突。
  • 资源状态或标志冲突:默认堆资源初始设为D3D12_RESOURCE_STATE_COPY_DEST是合理的,但要检查flags参数是否传入了冲突的标志(比如D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS却未匹配对应状态)。
  • 调试器误捕获:可能是VS调试器把DX调试层的警告当成了未处理异常。打开调试器的「异常设置」,取消勾选Win32 Exceptions下的0x87A即可忽略这类非致命调试信息。

内容的提问来源于stack exchange,提问作者parthc_211

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:03:13