зеркало из https://github.com/AvaloniaUI/angle.git
Refactor D3D device creation to make adapter selection explicit
To prepare for future changes which require that angle features be parsed before device creation, we must rearrange device creation such that driver version can be retrieved from the adapter BEFORE the device gets created. Bug: angleproject:8180 Change-Id: I08855b9df318d0a6234231f1e52d3c17cfaa8a30 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4575653 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
This commit is contained in:
Родитель
31aa3fa5da
Коммит
4500079d34
|
@ -440,7 +440,6 @@ Renderer11::Renderer11(egl::Display *display)
|
|||
|
||||
mD3d11Module = nullptr;
|
||||
mD3d12Module = nullptr;
|
||||
mDxgiModule = nullptr;
|
||||
mDCompModule = nullptr;
|
||||
mCreatedWithDeviceEXT = false;
|
||||
|
||||
|
@ -542,6 +541,7 @@ egl::Error Renderer11::initialize()
|
|||
{
|
||||
HRESULT result = S_OK;
|
||||
|
||||
ANGLE_TRY(initializeDXGIAdapter());
|
||||
ANGLE_TRY(initializeD3DDevice());
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
|
||||
|
@ -587,22 +587,6 @@ egl::Error Renderer11::initialize()
|
|||
mDeviceContext.As(&mDeviceContext1);
|
||||
mDeviceContext.As(&mDeviceContext3);
|
||||
|
||||
angle::ComPtr<IDXGIDevice> dxgiDevice;
|
||||
result = mDevice.As(&dxgiDevice);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) << "Could not query DXGI device.";
|
||||
}
|
||||
|
||||
result = dxgiDevice->GetParent(IID_PPV_ARGS(&mDxgiAdapter));
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
|
||||
<< "Could not retrieve DXGI adapter";
|
||||
}
|
||||
|
||||
angle::ComPtr<IDXGIAdapter2> dxgiAdapter2;
|
||||
mDxgiAdapter.As(&dxgiAdapter2);
|
||||
|
||||
|
@ -688,23 +672,72 @@ egl::Error Renderer11::initialize()
|
|||
|
||||
HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug)
|
||||
{
|
||||
angle::ComPtr<IDXGIAdapter> adapter;
|
||||
// If adapter is not nullptr, the driver type must be D3D_DRIVER_TYPE_UNKNOWN or
|
||||
// D3D11CreateDevice will return E_INVALIDARG.
|
||||
return createDevice(
|
||||
mDxgiAdapter.Get(), mDxgiAdapter ? D3D_DRIVER_TYPE_UNKNOWN : mRequestedDriverType, nullptr,
|
||||
debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
|
||||
static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mDevice,
|
||||
&(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
|
||||
}
|
||||
|
||||
const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
|
||||
// Check EGL_ANGLE_platform_angle_d3d_luid
|
||||
long high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0));
|
||||
unsigned long low =
|
||||
static_cast<unsigned long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0));
|
||||
// Check EGL_ANGLE_platform_angle_device_id
|
||||
if (high == 0 && low == 0)
|
||||
egl::Error Renderer11::initializeDXGIAdapter()
|
||||
{
|
||||
if (mCreatedWithDeviceEXT)
|
||||
{
|
||||
high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0));
|
||||
low = static_cast<unsigned long>(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0));
|
||||
ASSERT(mRequestedDriverType == D3D_DRIVER_TYPE_UNKNOWN);
|
||||
|
||||
DeviceD3D *deviceD3D = GetImplAs<DeviceD3D>(mDisplay->getDevice());
|
||||
ASSERT(deviceD3D != nullptr);
|
||||
|
||||
// We should use the inputted D3D11 device instead
|
||||
void *device = nullptr;
|
||||
ANGLE_TRY(deviceD3D->getAttribute(mDisplay, EGL_D3D11_DEVICE_ANGLE, &device));
|
||||
|
||||
ID3D11Device *d3dDevice = static_cast<ID3D11Device *>(device);
|
||||
if (FAILED(d3dDevice->GetDeviceRemovedReason()))
|
||||
{
|
||||
return egl::EglNotInitialized() << "Inputted D3D11 device has been lost.";
|
||||
}
|
||||
|
||||
if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
return egl::EglNotInitialized()
|
||||
<< "Inputted D3D11 device must be Feature Level 9_3 or greater.";
|
||||
}
|
||||
|
||||
// The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does.
|
||||
mDevice = d3dDevice;
|
||||
mDevice->GetImmediateContext(&mDeviceContext);
|
||||
mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel();
|
||||
|
||||
return initializeAdapterFromDevice();
|
||||
}
|
||||
if (high != 0 || low != 0)
|
||||
else
|
||||
{
|
||||
angle::ComPtr<IDXGIFactory1> factory;
|
||||
if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
|
||||
<< "Could not create DXGI factory";
|
||||
}
|
||||
|
||||
// If the developer requests a specific adapter, honor their request regardless of the value
|
||||
// of EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE.
|
||||
const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
|
||||
// Check EGL_ANGLE_platform_angle_d3d_luid
|
||||
long high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0));
|
||||
unsigned long low =
|
||||
static_cast<unsigned long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0));
|
||||
// Check EGL_ANGLE_platform_angle_device_id
|
||||
if (high == 0 && low == 0)
|
||||
{
|
||||
high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0));
|
||||
low = static_cast<unsigned long>(
|
||||
attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0));
|
||||
}
|
||||
if (high != 0 || low != 0)
|
||||
{
|
||||
angle::ComPtr<IDXGIAdapter> temp;
|
||||
for (UINT i = 0; SUCCEEDED(factory->EnumAdapters(i, &temp)); i++)
|
||||
|
@ -715,7 +748,7 @@ HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice,
|
|||
// EGL_ANGLE_platform_angle_d3d_luid
|
||||
if (desc.AdapterLuid.HighPart == high && desc.AdapterLuid.LowPart == low)
|
||||
{
|
||||
adapter = temp;
|
||||
mDxgiAdapter = std::move(temp);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -726,49 +759,82 @@ HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice,
|
|||
if ((high == 0 || desc.VendorId == static_cast<UINT>(high)) &&
|
||||
(low == 0 || desc.DeviceId == static_cast<UINT>(low)))
|
||||
{
|
||||
adapter = temp;
|
||||
mDxgiAdapter = std::move(temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For requested driver types besides Hardware such as Warp, Reference, or Null
|
||||
// allow D3D11CreateDevice to pick the adapter by passing it the driver type.
|
||||
if (!mDxgiAdapter && mRequestedDriverType == D3D_DRIVER_TYPE_HARDWARE)
|
||||
{
|
||||
hr = factory->EnumAdapters(0, &mDxgiAdapter);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
|
||||
<< "Could not retrieve DXGI adapter";
|
||||
}
|
||||
}
|
||||
}
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
egl::Error Renderer11::initializeAdapterFromDevice()
|
||||
{
|
||||
ASSERT(mDevice);
|
||||
ASSERT(!mDxgiAdapter);
|
||||
|
||||
angle::ComPtr<IDXGIDevice> dxgiDevice;
|
||||
HRESULT result = mDevice.As(&dxgiDevice);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) << "Could not query DXGI device.";
|
||||
}
|
||||
|
||||
// If adapter is not nullptr, the driver type must be D3D_DRIVER_TYPE_UNKNOWN or
|
||||
// D3D11CreateDevice will return E_INVALIDARG.
|
||||
return createDevice(
|
||||
adapter.Get(), adapter ? D3D_DRIVER_TYPE_UNKNOWN : mRequestedDriverType, nullptr,
|
||||
debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
|
||||
static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mDevice,
|
||||
&(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
|
||||
result = dxgiDevice->GetParent(IID_PPV_ARGS(&mDxgiAdapter));
|
||||
if (FAILED(result))
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) << "Could not retrieve DXGI adapter";
|
||||
}
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
HRESULT Renderer11::callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
|
||||
PFN_D3D11ON12_CREATE_DEVICE createDevice11on12,
|
||||
bool debug)
|
||||
{
|
||||
angle::ComPtr<IDXGIFactory4> factory;
|
||||
HRESULT result = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
|
||||
if (FAILED(result))
|
||||
HRESULT result = S_OK;
|
||||
if (mDxgiAdapter)
|
||||
{
|
||||
return result;
|
||||
// Passing nullptr into pAdapter chooses the default adapter which will be the hardware
|
||||
// adapter if it exists.
|
||||
result = createDevice12(mDxgiAdapter.Get(), mAvailableFeatureLevels[0],
|
||||
IID_PPV_ARGS(&mDevice12));
|
||||
}
|
||||
|
||||
if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
|
||||
else if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
|
||||
{
|
||||
angle::ComPtr<IDXGIAdapter> warpAdapter;
|
||||
result = factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
|
||||
angle::ComPtr<IDXGIFactory4> factory;
|
||||
result = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
|
||||
if (FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = factory->EnumWarpAdapter(IID_PPV_ARGS(&mDxgiAdapter));
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = createDevice12(warpAdapter.Get(), mAvailableFeatureLevels[0],
|
||||
result = createDevice12(mDxgiAdapter.Get(), mAvailableFeatureLevels[0],
|
||||
IID_PPV_ARGS(&mDevice12));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Passing nullptr into pAdapter chooses the default adapter which will be the hardware
|
||||
// adapter if it exists.
|
||||
result = createDevice12(nullptr, mAvailableFeatureLevels[0], IID_PPV_ARGS(&mDevice12));
|
||||
ASSERT(mRequestedDriverType == D3D_DRIVER_TYPE_REFERENCE ||
|
||||
mRequestedDriverType == D3D_DRIVER_TYPE_NULL);
|
||||
result = E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
|
@ -804,7 +870,6 @@ egl::Error Renderer11::initializeD3DDevice()
|
|||
PFN_D3D11ON12_CREATE_DEVICE D3D11On12CreateDevice = nullptr;
|
||||
{
|
||||
ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)");
|
||||
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
|
||||
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
|
||||
mDCompModule = LoadLibrary(TEXT("dcomp.dll"));
|
||||
|
||||
|
@ -842,10 +907,10 @@ egl::Error Renderer11::initializeD3DDevice()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (mD3d11Module == nullptr || mDxgiModule == nullptr)
|
||||
if (mD3d11Module == nullptr)
|
||||
{
|
||||
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
|
||||
<< "Could not load D3D11 or DXGI library.";
|
||||
<< "Could not load D3D11 library.";
|
||||
}
|
||||
|
||||
D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
|
||||
|
@ -935,33 +1000,13 @@ egl::Error Renderer11::initializeD3DDevice()
|
|||
<< "Could not create D3D11 device.";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceD3D *deviceD3D = GetImplAs<DeviceD3D>(mDisplay->getDevice());
|
||||
ASSERT(deviceD3D != nullptr);
|
||||
|
||||
// We should use the inputted D3D11 device instead
|
||||
void *device = nullptr;
|
||||
ANGLE_TRY(deviceD3D->getAttribute(mDisplay, EGL_D3D11_DEVICE_ANGLE, &device));
|
||||
|
||||
ID3D11Device *d3dDevice = static_cast<ID3D11Device *>(device);
|
||||
if (FAILED(d3dDevice->GetDeviceRemovedReason()))
|
||||
if (!mDxgiAdapter)
|
||||
{
|
||||
return egl::EglNotInitialized() << "Inputted D3D11 device has been lost.";
|
||||
// If the D3D11CreateDevice was asked to create the adapter via mRequestedDriverType,
|
||||
// fill in the adapter here.
|
||||
ANGLE_TRY(initializeAdapterFromDevice());
|
||||
}
|
||||
|
||||
if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3)
|
||||
{
|
||||
return egl::EglNotInitialized()
|
||||
<< "Inputted D3D11 device must be Feature Level 9_3 or greater.";
|
||||
}
|
||||
|
||||
// The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does.
|
||||
mDevice = d3dDevice;
|
||||
mDevice->AddRef();
|
||||
mDevice->GetImmediateContext(&mDeviceContext);
|
||||
mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel();
|
||||
}
|
||||
|
||||
mResourceManager11.setAllocationsInitialized(mCreateDebugDevice);
|
||||
|
@ -2282,12 +2327,6 @@ void Renderer11::release()
|
|||
mD3d11Module = nullptr;
|
||||
}
|
||||
|
||||
if (mDxgiModule)
|
||||
{
|
||||
FreeLibrary(mDxgiModule);
|
||||
mDxgiModule = nullptr;
|
||||
}
|
||||
|
||||
if (mDCompModule)
|
||||
{
|
||||
FreeLibrary(mDCompModule);
|
||||
|
|
|
@ -552,8 +552,10 @@ class Renderer11 : public RendererD3D
|
|||
HRESULT callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
|
||||
PFN_D3D11ON12_CREATE_DEVICE createDevice11on12,
|
||||
bool debug);
|
||||
egl::Error initializeDXGIAdapter();
|
||||
egl::Error initializeD3DDevice();
|
||||
egl::Error initializeDevice();
|
||||
egl::Error initializeAdapterFromDevice();
|
||||
void releaseDeviceResources();
|
||||
void release();
|
||||
|
||||
|
@ -570,7 +572,6 @@ class Renderer11 : public RendererD3D
|
|||
|
||||
HMODULE mD3d11Module;
|
||||
HMODULE mD3d12Module;
|
||||
HMODULE mDxgiModule;
|
||||
HMODULE mDCompModule;
|
||||
std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
|
||||
D3D_DRIVER_TYPE mRequestedDriverType;
|
||||
|
|
Загрузка…
Ссылка в новой задаче