@@ -77,6 +77,76 @@ static UINT getD3D12SDKVersion(std::wstring SDKPath) {
7777 return SDKVersion;
7878}
7979
80+ // RAII wrapper for WARP DLL loading
81+ class WarpDllLoader {
82+ public:
83+ WarpDllLoader () = default ;
84+
85+ ~WarpDllLoader () {
86+ Close ();
87+ }
88+
89+ // Non-copyable
90+ WarpDllLoader (const WarpDllLoader&) = delete ;
91+ WarpDllLoader& operator =(const WarpDllLoader&) = delete ;
92+
93+ void LoadWarpDll () {
94+ WEX::Common::String WarpDllPath;
95+ if (SUCCEEDED (WEX::TestExecution::RuntimeParameters::TryGetValue (
96+ L" WARP_DLL" , WarpDllPath))) {
97+ LogCommentFmt (L" WARP_DLL requested: %ls" , (const wchar_t *)WarpDllPath);
98+ Module = LoadLibraryExW (WarpDllPath, NULL , 0 );
99+ VERIFY_WIN32_BOOL_SUCCEEDED (!!Module);
100+ }
101+ }
102+
103+ void Close () {
104+ if (Module) {
105+ FreeLibrary (Module);
106+ Module = NULL ;
107+ }
108+ }
109+
110+ private:
111+ HMODULE Module = NULL ;
112+ };
113+
114+ // Helper function to create WARP device with proper DLL management
115+ static bool createWARPDevice (
116+ IDXGIFactory4* DXGIFactory,
117+ std::function<HRESULT(IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **)> CreateDeviceFn,
118+ ID3D12Device** D3DDeviceCom,
119+ bool SkipUnsupported) {
120+
121+ // Load WARP DLL if specified
122+ WarpDllLoader warpLoader;
123+ warpLoader.LoadWarpDll ();
124+
125+ // Create the WARP device
126+ CComPtr<IDXGIAdapter> WarpAdapter;
127+ VERIFY_SUCCEEDED (DXGIFactory->EnumWarpAdapter (IID_PPV_ARGS (&WarpAdapter)));
128+ HRESULT CreateHR = CreateDeviceFn (WarpAdapter, D3D_FEATURE_LEVEL_11_0,
129+ IID_PPV_ARGS (D3DDeviceCom));
130+ if (FAILED (CreateHR)) {
131+ LogCommentFmt (L" Failed to create WARP device: 0x%08x" , CreateHR);
132+
133+ if (SkipUnsupported)
134+ WEX::Logging::Log::Result (WEX::Logging::TestResults::Skipped);
135+
136+ return false ;
137+ }
138+
139+ // Log the actual version of WARP that's loaded
140+ if (GetModuleHandleW (L" d3d10warp.dll" ) != NULL ) {
141+ WCHAR FullModuleFilePath[MAX_PATH] = L" " ;
142+ GetModuleFileNameW (GetModuleHandleW (L" d3d10warp.dll" ), FullModuleFilePath,
143+ sizeof (FullModuleFilePath));
144+ LogCommentFmt (L" WARP driver loaded from: %ls" , FullModuleFilePath);
145+ }
146+
147+ return true ;
148+ }
149+
80150static bool createDevice (
81151 ID3D12Device **D3DDevice, D3D_SHADER_MODEL TestModel, bool SkipUnsupported,
82152 std::function<HRESULT(IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **)>
@@ -104,61 +174,9 @@ static bool createDevice(
104174
105175 VERIFY_SUCCEEDED (CreateDXGIFactory1 (IID_PPV_ARGS (&DXGIFactory)));
106176 if (GetTestParamUseWARP (useWarpByDefault ())) {
107- // The WARP_DLL runtime parameter can be used to specify a specific DLL to
108- // load. To force this to be used, we make sure that this DLL is loaded
109- // before attempting to create the device.
110-
111- struct WarpDll {
112- HMODULE Module = NULL ; // NOLINT
113-
114- ~WarpDll () { Close (); }
115-
116- void Close () {
117- if (Module) {
118- FreeLibrary (Module);
119- Module = NULL ;
120- }
121- }
122- };
123-
124- WarpDll ExplicitlyLoadedWarpDll;
125- WEX::Common::String WarpDllPath;
126- if (SUCCEEDED (WEX::TestExecution::RuntimeParameters::TryGetValue (
127- L" WARP_DLL" , WarpDllPath))) {
128- WEX::Logging::Log::Comment (WEX::Common::String ().Format (
129- L" WARP_DLL requested: %ls" , (const wchar_t *)WarpDllPath));
130- ExplicitlyLoadedWarpDll.Module = LoadLibraryExW (WarpDllPath, NULL , 0 );
131- VERIFY_WIN32_BOOL_SUCCEEDED (!!ExplicitlyLoadedWarpDll.Module );
132- }
133-
134- // Create the WARP device
135- CComPtr<IDXGIAdapter> WarpAdapter;
136- VERIFY_SUCCEEDED (DXGIFactory->EnumWarpAdapter (IID_PPV_ARGS (&WarpAdapter)));
137- HRESULT CreateHR = CreateDeviceFn (WarpAdapter, D3D_FEATURE_LEVEL_11_0,
138- IID_PPV_ARGS (&D3DDeviceCom));
139- if (FAILED (CreateHR)) {
140- LogCommentFmt (L" Failed to create WARP device: 0x%08x" , CreateHR);
141-
142- if (SkipUnsupported)
143- WEX::Logging::Log::Result (WEX::Logging::TestResults::Skipped);
144-
177+ if (!createWARPDevice (DXGIFactory, CreateDeviceFn, &D3DDeviceCom, SkipUnsupported)) {
145178 return false ;
146179 }
147-
148- // Now that the WARP device is created we can release our reference to the
149- // warp dll.
150- ExplicitlyLoadedWarpDll.Close ();
151-
152- // Log the actual version of WARP that's loaded so we can be sure that
153- // we're using the version we think.
154- if (GetModuleHandleW (L" d3d10warp.dll" ) != NULL ) {
155- WCHAR FullModuleFilePath[MAX_PATH] = L" " ;
156- GetModuleFileNameW (GetModuleHandleW (L" d3d10warp.dll" ), FullModuleFilePath,
157- sizeof (FullModuleFilePath));
158- WEX::Logging::Log::Comment (WEX::Common::String ().Format (
159- L" WARP driver loaded from: %ls" , FullModuleFilePath));
160- }
161-
162180 } else {
163181 CComPtr<IDXGIAdapter1> HardwareAdapter;
164182 WEX::Common::String AdapterValue;
@@ -167,8 +185,7 @@ static bool createDevice(
167185 if (SUCCEEDED (HR))
168186 st::GetHardwareAdapter (DXGIFactory, AdapterValue, &HardwareAdapter);
169187 else
170- WEX::Logging::Log::Comment (
171- L" Using default hardware adapter with D3D12 support." );
188+ LogCommentFmt (L" Using default hardware adapter with D3D12 support." );
172189
173190 VERIFY_SUCCEEDED (CreateDeviceFn (HardwareAdapter, D3D_FEATURE_LEVEL_11_0,
174191 IID_PPV_ARGS (&D3DDeviceCom)));
0 commit comments