11#pragma once
22
3- // Anonymous namespace for usings
4- namespace
5- {
6- using namespace std ;
7- using namespace Microsoft ::IndirectDisp;
8- using namespace Microsoft ::WRL;
9-
10- struct AdapterOption
11- {
12- bool hasTargetAdapter{};
13- LUID adapterLuid{};
14-
15- void load (const char * path)
16- {
17- ifstream ifs{ path };
18-
19- if (!ifs.is_open ())
20- {
21- return ;
22- }
3+ #include < wrl/client.h> // For ComPtr
4+ #include < dxgi.h> // For IDXGIAdapter, IDXGIFactory1
5+ #include < algorithm> // For sort
6+
7+ using namespace std ;
8+ using namespace Microsoft ::WRL;
9+
10+ // Structure to vector gpus
11+ struct GPUInfo {
12+ wstring name; // GPU name
13+ ComPtr<IDXGIAdapter> adapter;// COM pointer to the adapter
14+ DXGI_ADAPTER_DESC desc; // Adapter description
15+ };
16+
17+ // Sort function for GPUs by dedicated video memory
18+ bool CompareGPUs (const GPUInfo& a, const GPUInfo& b) {
19+ return a.desc .DedicatedVideoMemory > b.desc .DedicatedVideoMemory ;
20+ }
21+
22+ // Get a enumerate list of available GPUs
23+ vector<GPUInfo> getAvailableGPUs () {
24+ vector<GPUInfo> gpus; // Vector to hold all GPU's information
25+
26+ ComPtr<IDXGIFactory1> factory;
27+ if (!SUCCEEDED (CreateDXGIFactory1 (IID_PPV_ARGS (&factory)))) {
28+ return gpus;
29+ }
30+
31+ // Enumerate all adapters (GPUs)
32+ for (UINT i = 0 ;; i++) {
33+ ComPtr<IDXGIAdapter> adapter;
34+ if (!SUCCEEDED (factory->EnumAdapters (i, &adapter))) {
35+ break ;
36+ }
37+
38+ DXGI_ADAPTER_DESC desc;
39+
40+ if (!SUCCEEDED (adapter->GetDesc (&desc))) {
41+ continue ;
42+ }
43+
44+ // Add the adapter information to the list
45+ GPUInfo info{ desc.Description , adapter, desc };
46+ gpus.push_back (info);
47+ }
48+
49+ return gpus;
50+ }
51+
52+ class AdapterOption {
53+ public:
54+ bool hasTargetAdapter{}; // Indicates if a target adapter is selected
55+ LUID adapterLuid{}; // Adapter's unique identifier (LUID)
56+ wstring target_name{}; // Target adapter name
2357
24- std::string line;
58+ // Select the best GPU based on dedicated video memory
59+ wstring selectBestGPU () {
60+ auto gpus = getAvailableGPUs ();
61+ if (gpus.empty ()) {
62+ return L" " ; // Error check for headless / vm
63+ }
64+
65+ // Sort GPUs by dedicated video memory in descending order
66+ sort (gpus.begin (), gpus.end (), CompareGPUs);
67+ auto bestGPU = gpus.front (); // Get the GPU with the most memory
68+
69+ return bestGPU.name ;
70+ }
71+
72+ // Load friendlyname from a file OR select the best GPU
73+ void load (const wchar_t * path) {
74+ ifstream ifs{ path };
75+
76+ if (!ifs.is_open ()) {
77+ target_name = selectBestGPU ();
78+ }
79+ else {
80+ string line;
2581 getline (ifs, line);
82+ target_name.assign (line.begin (), line.end ());
83+ }
2684
27- std::wstring target_name{ line.begin (), line.end () };
85+ // Find and set the adapter based on the target name
86+ if (!findAndSetAdapter (target_name)) {
87+ // If the adapter is not found, select the best GPU and retry
88+ target_name = selectBestGPU ();
89+ findAndSetAdapter (target_name);
90+ }
91+ }
2892
29- ComPtr<IDXGIFactory1> factory{};
30- if (!SUCCEEDED (CreateDXGIFactory1 (IID_PPV_ARGS (&factory))))
31- {
32- return ;
33- }
93+ // Set the target adapter from a given name and validate it
94+ void xmlprovide (const wstring& xtarg) {
95+ target_name = xtarg;
96+ if (!findAndSetAdapter (target_name)) {
97+ // If the adapter is not found, select the best GPU and retry
98+ target_name = selectBestGPU ();
99+ findAndSetAdapter (target_name);
100+ }
101+ }
34102
35- for (UINT i = 0 ;; i++)
36- {
37- ComPtr<IDXGIAdapter> adapter{};
38- if (!SUCCEEDED (factory->EnumAdapters (i, &adapter)))
39- {
40- break ;
41- }
42-
43- DXGI_ADAPTER_DESC desc;
44- if (!SUCCEEDED (adapter->GetDesc (&desc)))
45- {
46- break ;
47- }
48-
49- // We found our target
50- if (_wcsicmp (target_name.c_str (), desc.Description ) == 0 )
51- {
52- adapterLuid = desc.AdapterLuid ;
53- hasTargetAdapter = true ;
54- }
55- }
103+ // Apply the adapter settings to the specified adapter
104+ void apply (const IDDCX_ADAPTER& adapter) {
105+ if (hasTargetAdapter && IDD_IS_FUNCTION_AVAILABLE (IddCxAdapterSetRenderAdapter)) {
106+ IDARG_IN_ADAPTERSETRENDERADAPTER arg{};
107+ arg.PreferredRenderAdapter = adapterLuid;
108+ IddCxAdapterSetRenderAdapter (adapter, &arg);
56109 }
110+ }
111+
112+ private:
113+ // Find and set the adapter by its name
114+ bool findAndSetAdapter (const wstring& adapterName) {
115+ auto gpus = getAvailableGPUs ();
57116
58- void apply (const IDDCX_ADAPTER& adapter)
59- {
60- if (hasTargetAdapter)
61- {
62- if (IDD_IS_FUNCTION_AVAILABLE (IddCxAdapterSetRenderAdapter))
63- {
64- IDARG_IN_ADAPTERSETRENDERADAPTER arg{};
65- arg.PreferredRenderAdapter = adapterLuid;
66-
67- IddCxAdapterSetRenderAdapter (adapter, &arg);
68- }
117+ // Iterate through all available GPUs
118+ for (const auto & gpu : gpus) {
119+ if (_wcsicmp (gpu.name .c_str (), adapterName.c_str ()) == 0 ) {
120+ adapterLuid = gpu.desc .AdapterLuid ; // Set the adapter LUID
121+ hasTargetAdapter = true ; // Indicate that a target adapter is selected
122+ return true ;
69123 }
70124 }
71- };
72- }
125+
126+ hasTargetAdapter = false ; // Indicate that no target adapter is selected
127+ return false ;
128+ }
129+ };
0 commit comments