Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 5d9c4ee

Browse files
NathanZabriskieCommit Bot
authored andcommitted
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: Jamie Madill <jmadill@chromium.org>
1 parent d7323cf commit 5d9c4ee

File tree

10 files changed

+284
-16
lines changed

10 files changed

+284
-16
lines changed

CONTRIBUTORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Microsoft Corporation
115115
Shawn Hargreaves
116116
Rafael Cintron
117117
James Clarke
118+
Nathan Zabriskie
118119

119120
Microsoft Open Technologies, Inc.
120121
Cooper Partin
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
Name
2+
3+
ANGLE_platform_angle_d3d11on12
4+
5+
Name Strings
6+
7+
EGL_ANGLE_platform_angle_d3d11on12
8+
9+
Contributors
10+
11+
Nathan Zabriskie, Microsoft
12+
13+
Contacts
14+
15+
Nathan Zabriskie, Microsoft (nazabris 'at' microsoft 'dot' com)
16+
17+
Status
18+
19+
Draft
20+
21+
Version
22+
23+
Version 1, 2019-10-07
24+
25+
Number
26+
27+
EGL Extension XXX
28+
29+
Extension Type
30+
31+
EGL client extension
32+
33+
Dependencies
34+
35+
Requires ANGLE_platform_angle_d3d.
36+
37+
Overview
38+
39+
This extension enables the creation of a D3D11on12 display.
40+
41+
New Types
42+
43+
None
44+
45+
New Procedures and Functions
46+
47+
None
48+
49+
New Tokens
50+
51+
Accepted as an attribute name in the <attrib_list> argument of
52+
eglGetPlatformDisplayEXT:
53+
54+
EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
55+
56+
Additions to the EGL Specification
57+
58+
None.
59+
60+
New Behavior
61+
62+
To request a D3D11on12 display the value of
63+
EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE should be set to EGL_TRUE.
64+
65+
If EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE is included in the
66+
<attrib_list> argument of eglGetPlatformDisplayEXT and
67+
EGL_PLATFORM_ANGLE_TYPE_ANGLE is not set to
68+
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, an EGL_BAD_ATTRIBUTE error is
69+
generated and EGL_NO_DISPLAY is returned.
70+
71+
EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE can be combined with
72+
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE if it is set to
73+
EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE or
74+
EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE. Other device types
75+
will generate an EGL_BAD_ATTRIBUTE error and return
76+
EGL_NO_DISPLAY.
77+
78+
Revision History
79+
80+
Version 1, 2019-10-07 (Nathan Zabriskie)
81+
- Initial draft

include/EGL/eglext_angle.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@
6565
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
6666
#endif /* EGL_ANGLE_platform_angle_d3d */
6767

68+
#ifndef EGL_ANGLE_platform_angle_d3d11on12
69+
#define EGL_ANGLE_platform_angle_d3d11on12 1
70+
#define EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
71+
#endif /* EGL_ANGLE_platform_angle_d3d11on12 */
72+
6873
#ifndef EGL_ANGLE_platform_angle_opengl
6974
#define EGL_ANGLE_platform_angle_opengl 1
7075
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D

src/common/platform.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@
5959
# include <d3d10_1.h>
6060
# include <d3d11.h>
6161
# include <d3d11_3.h>
62+
# include <d3d11on12.h>
63+
# include <d3d12.h>
6264
# include <d3dcompiler.h>
6365
# include <dxgi.h>
6466
# include <dxgi1_2.h>
67+
# include <dxgi1_4.h>
6568
# endif
6669

6770
# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)

src/libANGLE/Caps.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,7 @@ std::vector<std::string> ClientExtensions::getStrings() const
12621262
InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings);
12631263
InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings);
12641264
InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
1265+
InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12", platformANGLED3D11ON12, &extensionStrings);
12651266
InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings);
12661267
InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings);
12671268
InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings);

src/libANGLE/Caps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,9 @@ struct ClientExtensions
970970
// EGL_ANGLE_platform_angle_d3d
971971
bool platformANGLED3D = false;
972972

