调用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
相关产品推荐
相关产品推荐

