与另一个单独的进程共享来自交换链后台缓冲区的 direct3d11 渲染帧作为纹理
Posted
技术标签:
【中文标题】与另一个单独的进程共享来自交换链后台缓冲区的 direct3d11 渲染帧作为纹理【英文标题】:Share direct3d11 rendered frame from swapchain backbuffer as texture with another separate process 【发布时间】:2021-12-30 18:01:48 【问题描述】:所以我会详细说明标题
我想要完成的是在一个进程中完成所有计算和渲染,然后从另一个进程中读取结果帧(在所有计算完成后,我将在出现之前使用交换链后台缓冲区)并将其显示在显示器上。基本上我想在两个单独的进程之间共享视频内存(不是整个屏幕,只是应用程序窗口)。
我正在使用带有 DirectXTK 的 direct3d11。我的笔记本电脑有 NVIDIA gpu 和 intel UHD 620 graphics 。 以管理员权限打开了 Visual Studio。
这是我尝试创建缓冲区共享句柄的代码
auto swapChain = m_deviceResources->GetSwapChain();
/*ComPtr< ID3D11Resource> backbuffer;*/
/*swapChain->GetBuffer(0, __uuidof(ID3D11Resource),
(void **) backbuffer.GetAddressOf());*/
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),(void **)tex_shared.GetAddressOf());
D3D11_TEXTURE2D_DESC tex_2d_desc;
tex_shared->GetDesc(&tex_2d_desc);
tex_2d_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
tex_2d_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
HANDLE sharedhandle=nullptr;
IDXGIResource1* pOtherResource=nullptr;
tex_shared->QueryInterface(__uuidof(IDXGIResource1), (void**)&pOtherResource);
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = FALSE;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
pOtherResource->CreateSharedHandle(&sa,GENERIC_ALL,L"SharedTexture" ,&sharedhandle);
我尝试从另一个进程中使用此代码检索句柄
ComPtr<IDXGIResource1> p_tex_shared;
device->OpenSharedResourceByName(L"SharedTexture",
DXGI_SHARED_RESOURCE_READ ,
__uuidof(IDXGIResource1),
(void**)p_tex_shared.GetAddressOf());
但我得到了这个错误
Exception thrown at 0x00007FF84751466C in SimpleTrianglePC.exe: Microsoft C++ exception: _com_error at memory location 0x000000139CEFF248.
D3D11 ERROR: ID3D11Device::OpenSharedResourceByName: Returning E_INVALIDARG, meaning
invalid parameters were passed. [ STATE_CREATION ERROR #381:
DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN]
D3D11: **BREAK** enabled for the previous message, which was: [ ERROR STATE_CREATION
Exception thrown at 0x00007FF84751466C (KernelBase.dll) in SimpleTrianglePC.exe:
0x0000087A (parameters: 0x0000000000000001, 0x000000139CEFC500, 0x000000139CEFE2D0).
Unhandled exception at 0x00007FF84751466C (KernelBase.dll) in SimpleTrianglePC.exe:
0x0000087A (parameters: 0x0000000000000001, 0x000000139CEFC500, 0x000000139CEFE2D0).
我也尝试使用 OpenSharedResource1 而不是 OpenSharedResourceByName,但给出了同样的错误。
【问题讨论】:
您是否尝试为 CreateSharedHandle 的第一个参数 (sa) 和 DXGI_SHARED_RESOURCE_READ 而不是 GENERIC_ALL 传递 null 而不是某些东西? @SimonMourier 我刚刚尝试过,但报同样的错误。 【参考方案1】:您无法修改 DXGI 交换链拥有的纹理表面来添加共享标志,就像您在上面尝试做的那样。您最好的选择是将后备缓冲区复制到可共享的纹理中。
-
使用与交换链后台缓冲区相同的大小和格式创建可共享纹理。
获取 DXGI 后缓冲纹理
使用
ID3D11DeviceContext::CopyResource
将上下文从后台缓冲区复制到每帧的可共享纹理。
见Microsoft Docs
【讨论】:
感谢@Chuck Walbourn。如何完成将后台缓冲区复制到可共享纹理。以上是关于与另一个单独的进程共享来自交换链后台缓冲区的 direct3d11 渲染帧作为纹理的主要内容,如果未能解决你的问题,请参考以下文章