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

使用D3D12纹理作为D2D渲染目标触发验证错误,求助排查

问题描述

我尝试将D2D/DWrite内容绘制到一个将用作D3D12着色器资源的纹理中。为此,我参考示例创建了ID3D11On12Device,但不想映射D3D12后台缓冲区,而是自行创建纹理。

资源属性定义

D3D12_RESOURCE_DESC desc;
::ZeroMemory(&desc, sizeof(desc));
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.DepthOrArraySize = 1;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS;
desc.SampleDesc.Count = 1;

D3D12_HEAP_PROPERTIES heapProps;
::ZeroMemory(&heapProps, sizeof(heapProps));
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;

创建D3D12纹理

THROW_IF_FAILED(d3d12Device->CreateCommittedResource(
    &heapProps,
    D3D12_HEAP_FLAG_SHARED,
    &desc,
    D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE,
    &clear,
    ::IID_ID3D12Resource,
    this->d3d12Targets[i].put_void()));

我已按照相关说明设置了D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS和D3D12_HEAP_FLAG_SHARED。

创建包装资源时出错

执行以下代码创建包装资源:

D3D11_RESOURCE_FLAGS flags = { D3D11_BIND_RENDER_TARGET };
THROW_IF_FAILED(this->d3d11On12Device->CreateWrappedResource(
    this->d3d12Targets[i].get(),
    &flags,
    D3D12_RESOURCE_STATE_RENDER_TARGET,
    D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
    ::IID_ID3D11Resource,
    this->d3d11Targets[i].put_void()));

出现验证错误:

D3D12 ERROR: ID3D12CompatibilityDevice::ReflectSharedProperties: Resource provided was not shared by D3D11, or with a D3D11 desc. [ MISCELLANEOUS ERROR #916: REFLECTSHAREDPROPERTIES_INVALIDOBJECT]

请问我遗漏了什么?


解决方案

问题出在共享资源的创建模式上:ID3D11On12Device::CreateWrappedResource要求使用基于NT句柄的跨API共享模式,而非普通的D3D12共享资源标记。你需要调整资源和堆的标记,使其符合D3D11兼容的共享格式。

具体调整步骤

  1. 修改资源标记:在原有标记基础上添加D3D12_RESOURCE_FLAG_ALLOW_SHARED_NTHANDLE,这是D3D11On12能识别的共享标记。
  2. 修改堆标记:将D3D12_HEAP_FLAG_SHARED替换为D3D12_HEAP_FLAG_SHARED_NTHANDLE,匹配资源的共享模式。
  3. 调整初始资源状态:因为要通过D3D11On12绘制,初始状态设为D3D12_RESOURCE_STATE_RENDER_TARGET更合理,后续再转换为着色器资源状态。

调整后的代码

D3D12_RESOURCE_DESC desc;
::ZeroMemory(&desc, sizeof(desc));
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.DepthOrArraySize = 1;
// 添加上ALLOW_SHARED_NTHANDLE标记
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET 
            | D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS
            | D3D12_RESOURCE_FLAG_ALLOW_SHARED_NTHANDLE;
desc.SampleDesc.Count = 1;

D3D12_HEAP_PROPERTIES heapProps;
::ZeroMemory(&heapProps, sizeof(heapProps));
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;

// 使用SHARED_NTHANDLE堆标记
THROW_IF_FAILED(d3d12Device->CreateCommittedResource(
    &heapProps,
    D3D12_HEAP_FLAG_SHARED_NTHANDLE,
    &desc,
    D3D12_RESOURCE_STATE_RENDER_TARGET,
    &clear,
    ::IID_ID3D12Resource,
    this->d3d12Targets[i].put_void()));

核心原因

普通的D3D12共享资源(D3D12_HEAP_FLAG_SHARED)是为D3D12进程间共享设计的,无法被D3D11On12设备正确识别。而SHARED_NTHANDLE是专门为D3D11与D3D12跨API共享设计的模式,能让D3D11On12设备正确解析资源的共享属性,从而成功创建包装资源。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:35:05