Commit 5d9c4ee3 by Nathan Zabriskie Committed by Commit Bot

Add D3D11on12 device option

This CL adds a new D3D11on12 device option which runs the D3D11 API on top of D3D12. This is done to aid in preliminary investigations into the feasibility of creating a full D3D12 backend implementation. Bug: angleproject:3919 Change-Id: I0ad4250eb3c93b0b74274c904aac74f03753c7ad Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1814404 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d7323cf7
......@@ -115,6 +115,7 @@ Microsoft Corporation
Shawn Hargreaves
Rafael Cintron
James Clarke
Nathan Zabriskie
Microsoft Open Technologies, Inc.
Cooper Partin
......
Name
ANGLE_platform_angle_d3d11on12
Name Strings
EGL_ANGLE_platform_angle_d3d11on12
Contributors
Nathan Zabriskie, Microsoft
Contacts
Nathan Zabriskie, Microsoft (nazabris 'at' microsoft 'dot' com)
Status
Draft
Version
Version 1, 2019-10-07
Number
EGL Extension XXX
Extension Type
EGL client extension
Dependencies
Requires ANGLE_platform_angle_d3d.
Overview
This extension enables the creation of a D3D11on12 display.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as an attribute name in the <attrib_list> argument of
eglGetPlatformDisplayEXT:
EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
Additions to the EGL Specification
None.
New Behavior
To request a D3D11on12 display the value of
EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE should be set to EGL_TRUE.
If EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE is included in the
<attrib_list> argument of eglGetPlatformDisplayEXT and
EGL_PLATFORM_ANGLE_TYPE_ANGLE is not set to
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, an EGL_BAD_ATTRIBUTE error is
generated and EGL_NO_DISPLAY is returned.
EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE can be combined with
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE if it is set to
EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE or
EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE. Other device types
will generate an EGL_BAD_ATTRIBUTE error and return
EGL_NO_DISPLAY.
Revision History
Version 1, 2019-10-07 (Nathan Zabriskie)
- Initial draft
......@@ -65,6 +65,11 @@
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
#endif /* EGL_ANGLE_platform_angle_d3d */
#ifndef EGL_ANGLE_platform_angle_d3d11on12
#define EGL_ANGLE_platform_angle_d3d11on12 1
#define EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
#endif /* EGL_ANGLE_platform_angle_d3d11on12 */
#ifndef EGL_ANGLE_platform_angle_opengl
#define EGL_ANGLE_platform_angle_opengl 1
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
......
......@@ -59,9 +59,12 @@
# include <d3d10_1.h>
# include <d3d11.h>
# include <d3d11_3.h>
# include <d3d11on12.h>
# include <d3d12.h>
# include <d3dcompiler.h>
# include <dxgi.h>
# include <dxgi1_2.h>
# include <dxgi1_4.h>
# endif
# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
......
......@@ -1262,6 +1262,7 @@ std::vector<std::string> ClientExtensions::getStrings() const
InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12", platformANGLED3D11ON12, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings);
......
......@@ -970,6 +970,9 @@ struct ClientExtensions
// EGL_ANGLE_platform_angle_d3d
bool platformANGLED3D = false;
// EGL_ANGLE_platform_angle_d3d11on12
bool platformANGLED3D11ON12 = false;
// EGL_ANGLE_platform_angle_opengl
bool platformANGLEOpenGL = false;
......
......@@ -42,6 +42,8 @@
#include "libANGLE/trace.h"
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
# include <versionhelpers.h>
# include "libANGLE/renderer/d3d/DisplayD3D.h"
#endif
......@@ -1223,6 +1225,10 @@ static ClientExtensions GenerateClientExtensions()
extensions.platformDevice = true;
#endif
#if defined(ANGLE_ENABLE_D3D11)
extensions.platformANGLED3D11ON12 = IsWindows10OrGreater();
#endif
#if defined(ANGLE_ENABLE_OPENGL)
extensions.platformANGLEOpenGL = true;
......
......@@ -402,6 +402,7 @@ Renderer11::Renderer11(egl::Display *display)
mRenderer11DeviceCaps.B5G5R5A1support = 0;
mD3d11Module = nullptr;
mD3d12Module = nullptr;
mDxgiModule = nullptr;
mDCompModule = nullptr;
mCreatedWithDeviceEXT = false;
......@@ -668,35 +669,119 @@ HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice,
D3D11_SDK_VERSION, &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
}
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))
{
return result;
}
if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
{
angle::ComPtr<IDXGIAdapter> warpAdapter;
result = factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
if (SUCCEEDED(result))
{
result = createDevice12(warpAdapter.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));
}
if (SUCCEEDED(result))
{
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
result = mDevice12->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue));
}
if (SUCCEEDED(result))
{
result = createDevice11on12(
mDevice12.Get(), debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
static_cast<unsigned int>(mAvailableFeatureLevels.size()),
reinterpret_cast<IUnknown **>(mCommandQueue.GetAddressOf()), 1 /* NumQueues */,
0 /* NodeMask */, &mDevice, &mDeviceContext, &(mRenderer11DeviceCaps.featureLevel));
}
return result;
}
egl::Error Renderer11::initializeD3DDevice()
{
HRESULT result = S_OK;
bool createD3D11on12Device = false;
if (!mCreatedWithDeviceEXT)
{
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr;
PFN_D3D12_CREATE_DEVICE D3D12CreateDevice = nullptr;
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"));
if (mD3d11Module == nullptr || mDxgiModule == nullptr)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not load D3D11 or DXGI library.";
}
// create the D3D11 device
ASSERT(mDevice == nullptr);
D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
if (D3D11CreateDevice == nullptr)
const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
createD3D11on12Device =
static_cast<EGLint>(attributes.get(EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE, EGL_FALSE));
if (createD3D11on12Device)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not retrieve D3D11CreateDevice address.";
mD3d12Module = LoadLibrary(TEXT("d3d12.dll"));
if (mD3d12Module == nullptr)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not load D3D12 library.";
}
D3D12CreateDevice = reinterpret_cast<PFN_D3D12_CREATE_DEVICE>(
GetProcAddress(mD3d12Module, "D3D12CreateDevice"));
if (D3D12CreateDevice == nullptr)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not retrieve D3D12CreateDevice address.";
}
D3D11on12CreateDevice = reinterpret_cast<PFN_D3D11ON12_CREATE_DEVICE>(
GetProcAddress(mD3d11Module, "D3D11On12CreateDevice"));
if (D3D11on12CreateDevice == nullptr)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not retrieve D3D11On12CreateDevice address.";
}
}
else
{
if (mD3d11Module == nullptr || mDxgiModule == nullptr)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not load D3D11 or DXGI library.";
}
D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
if (D3D11CreateDevice == nullptr)
{
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
<< "Could not retrieve D3D11CreateDevice address.";
}
}
}
#endif
......@@ -704,7 +789,14 @@ egl::Error Renderer11::initializeD3DDevice()
if (mCreateDebugDevice)
{
ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)");
result = callD3D11CreateDevice(D3D11CreateDevice, true);
if (createD3D11on12Device)
{
result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, true);
}
else
{
result = callD3D11CreateDevice(D3D11CreateDevice, true);
}
if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
......@@ -713,7 +805,15 @@ egl::Error Renderer11::initializeD3DDevice()
// Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
// levels to fall back on.
mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
result = callD3D11CreateDevice(D3D11CreateDevice, true);
if (createD3D11on12Device)
{
result =
callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, true);
}
else
{
result = callD3D11CreateDevice(D3D11CreateDevice, true);
}
}
if (!mDevice || FAILED(result))
......@@ -725,8 +825,14 @@ egl::Error Renderer11::initializeD3DDevice()
if (!mDevice || FAILED(result))
{
ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice");
result = callD3D11CreateDevice(D3D11CreateDevice, false);
if (createD3D11on12Device)
{
result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, false);
}
else
{
result = callD3D11CreateDevice(D3D11CreateDevice, false);
}
if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
......@@ -735,7 +841,15 @@ egl::Error Renderer11::initializeD3DDevice()
// Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
// levels to fall back on.
mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
result = callD3D11CreateDevice(D3D11CreateDevice, false);
if (createD3D11on12Device)
{
result =
callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, false);
}
else
{
result = callD3D11CreateDevice(D3D11CreateDevice, false);
}
}
// Cleanup done by destructor
......@@ -1970,6 +2084,15 @@ void Renderer11::release()
mDCompModule = nullptr;
}
mDevice12.Reset();
mCommandQueue.Reset();
if (mD3d12Module)
{
FreeLibrary(mD3d12Module);
mD3d12Module = nullptr;
}
mCompiler.release();
mSupportsShareHandles.reset();
......
......@@ -553,6 +553,9 @@ class Renderer11 : public RendererD3D
const gl::TextureCaps &depthStencilBufferFormatCaps) const;
HRESULT callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug);
HRESULT callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
PFN_D3D11ON12_CREATE_DEVICE createDevice11on12,
bool debug);
egl::Error initializeD3DDevice();
egl::Error initializeDevice();
void releaseDeviceResources();
......@@ -569,6 +572,7 @@ class Renderer11 : public RendererD3D
UINT vertexCount);
HMODULE mD3d11Module;
HMODULE mD3d12Module;
HMODULE mDxgiModule;
HMODULE mDCompModule;
std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
......@@ -603,6 +607,9 @@ class Renderer11 : public RendererD3D
double mLastHistogramUpdateTime;
angle::ComPtr<ID3D12Device> mDevice12;
angle::ComPtr<ID3D12CommandQueue> mCommandQueue;
ID3D11Device *mDevice;
Renderer11DeviceCaps mRenderer11DeviceCaps;
ID3D11DeviceContext *mDeviceContext;
......
......@@ -387,6 +387,7 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
{
EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
bool enableAutoTrimSpecified = false;
bool enableD3D11on12 = false;
bool presentPathSpecified = false;
Optional<EGLAttrib> majorVersion;
......@@ -433,6 +434,25 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
enableAutoTrimSpecified = true;
break;
case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE:
if (!clientExtensions.platformANGLED3D ||
!clientExtensions.platformANGLED3D11ON12)
{
return EglBadAttribute()
<< "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active.";
}
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
break;
default:
return EglBadAttribute() << "Invalid D3D11on12 attribute";
}
enableD3D11on12 = true;
break;
case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE:
if (!clientExtensions.experimentalPresentPath)
{
......@@ -550,6 +570,24 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.";
}
if (enableD3D11on12)
{
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
return EglBadAttribute() << "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE "
"requires a platform type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.";
}
if (deviceType.valid() && deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE &&
deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
{
return EglBadAttribute() << "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device "
"type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE "
"or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE";
}
}
if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
return EglBadAttribute() << "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a "
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment