mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Don't mix GPU adapters across processes. (bug 1183910 part 10, r=jmuizelaar)
This commit is contained in:
parent
fd1fcf1481
commit
5953408ea9
@ -8,6 +8,20 @@
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
struct DxgiLUID
|
||||
{
|
||||
uint32_t LowPart;
|
||||
int32_t HighPart;
|
||||
};
|
||||
|
||||
struct DxgiDesc
|
||||
{
|
||||
uint32_t vendorID;
|
||||
uint32_t deviceID;
|
||||
uint32_t subSysID;
|
||||
DxgiLUID luid;
|
||||
};
|
||||
|
||||
struct DeviceInitData
|
||||
{
|
||||
bool useAcceleration;
|
||||
@ -19,6 +33,7 @@ struct DeviceInitData
|
||||
bool d3d11TextureSharingWorks;
|
||||
bool useD2D;
|
||||
bool useD2D1;
|
||||
DxgiDesc dxgiDesc;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -1708,25 +1708,35 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out)
|
||||
{
|
||||
nsRefPtr<IDXGIDevice> dxgiDevice;
|
||||
HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<IDXGIAdapter> dxgiAdapter;
|
||||
if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return SUCCEEDED(dxgiAdapter->GetDesc(out));
|
||||
}
|
||||
|
||||
static void
|
||||
CheckForAdapterMismatch(ID3D11Device *device)
|
||||
{
|
||||
nsRefPtr<IDXGIDevice> dxgiDevice;
|
||||
if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice),
|
||||
getter_AddRefs(dxgiDevice)))) {
|
||||
return;
|
||||
}
|
||||
nsRefPtr<IDXGIAdapter> dxgiAdapter;
|
||||
if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
|
||||
return;
|
||||
}
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
PodZero(&desc);
|
||||
GetDxgiDesc(device, &desc);
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
nsString vendorID;
|
||||
gfxInfo->GetAdapterVendorID(vendorID);
|
||||
nsresult ec;
|
||||
int32_t vendor = vendorID.ToInteger(&ec, 16);
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
dxgiAdapter->GetDesc(&desc);
|
||||
if (vendor != desc.VendorId) {
|
||||
gfxCriticalNote << "VendorIDMismatch " << hexa(vendor) << " " << hexa(desc.VendorId);
|
||||
}
|
||||
@ -2051,6 +2061,29 @@ gfxWindowsPlatform::AttemptWARPDeviceCreation()
|
||||
mIsWARP = true;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::ContentAdapterIsParentAdapter(ID3D11Device* device)
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
if (!GetDxgiDesc(device, &desc)) {
|
||||
gfxCriticalNote << "Could not query device DXGI adapter info";
|
||||
return false;
|
||||
}
|
||||
|
||||
const DxgiDesc& parent = GetParentDevicePrefs().dxgiDesc();
|
||||
if (desc.VendorId != parent.vendorID() ||
|
||||
desc.DeviceId != parent.deviceID() ||
|
||||
desc.SubSysId != parent.subSysID() ||
|
||||
desc.AdapterLuid.HighPart != parent.luid().HighPart() ||
|
||||
desc.AdapterLuid.LowPart != parent.luid().LowPart())
|
||||
{
|
||||
gfxCriticalNote << "VendorIDMismatch " << hexa(parent.vendorID()) << " " << hexa(desc.VendorId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::AttemptD3D11ContentDeviceCreation()
|
||||
{
|
||||
@ -2085,9 +2118,13 @@ gfxWindowsPlatform::AttemptD3D11ContentDeviceCreation()
|
||||
// binding the parent and child processes to different GPUs. As a safety net,
|
||||
// we re-check texture sharing against the newly created D3D11 content device.
|
||||
// If it fails, we won't use Direct2D.
|
||||
if (XRE_IsContentProcess() && !DoesD3D11TextureSharingWork(mD3D11ContentDevice)) {
|
||||
mD3D11ContentDevice = nullptr;
|
||||
return false;
|
||||
if (XRE_IsContentProcess()) {
|
||||
if (!DoesD3D11TextureSharingWork(mD3D11ContentDevice) ||
|
||||
!ContentAdapterIsParentAdapter(mD3D11ContentDevice))
|
||||
{
|
||||
mD3D11ContentDevice = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mD3D11ContentDevice->SetExceptionMode(0);
|
||||
@ -2119,7 +2156,9 @@ gfxWindowsPlatform::AttemptD3D11ImageBridgeDeviceCreation()
|
||||
}
|
||||
|
||||
mD3D11ImageBridgeDevice->SetExceptionMode(0);
|
||||
if (!DoesD3D11AlphaTextureSharingWork(mD3D11ImageBridgeDevice)) {
|
||||
if (!DoesD3D11AlphaTextureSharingWork(mD3D11ImageBridgeDevice) ||
|
||||
(XRE_IsContentProcess() && !ContentAdapterIsParentAdapter(mD3D11ImageBridgeDevice)))
|
||||
{
|
||||
mD3D11ImageBridgeDevice = nullptr;
|
||||
return;
|
||||
}
|
||||
@ -2725,4 +2764,17 @@ gfxWindowsPlatform::GetDeviceInitData(DeviceInitData* aOut)
|
||||
aOut->useD3D11WARP() = mIsWARP;
|
||||
aOut->useD2D() = (GetD2DStatus() == FeatureStatus::Available);
|
||||
aOut->useD2D1() = (GetD2D1Status() == FeatureStatus::Available);
|
||||
|
||||
if (mD3D11Device) {
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
if (!GetDxgiDesc(mD3D11Device, &desc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aOut->dxgiDesc().vendorID() = desc.VendorId;
|
||||
aOut->dxgiDesc().deviceID() = desc.DeviceId;
|
||||
aOut->dxgiDesc().subSysID() = desc.SubSysId;
|
||||
aOut->dxgiDesc().luid().LowPart() = desc.AdapterLuid.LowPart;
|
||||
aOut->dxgiDesc().luid().HighPart() = desc.AdapterLuid.HighPart;
|
||||
}
|
||||
}
|
||||
|
@ -323,6 +323,7 @@ private:
|
||||
void AttemptD3D11ImageBridgeDeviceCreation();
|
||||
bool AttemptD3D11ContentDeviceCreation();
|
||||
bool CanUseD3D11ImageBridge();
|
||||
bool ContentAdapterIsParentAdapter(ID3D11Device* device);
|
||||
|
||||
IDXGIAdapter1 *GetDXGIAdapter();
|
||||
bool IsDeviceReset(HRESULT hr, DeviceResetReason* aReason);
|
||||
|
Loading…
Reference in New Issue
Block a user