973+
// EGL_ANGLE_platform_angle_d3d11on12
974+
bool platformANGLED3D11ON12 = false;
975+
973976
// EGL_ANGLE_platform_angle_opengl
974977
bool platformANGLEOpenGL = false;
975978

src/libANGLE/Display.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#include "libANGLE/trace.h"
4343

4444
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
45+
# include <versionhelpers.h>
46+
4547
# include "libANGLE/renderer/d3d/DisplayD3D.h"
4648
#endif
4749

@@ -1223,6 +1225,10 @@ static ClientExtensions GenerateClientExtensions()
12231225
extensions.platformDevice = true;
12241226
#endif
12251227

1228+
#if defined(ANGLE_ENABLE_D3D11)
1229+
extensions.platformANGLED3D11ON12 = IsWindows10OrGreater();
1230+
#endif
1231+
12261232
#if defined(ANGLE_ENABLE_OPENGL)
12271233
extensions.platformANGLEOpenGL = true;
12281234

src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp

Lines changed: 139 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ Renderer11::Renderer11(egl::Display *display)
402402
mRenderer11DeviceCaps.B5G5R5A1support = 0;
403403

404404
mD3d11Module = nullptr;
405+
mD3d12Module = nullptr;
405406
mDxgiModule = nullptr;
406407
mDCompModule = nullptr;
407408
mCreatedWithDeviceEXT = false;
@@ -668,43 +669,134 @@ HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice,
668669
D3D11_SDK_VERSION, &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
669670
}
670671

672+
HRESULT Renderer11::callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
673+
PFN_D3D11ON12_CREATE_DEVICE createDevice11on12,
674+
bool debug)
675+
{
676+
angle::ComPtr<IDXGIFactory4> factory;
677+
HRESULT result = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
678+
if (FAILED(result))
679+
{
680+
return result;
681+
}
682+
683+
if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
684+
{
685+
angle::ComPtr<IDXGIAdapter> warpAdapter;
686+
result = factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
687+
if (SUCCEEDED(result))
688+
{
689+
result = createDevice12(warpAdapter.Get(), mAvailableFeatureLevels[0],
690+
IID_PPV_ARGS(&mDevice12));
691+
}
692+
}
693+
else
694+
{
695+
// Passing nullptr into pAdapter chooses the default adapter which will be the hardware
696+
// adapter if it exists.
697+
result = createDevice12(nullptr, mAvailableFeatureLevels[0], IID_PPV_ARGS(&mDevice12));
698+
}
699+
700+
if (SUCCEEDED(result))
701+
{
702+
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
703+
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
704+
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
705+
result = mDevice12->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue));
706+
}
707+
708+
if (SUCCEEDED(result))
709+
{
710+
result = createDevice11on12(
711+
mDevice12.Get(), debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
712+
static_cast<unsigned int>(mAvailableFeatureLevels.size()),
713+
reinterpret_cast<IUnknown **>(mCommandQueue.GetAddressOf()), 1 /* NumQueues */,
714+
0 /* NodeMask */, &mDevice, &mDeviceContext, &(mRenderer11DeviceCaps.featureLevel));
715+
}
716+
717+
return result;
718+
}
719+
671720
egl::Error Renderer11::initializeD3DDevice()
672721
{
673722
HRESULT result = S_OK;
723+
bool createD3D11on12Device = false;
674724

675725
if (!mCreatedWithDeviceEXT)
676726
{
677727
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
678728
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr;
729+
PFN_D3D12_CREATE_DEVICE D3D12CreateDevice = nullptr;
730+
PFN_D3D11ON12_CREATE_DEVICE D3D11on12CreateDevice = nullptr;
679731
{
680732
ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)");
681733
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
682734
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
683735
mDCompModule = LoadLibrary(TEXT("dcomp.dll"));
684736

685-
if (mD3d11Module == nullptr || mDxgiModule == nullptr)
686-
{
687-
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
688-
<< "Could not load D3D11 or DXGI library.";
689-
}
690-
691737
// create the D3D11 device
692738
ASSERT(mDevice == nullptr);
693-
D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
694-
GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
695739

696-
if (D3D11CreateDevice == nullptr)
740+
const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
741+
createD3D11on12Device =
742+
static_cast<EGLint>(attributes.get(EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE, EGL_FALSE));
743+
744+
if (createD3D11on12Device)
697745
{
698-
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
699-
<< "Could not retrieve D3D11CreateDevice address.";
746+
mD3d12Module = LoadLibrary(TEXT("d3d12.dll"));
747+
if (mD3d12Module == nullptr)
748+
{
749+
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
750+
<< "Could not load D3D12 library.";
751+
}
752+
753+
D3D12CreateDevice = reinterpret_cast<PFN_D3D12_CREATE_DEVICE>(
754+
GetProcAddress(mD3d12Module, "D3D12CreateDevice"));
755+
if (D3D12CreateDevice == nullptr)
756+
{
757+
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
758+
<< "Could not retrieve D3D12CreateDevice address.";
759+
}
760+
761+
D3D11on12CreateDevice = reinterpret_cast<PFN_D3D11ON12_CREATE_DEVICE>(
762+
GetProcAddress(mD3d11Module, "D3D11On12CreateDevice"));
763+
if (D3D11on12CreateDevice == nullptr)
764+
{
765+
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
766+
<< "Could not retrieve D3D11On12CreateDevice address.";
767+
}
768+
}
769+
else
770+
{
771+
if (mD3d11Module == nullptr || mDxgiModule == nullptr)
772+
{
773+
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
774+
<< "Could not load D3D11 or DXGI library.";
775+
}
776+
777+
D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
778+
GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
779+
780+
if (D3D11CreateDevice == nullptr)
781+
{
782+
return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
783+
<< "Could not retrieve D3D11CreateDevice address.";
784+
}
700785
}
701786
}
702787
#endif
703788

704789
if (mCreateDebugDevice)
705790
{
706791
ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)");
707-
result = callD3D11CreateDevice(D3D11CreateDevice, true);
792+
if (createD3D11on12Device)
793+
{
794+
result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, true);
795+
}
796+
else
797+
{
798+
result = callD3D11CreateDevice(D3D11CreateDevice, true);
799+
}
708800

