Skip to content

Commit c9fbe91

Browse files
committed
Adding driver discovery on windows
Signed-off-by: Jaroslaw Chodor <[email protected]>
1 parent 136a07f commit c9fbe91

File tree

6 files changed

+221
-12
lines changed

6 files changed

+221
-12
lines changed

source/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ target_link_libraries(${TARGET_LOADER_NAME}
2828
${CMAKE_DL_LIBS}
2929
)
3030

31+
if(WIN32)
32+
target_link_libraries (${TARGET_LOADER_NAME} cfgmgr32.lib)
33+
endif()
34+
3135
install(TARGETS ze_loader
3236
LIBRARY
3337
DESTINATION ${CMAKE_INSTALL_LIBDIR}

source/loader/CMakeLists.txt

+13
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,26 @@
33

44
target_sources(${TARGET_LOADER_NAME}
55
PRIVATE
6+
${CMAKE_CURRENT_SOURCE_DIR}/driver_discovery.h
67
${CMAKE_CURRENT_SOURCE_DIR}/ze_object.h
78
${CMAKE_CURRENT_SOURCE_DIR}/ze_loader.h
89
${CMAKE_CURRENT_SOURCE_DIR}/ze_loader.cpp
910
${CMAKE_CURRENT_SOURCE_DIR}/ze_core_loader.cpp
1011
${CMAKE_CURRENT_SOURCE_DIR}/ze_tools_loader.cpp
1112
)
1213

14+
if(WIN32)
15+
target_sources(${TARGET_LOADER_NAME}
16+
PRIVATE
17+
${CMAKE_CURRENT_SOURCE_DIR}/windows/driver_discovery_win.cpp
18+
)
19+
else()
20+
target_sources(${TARGET_LOADER_NAME}
21+
PRIVATE
22+
${CMAKE_CURRENT_SOURCE_DIR}/linux/driver_discovery_lin.cpp
23+
)
24+
endif()
25+
1326
file(GLOB LEVEL_ZERO_LOADER_INCLUDES
1427
"*.h"
1528
)

source/loader/driver_discovery.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
*
3+
* Copyright (C) 2020 Intel Corporation
4+
*
5+
* SPDX-License-Identifier: MIT
6+
*
7+
*/
8+
9+
#pragma once
10+
11+
#include <string>
12+
#include <vector>
13+
14+
namespace loader {
15+
16+
using DriverLibraryPath = std::string;
17+
18+
std::vector<DriverLibraryPath> discoverEnabledDrivers();
19+
20+
} // namespace loader
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
*
3+
* Copyright (C) 2020 Intel Corporation
4+
*
5+
* SPDX-License-Identifier: MIT
6+
*
7+
*/
8+
9+
#include "source/loader/driver_discovery.h"
10+
11+
#include "source/inc/ze_util.h"
12+
13+
namespace loader {
14+
15+
static const char *knownDriverNames[] = {
16+
MAKE_LIBRARY_NAME("ze_intel_gpu", "0.8"),
17+
};
18+
19+
std::vector<DriverLibraryPath> discoverEnabledDrivers() {
20+
std::vector<DriverLibraryPath> enabledDrivers;
21+
for (auto path : knownDriverNames) {
22+
enabledDrivers.emplace_back(path);
23+
}
24+
return enabledDrivers;
25+
}
26+
27+
} // namespace loader
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
*
3+
* Copyright (C) 2020 Intel Corporation
4+
*
5+
* SPDX-License-Identifier: MIT
6+
*
7+
*/
8+
9+
#include "source/loader/driver_discovery.h"
10+
11+
#include <Windows.h>
12+
13+
#include <cassert>
14+
#include <cfgmgr32.h>
15+
#include <devpkey.h>
16+
#include <devguid.h>
17+
18+
namespace loader {
19+
20+
std::vector<DriverLibraryPath> discoverDriversBasedOnDisplayAdapters();
21+
22+
std::vector<DriverLibraryPath> discoverEnabledDrivers() {
23+
return discoverDriversBasedOnDisplayAdapters();
24+
}
25+
26+
bool isDeviceAvailable(DEVINST devnode) {
27+
ULONG devStatus = {};
28+
ULONG devProblem = {};
29+
auto configErr = CM_Get_DevNode_Status(&devStatus, &devProblem, devnode, 0);
30+
31+
if (CR_SUCCESS != configErr) {
32+
assert(false && "CM_Get_DevNode_Status failed");
33+
return false;
34+
}
35+
36+
bool isInInvalidState = (devStatus & DN_HAS_PROBLEM)
37+
&& (devProblem == CM_PROB_NEED_RESTART);
38+
isInInvalidState |= (DN_NEED_RESTART == (devStatus & DN_NEED_RESTART));
39+
40+
return false == isInInvalidState;
41+
}
42+
43+
DriverLibraryPath readDriverPathForDisplayAdapter(DEVINST dnDevNode) {
44+
static constexpr char levelZeroDriverPathKey[] = "LevelZeroDriverPath";
45+
46+
HKEY hkey = {};
47+
CONFIGRET configErr = CM_Open_DevNode_Key(dnDevNode, KEY_QUERY_VALUE, 0,
48+
RegDisposition_OpenExisting, &hkey,
49+
CM_REGISTRY_SOFTWARE);
50+
51+
if (CR_SUCCESS != configErr) {
52+
assert(false && "CM_Open_DevNode_Key failed");
53+
return "";
54+
}
55+
56+
DWORD regValueType = {};
57+
DWORD pathSize = {};
58+
LSTATUS regOpStatus = RegQueryValueExA(hkey, levelZeroDriverPathKey, NULL,
59+
&regValueType, NULL, &pathSize);
60+
61+
std::string driverPath;
62+
if ((ERROR_SUCCESS == regOpStatus) && (REG_SZ == regValueType)) {
63+
driverPath.resize(pathSize);
64+
regOpStatus = RegQueryValueExA(hkey, levelZeroDriverPathKey, NULL,
65+
&regValueType, (LPBYTE) & *driverPath.begin(),
66+
&pathSize);
67+
if (ERROR_SUCCESS != regOpStatus) {
68+
assert(false && "RegQueryValueExA failed");
69+
driverPath.clear();
70+
}
71+
}
72+
73+
regOpStatus = RegCloseKey(hkey);
74+
assert((ERROR_SUCCESS == regOpStatus) && "RegCloseKey failed");
75+
76+
return driverPath;
77+
}
78+
79+
std::wstring readDisplayAdaptersDeviceIdsList() {
80+
OLECHAR displayGuidStr[MAX_GUID_STRING_LEN];
81+
82+
int strFromGuidErr = StringFromGUID2(GUID_DEVCLASS_DISPLAY, displayGuidStr,
83+
MAX_GUID_STRING_LEN);
84+
if (MAX_GUID_STRING_LEN != strFromGuidErr) {
85+
assert(false && "StringFromGUID2 failed");
86+
return L"";
87+
}
88+
89+
std::wstring deviceIdList;
90+
CONFIGRET getDeviceIdListErr = CR_BUFFER_SMALL;
91+
while (CR_BUFFER_SMALL == getDeviceIdListErr) {
92+
ULONG deviceIdListSize = {};
93+
ULONG deviceIdListFlags = CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT;
94+
auto getDeviceIdListSizeErr = CM_Get_Device_ID_List_SizeW(&deviceIdListSize,
95+
displayGuidStr,
96+
deviceIdListFlags);
97+
if (CR_SUCCESS != getDeviceIdListSizeErr) {
98+
assert(false && "CM_Get_Device_ID_List_size failed");
99+
break;
100+
}
101+
102+
deviceIdList.resize(deviceIdListSize);
103+
getDeviceIdListErr = CM_Get_Device_ID_ListW(displayGuidStr,
104+
&*deviceIdList.begin(),
105+
deviceIdListSize,
106+
deviceIdListFlags);
107+
}
108+
109+
return deviceIdList;
110+
}
111+
112+
std::vector<DriverLibraryPath> discoverDriversBasedOnDisplayAdapters() {
113+
std::vector<DriverLibraryPath> enabledDrivers;
114+
auto deviceIdList = readDisplayAdaptersDeviceIdsList();
115+
if (deviceIdList.empty()) {
116+
return enabledDrivers;
117+
}
118+
119+
auto isNotDeviceListEnd = [](wchar_t *it) { return '\0' != it[0]; };
120+
auto getNextDeviceInList = [](wchar_t *it) { return it + wcslen(it) + 1; };
121+
122+
auto deviceIdIt = &*deviceIdList.begin();
123+
for (; isNotDeviceListEnd(deviceIdIt); deviceIdIt = getNextDeviceInList(deviceIdIt)) {
124+
DEVINST devinst = {};
125+
if (CR_SUCCESS != CM_Locate_DevNodeW(&devinst, deviceIdIt, 0)) {
126+
assert(false && "CM_Locate_DevNodeW failed");
127+
continue;
128+
}
129+
130+
if (false == isDeviceAvailable(devinst)) {
131+
continue;
132+
}
133+
134+
auto driverPath = readDriverPathForDisplayAdapter(devinst);
135+
136+
if (driverPath.empty()) {
137+
continue;
138+
}
139+
140+
bool alreadyOnTheList = (enabledDrivers.end() != std::find(enabledDrivers.begin(), enabledDrivers.end(), driverPath));
141+
if (alreadyOnTheList) {
142+
continue;
143+
}
144+
145+
enabledDrivers.push_back(std::move(driverPath));
146+
}
147+
return enabledDrivers;
148+
}
149+
150+
} // namespace loader

source/loader/ze_loader.cpp

+7-12
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,23 @@
77
*/
88
#include "ze_loader.h"
99

10+
#include "driver_discovery.h"
11+
1012
namespace loader
1113
{
12-
///////////////////////////////////////////////////////////////////////////////
13-
static const char* known_driver_names[] = {
14-
MAKE_LIBRARY_NAME( "ze_intel_gpu", "0.8"),
15-
};
16-
17-
static const size_t num_known_driver_names =
18-
sizeof( known_driver_names ) / sizeof( known_driver_names[ 0 ] );
19-
20-
2114
///////////////////////////////////////////////////////////////////////////////
2215
context_t context;
2316

2417

2518
///////////////////////////////////////////////////////////////////////////////
2619
context_t::context_t()
2720
{
28-
drivers.reserve( num_known_driver_names );
29-
for( auto name : known_driver_names )
21+
auto discoveredDrivers = discoverEnabledDrivers();
22+
23+
drivers.reserve( discoveredDrivers.size() );
24+
for( auto name : discoveredDrivers )
3025
{
31-
auto handle = LOAD_DRIVER_LIBRARY( name );
26+
auto handle = LOAD_DRIVER_LIBRARY( name.c_str() );
3227
if( NULL != handle )
3328
{
3429
drivers.emplace_back();

0 commit comments

Comments
 (0)