该系统是一台笔记本电脑,带有2个GPU,运行Windows 10的Intel UHD 630,NVIDIA GTX 1070。
我的应用正在使用D3D 11,并且在驱动程序属性中未将其标记为“使用高性能nVidia图形”,但我无法对其进行标记,请参见this support article原因。
我需要将2D纹理从Intel传递到Nvidia GPU。无法执行此操作,因为ID3D11Device::OpenSharedResource
返回E_INVALIDARG
时,即使在调试运行时也没有来自运行时的更多信息。
尝试在任一GPU上创建纹理并在另一个GPU上打开,升级到D3D 11.1,并使用NT手柄代替普通手柄,切换到更兼容的RGBA格式而不是BGRA(均支持BGRA的设备),并指定SHADER_RESOURCE和the docs的“从D3D9到D3D11共享纹理”部分中所写的RENDER_TARGET绑定标志,仍然是相同的结果。
这是代码:
HRESULT createSharedTexture( ID3D11Device* device1, ID3D11Device* device2, const CSize& size, ID3D11Texture2D** ppTexture1, ID3D11Texture2D** ppTexture2 )
{
D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory( &texDesc, sizeof( texDesc ) );
texDesc.Width = (UINT)size.cx;
texDesc.Height = (UINT)size.cy;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texDesc.BindFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
CComPtr<ID3D11Texture2D> tex1, tex2;
CHECK( device1->CreateTexture2D( &texDesc, nullptr, &tex1 ) );
CComQIPtr<IDXGIResource> res = tex1.operator ->();
HANDLE h = nullptr;
CHECK( res->GetSharedHandle( &h ) );
// The following line always fails
CHECK( device2->OpenSharedResource( h, IID_PPV_ARGS( &tex2 ) ) );
*ppTexture1 = tex1.Detach();
*ppTexture2 = tex2.Detach();
return S_OK;
}
我以为Windows刚刚关闭了Nvidia GPU的电源,但是不,我能够在两个GPU上进行渲染,并通过系统RAM在它们之间复制数据。但是该复制太慢了,无法满足我的要求,我正在以140 FPS的速度复制FullHD纹理,从过渡到动态纹理,并观察Nvidia用户模式GPU驱动程序的CPU使用率。