Skip to content

Commit 4c76c65

Browse files
committed
Factor out createWARPDevice and add RAII wrapper for WARP dll.
1 parent ba86cc0 commit 4c76c65

File tree

1 file changed

+72
-55
lines changed

1 file changed

+72
-55
lines changed

tools/clang/unittests/HLSLExec/HlslExecTestUtils.cpp

Lines changed: 72 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
80150
static 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

Comments
 (0)