0

所以我会详细说明标题

我想要完成的是在一个进程中完成所有计算和渲染,然后从另一个进程读取结果帧(当所有计算完成时,我将在出现之前使用交换链后台缓冲区)并将其显示在显示器上。基本上我想在两个单独的进程之间共享视频内存(不是整个屏幕只是应用程序窗口)。

我正在使用带有 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但给出了同样的错误。

4

1 回答 1

1

您不能像上面尝试的那样修改 DXGI 交换链拥有的纹理表面来添加共享标志。您最好的选择是需要将后台缓冲区复制到可共享的纹理中。

  1. 使用与交换链后台缓冲区相同的大小和格式创建可共享纹理。
  2. 获取 DXGI 后缓冲纹理
  3. 用于ID3D11DeviceContext::CopyResource将上下文从后台缓冲区复制到每帧的可共享纹理。

请参阅Microsoft 文档

于 2021-11-30T05:36:03.173 回答