Direct3D11跨进程共享交换链后台缓冲为纹理时接口报错如何解决
问题根因与修复方案
你的代码存在几个核心错误,按优先级排序修复即可解决:
1. 直接修改交换链后台缓冲的描述符无效
从交换链GetBuffer拿到的后台缓冲是已经创建完成的资源,你后续修改tex_2d_desc的字段不会对已存在的纹理产生任何影响,交换链默认创建的后台缓冲没有携带共享所需的MiscFlags,也不支持CPU直接访问,这是你报错的核心原因。
推荐更兼容的方案:不直接共享交换链后台缓冲,新增一个自定义的共享纹理中转渲染结果:
// 1. 初始化阶段创建自定义共享纹理 D3D11_TEXTURE2D_DESC sharedTexDesc{}; // 从交换链后台缓冲拷贝格式、宽高等参数 tex_shared->GetDesc(&sharedTexDesc); // 仅保留必要的flag,删除CPU访问标记(共享纹理不支持CPU直接访问) sharedTexDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE; sharedTexDesc.CPUAccessFlags = 0; sharedTexDesc.Usage = D3D11_USAGE_DEFAULT; sharedTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; ComPtr<ID3D11Texture2D> m_sharedTex; HRESULT hr = m_device->CreateTexture2D(&sharedTexDesc, nullptr, &m_sharedTex); if (FAILED(hr)) { /* 此处添加错误处理逻辑 */ } // 2. 每帧渲染完后,把交换链后台缓冲拷贝到共享纹理 m_context->CopyResource(m_sharedTex.Get(), tex_shared.Get()); // 3. 给自定义共享纹理创建共享句柄,必须检查返回值 ComPtr<IDXGIResource1> pDxgiRes; hr = m_sharedTex.As(&pDxgiRes); if (FAILED(hr)) { /* 此处添加错误处理逻辑 */ } SECURITY_ATTRIBUTES sa{ sizeof(sa), NULL, FALSE }; HANDLE sharedHandle = nullptr; hr = pDxgiRes->CreateSharedHandle(&sa, GENERIC_ALL, L"Global\\SharedTexture", &sharedHandle); if (FAILED(hr)) { /* 此处添加错误处理逻辑,你之前的代码大概率这一步已经失败却没有捕获 */ }
2. 双显卡设备匹配错误
你的设备是双显卡笔记本,两个进程的D3D11设备必须由同一块显卡创建,不能一个用NVIDIA独显、一个用Intel核显,否则跨设备共享资源会失败。
修复方式:创建设备前先枚举DXGI适配器,强制两个进程选择同VendorID的显卡:
- NVIDIA独显VendorID:
0x10DE - Intel核显VendorID:
0x8086
3. 跨进程打开参数错误
如果使用OpenSharedResource1,需要先把第一个进程创建得到的sharedHandle通过进程间通信传递到第二个进程,不要优先用名字访问避免权限问题,打开时请求的UUID应为ID3D11Texture2D而非IDXGIResource1:
// 第二个进程打开逻辑 ComPtr<ID3D11Texture2D> pSharedTex; HRESULT hr = device->OpenSharedResource1( sharedHandle, // 从第一个进程传过来的共享句柄 DXGI_SHARED_RESOURCE_READ, __uuidof(ID3D11Texture2D), (void**)pSharedTex.GetAddressOf() ); if (FAILED(hr)) { /* 此处添加错误处理逻辑 */ }
额外注意事项
- 访问带
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX的纹理前,需要先调用IDXGIKeyedMutex::AcquireSync加锁,访问完成后调用ReleaseSync解锁,两个进程约定统一的key值避免访问冲突。 - 所有COM接口调用都必须检查
HRESULT返回值,可以快速定位到具体失败的步骤,而不是等到最后打开时报无意义的参数错误。
内容的提问来源于stack exchange,提问作者kingpin
相关产品推荐
相关产品推荐

