Skip to content

Commit 7670fb9

Browse files
author
Bud
authored
GPU fallback and XML + EDID update
GPU fallback and XML + EDID update
2 parents 7d13448 + b18c2e9 commit 7670fb9

2 files changed

Lines changed: 331 additions & 104 deletions

File tree

Common/Include/AdapterOption.h

Lines changed: 118 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,129 @@
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

Comments
 (0)