@@ -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+
671720egl::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