为什么在使用 CopyResource 跨 ID3D11Devices 共享纹理时会出现视频内存泄漏?

如何解决为什么在使用 CopyResource 跨 ID3D11Devices 共享纹理时会出现视频内存泄漏?

  • 我创建了两个设备 A 和 B,其中 A 是生产者,B 是消费者。纹理在两者之间通过 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX 共享。现在我发现每次B调用copyResource将共享纹理复制到本地时,显存会不断增加。这个问题困扰了我很久。我搜索了github或其他代码源,但找不到解决方案。我的机器是Win10和Geforce GTX 1060。

  • 重现问题最精简的代码如下:

     #include <dxgi.h>
     #include <d3d11.h>
     #include <atlbase.h>
     #pragma comment(lib,"D3D11.lib")
    
     #define RETURN_ON_FAIL(hr)    if(Failed(hr)) return hr;
    
     namespace SharedTextureLeakTest
     {
     const UINT32 texture_width = 320;
     const UINT32 texture_height = 240;
    
     ATL::CComPtr<ID3D11Device>          device_1 = nullptr;
     ATL::CComPtr<ID3D11DeviceContext>   context_1 = nullptr;
     ATL::CComPtr<ID3D11Device>          device_2 = nullptr;
     ATL::CComPtr<ID3D11DeviceContext>   context_2 = nullptr;
     ATL::CComPtr<ID3D11Texture2D>       shared_texture_dev1 = nullptr;  //owner by device1
     ATL::CComPtr<ID3D11Texture2D>       dst_texture_dev2 = nullptr; //owner by device2
     HANDLE  shared_handle = nullptr;
    
     HRESULT CheckEnvironmentValid()
     {
         HRESULT hr = S_OK;
    
         //Create Device1
         if (!device_1)
         {
             D3D_FEATURE_LEVEL pFeatureLevel;
             UINT Flags = D3D11_CREATE_DEVICE_DEBUG;
             hr = ::D3D11CreateDevice(nullptr,D3D_DRIVER_TYPE_HARDWARE,nullptr,Flags,D3D11_SDK_VERSION,&device_1,&pFeatureLevel,&context_1);
             if (Failed(hr)) 
             {
                 device_1 = nullptr;
                 return hr;
             }
         }
    
         //Create Shared Texture
         if (!shared_texture_dev1)
         {
             D3D11_TEXTURE2D_DESC desc;
             desc.ArraySize = 1;
             desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
             desc.cpuAccessFlags = 0;
             desc.Format = dxgi_FORMAT_B8G8R8A8_UnorM;
             desc.Width = texture_width;
             desc.Height = texture_height;
             desc.MipLevels = 1;
             desc.Usage = D3D11_USAGE_DEFAULT;
             desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
             desc.SampleDesc.Count = 1;
             desc.SampleDesc.Quality = 0;
    
             hr = device_1->CreateTexture2D(&desc,&shared_texture_dev1);
             RETURN_ON_FAIL(hr);
         }
    
         //Get Handle of Shared Texture
         if (!shared_handle)
         {
             ATL::CComPtr<IdxgiResource> dxgi_res;
             hr = shared_texture_dev1->QueryInterface(__uuidof(IdxgiResource),(void**)&dxgi_res);
             RETURN_ON_FAIL(hr);
    
             hr = dxgi_res->GetSharedHandle(&shared_handle);
             RETURN_ON_FAIL(hr);
         }
    
         //Create Device2
         if (!device_2)
         {
             D3D_FEATURE_LEVEL pFeatureLevel;
             UINT Flags = D3D11_CREATE_DEVICE_DEBUG;
             hr = ::D3D11CreateDevice(nullptr,&device_2,&context_2);
             if (Failed(hr))
             {
                 device_2= nullptr;
                 return hr;
             }
         }
    
         //Create Dst Texture
         if (!dst_texture_dev2)
         {
             D3D11_TEXTURE2D_DESC desc;
             desc.ArraySize = 1;
             desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
             desc.cpuAccessFlags = 0;
             desc.Format = dxgi_FORMAT_B8G8R8A8_UnorM;
             desc.Width = texture_width;
             desc.Height = texture_height;
             desc.MipLevels = 1;
             desc.Usage = D3D11_USAGE_DEFAULT;
             desc.MiscFlags = 0;
             desc.SampleDesc.Count = 1;
             desc.SampleDesc.Quality = 0;
    
             hr = device_2->CreateTexture2D(&desc,&dst_texture_dev2);
             RETURN_ON_FAIL(hr);
         }
    
         return hr;
     }
    
     HRESULT LoopOncetest()
     {
         HRESULT hr = CheckEnvironmentValid();
         RETURN_ON_FAIL(hr);
    
         //Open Shared Texture
         ATL::CComPtr<ID3D11Texture2D>   shared_texture_dev2;
         hr = device_2->OpenSharedResource(shared_handle,IID_PPV_ARGS(&shared_texture_dev2));
         RETURN_ON_FAIL(hr);
    
         //copy
         do
         {
             CComPtr<IdxgiKeyedMutex> km;
             hr = shared_texture_dev2->QueryInterface(__uuidof(IdxgiKeyedMutex),(void**)&km);
             RETURN_ON_FAIL(hr);
    
             INT64 release_key = 0;
             hr = km->AcquireSync(0,10);
             RETURN_ON_FAIL(hr);
    
             if (hr == WAIT_OBJECT_0)
             {
                 context_2->copyResource(dst_texture_dev2,shared_texture_dev2);
             //  context_2->Flush();
             }
    
             hr = km->ReleaseSync(0);
             RETURN_ON_FAIL(hr);
    
         } while (FALSE);
    
         return hr;
     }
     }
    
     void Dotest()
     {
         for(;;)
         {
              SharedTextureLeakTest::LoopOncetest();
              Sleep(1000);
         }
     }
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?