709801
if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
710802
mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
@@ -713,7 +805,15 @@ egl::Error Renderer11::initializeD3DDevice()
713805
// Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
714806
// levels to fall back on.
715807
mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
716-
result = callD3D11CreateDevice(D3D11CreateDevice, true);
808+
if (createD3D11on12Device)
809+
{
810+
result =
811+
callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, true);
812+
}
813+
else
814+
{
815+
result = callD3D11CreateDevice(D3D11CreateDevice, true);
816+
}
717817
}
718818

719819
if (!mDevice || FAILED(result))
@@ -725,8 +825,14 @@ egl::Error Renderer11::initializeD3DDevice()
725825
if (!mDevice || FAILED(result))
726826
{
727827
ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice");
728-
729-
result = callD3D11CreateDevice(D3D11CreateDevice, false);
828+
if (createD3D11on12Device)
829+
{
830+
result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, false);
831+
}
832+
else
833+
{
834+
result = callD3D11CreateDevice(D3D11CreateDevice, false);
835+
}
730836

731837
if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
732838
mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
@@ -735,7 +841,15 @@ egl::Error Renderer11::initializeD3DDevice()
735841
// Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
736842
// levels to fall back on.
737843
mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
738-
result = callD3D11CreateDevice(D3D11CreateDevice, false);
844+
if (createD3D11on12Device)
845+
{
846+
result =
847+
callD3D11On12CreateDevice(D3D12CreateDevice, D3D11on12CreateDevice, false);
848+
}
849+
else
850+
{
851+
result = callD3D11CreateDevice(D3D11CreateDevice, false);
852+
}
739853
}
740854

741855
// Cleanup done by destructor
@@ -1970,6 +2084,15 @@ void Renderer11::release()
19702084
mDCompModule = nullptr;
19712085
}
19722086

2087+
mDevice12.Reset();
2088+
mCommandQueue.Reset();
2089+
2090+
if (mD3d12Module)
2091+
{
2092+
FreeLibrary(mD3d12Module);
2093+
mD3d12Module = nullptr;
2094+
}
2095+
19732096
mCompiler.release();
19742097

19752098
mSupportsShareHandles.reset();

0 commit comments

Comments
 (0)