mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Don't mix GPU adapters across processes. (bug 1183910 part 10, r=jmuizelaar)
This commit is contained in:
parent
0739f752c2
commit
b428af7892
@ -8,6 +8,20 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gfx {
|
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
|
struct DeviceInitData
|
||||||
{
|
{
|
||||||
bool useAcceleration;
|
bool useAcceleration;
|
||||||
@ -19,6 +33,7 @@ struct DeviceInitData
|
|||||||
bool d3d11TextureSharingWorks;
|
bool d3d11TextureSharingWorks;
|
||||||
bool useD2D;
|
bool useD2D;
|
||||||
bool useD2D1;
|
bool useD2D1;
|
||||||
|
DxgiDesc dxgiDesc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
@ -1708,25 +1708,35 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
|
|||||||
return true;
|
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
|
static void
|
||||||
CheckForAdapterMismatch(ID3D11Device *device)
|
CheckForAdapterMismatch(ID3D11Device *device)
|
||||||
{
|
{
|
||||||
nsRefPtr<IDXGIDevice> dxgiDevice;
|
DXGI_ADAPTER_DESC desc;
|
||||||
if (FAILED(device->QueryInterface(__uuidof(IDXGIDevice),
|
PodZero(&desc);
|
||||||
getter_AddRefs(dxgiDevice)))) {
|
GetDxgiDesc(device, &desc);
|
||||||
return;
|
|
||||||
}
|
|
||||||
nsRefPtr<IDXGIAdapter> dxgiAdapter;
|
|
||||||
if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||||
nsString vendorID;
|
nsString vendorID;
|
||||||
gfxInfo->GetAdapterVendorID(vendorID);
|
gfxInfo->GetAdapterVendorID(vendorID);
|
||||||
nsresult ec;
|
nsresult ec;
|
||||||
int32_t vendor = vendorID.ToInteger(&ec, 16);
|
int32_t vendor = vendorID.ToInteger(&ec, 16);
|
||||||
DXGI_ADAPTER_DESC desc;
|
|
||||||
dxgiAdapter->GetDesc(&desc);
|
|
||||||
if (vendor != desc.VendorId) {
|
if (vendor != desc.VendorId) {
|
||||||
gfxCriticalNote << "VendorIDMismatch " << hexa(vendor) << " " << hexa(desc.VendorId);
|
gfxCriticalNote << "VendorIDMismatch " << hexa(vendor) << " " << hexa(desc.VendorId);
|
||||||
}
|
}
|
||||||
@ -2051,6 +2061,29 @@ gfxWindowsPlatform::AttemptWARPDeviceCreation()
|
|||||||
mIsWARP = true;
|
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
|
bool
|
||||||
gfxWindowsPlatform::AttemptD3D11ContentDeviceCreation()
|
gfxWindowsPlatform::AttemptD3D11ContentDeviceCreation()
|
||||||
{
|
{
|
||||||
@ -2085,10 +2118,14 @@ gfxWindowsPlatform::AttemptD3D11ContentDeviceCreation()
|
|||||||
// binding the parent and child processes to different GPUs. As a safety net,
|
// 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.
|
// we re-check texture sharing against the newly created D3D11 content device.
|
||||||
// If it fails, we won't use Direct2D.
|
// If it fails, we won't use Direct2D.
|
||||||
if (XRE_IsContentProcess() && !DoesD3D11TextureSharingWork(mD3D11ContentDevice)) {
|
if (XRE_IsContentProcess()) {
|
||||||
|
if (!DoesD3D11TextureSharingWork(mD3D11ContentDevice) ||
|
||||||
|
!ContentAdapterIsParentAdapter(mD3D11ContentDevice))
|
||||||
|
{
|
||||||
mD3D11ContentDevice = nullptr;
|
mD3D11ContentDevice = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mD3D11ContentDevice->SetExceptionMode(0);
|
mD3D11ContentDevice->SetExceptionMode(0);
|
||||||
|
|
||||||
@ -2119,7 +2156,9 @@ gfxWindowsPlatform::AttemptD3D11ImageBridgeDeviceCreation()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mD3D11ImageBridgeDevice->SetExceptionMode(0);
|
mD3D11ImageBridgeDevice->SetExceptionMode(0);
|
||||||
if (!DoesD3D11AlphaTextureSharingWork(mD3D11ImageBridgeDevice)) {
|
if (!DoesD3D11AlphaTextureSharingWork(mD3D11ImageBridgeDevice) ||
|
||||||
|
(XRE_IsContentProcess() && !ContentAdapterIsParentAdapter(mD3D11ImageBridgeDevice)))
|
||||||
|
{
|
||||||
mD3D11ImageBridgeDevice = nullptr;
|
mD3D11ImageBridgeDevice = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2725,4 +2764,17 @@ gfxWindowsPlatform::GetDeviceInitData(DeviceInitData* aOut)
|
|||||||
aOut->useD3D11WARP() = mIsWARP;
|
aOut->useD3D11WARP() = mIsWARP;
|
||||||
aOut->useD2D() = (GetD2DStatus() == FeatureStatus::Available);
|
aOut->useD2D() = (GetD2DStatus() == FeatureStatus::Available);
|
||||||
aOut->useD2D1() = (GetD2D1Status() == 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();
|
void AttemptD3D11ImageBridgeDeviceCreation();
|
||||||
bool AttemptD3D11ContentDeviceCreation();
|
bool AttemptD3D11ContentDeviceCreation();
|
||||||
bool CanUseD3D11ImageBridge();
|
bool CanUseD3D11ImageBridge();
|
||||||
|
bool ContentAdapterIsParentAdapter(ID3D11Device* device);
|
||||||
|
|
||||||
IDXGIAdapter1 *GetDXGIAdapter();
|
IDXGIAdapter1 *GetDXGIAdapter();
|
||||||
bool IsDeviceReset(HRESULT hr, DeviceResetReason* aReason);
|
bool IsDeviceReset(HRESULT hr, DeviceResetReason* aReason);
|
||||||
|
Loading…
Reference in New Issue
Block a user