|
| 1 | +diff --git a/Common/Include/AdapterOption.h b/Common/Include/AdapterOption.h |
| 2 | +index 9c2e8e1..b8b3b23 100644 |
| 3 | +--- a/Common/Include/AdapterOption.h |
| 4 | ++++ b/Common/Include/AdapterOption.h |
| 5 | +@@ -65,6 +65,100 @@ vector<GPUInfo> getAvailableGPUs() { |
| 6 | + |
| 7 | + return gpus; |
| 8 | + } |
| 9 | ++ |
| 10 | ++// #--- // Find the integrated GPU (iGPU) from available adapters |
| 11 | ++// #--- // Returns optional LUID if iGPU is found, nullopt otherwise |
| 12 | ++// #--- inline std::optional<LUID> findiGPU() { |
| 13 | ++// #--- auto gpus = getAvailableGPUs(); |
| 14 | ++// #--- if (gpus.empty()) { |
| 15 | ++// #--- return std::nullopt; |
| 16 | ++// #--- } |
| 17 | ++// #--- |
| 18 | ++// #--- // iGPU detection criteria: |
| 19 | ++// #--- // 1. Not a software adapter (has dedicated video memory > 0) |
| 20 | ++// #--- // 2. Low dedicated video memory (typically < 512MB for integrated) |
| 21 | ++// #--- // 3. Usually Intel HD/UHD graphics (Vendor ID 0x8086) or AMD APU (Vendor ID 0x1002) |
| 22 | ++// #--- // 4. Often the GPU with least dedicated memory (excluding software adapters) |
| 23 | ++// #--- |
| 24 | ++// #--- const UINT64 iGPUMemoryThreshold = 512ULL * 1024ULL * 1024ULL; // 512MB threshold |
| 25 | ++// #--- const UINT intelVendorId = 0x8086; // Intel |
| 26 | ++// #--- const UINT amdVendorId = 0x1002; // AMD (for APUs) |
| 27 | ++// #--- |
| 28 | ++// #--- std::optional<LUID> iGPULuid = std::nullopt; |
| 29 | ++// #--- UINT64 minDedicatedMemory = UINT64_MAX; |
| 30 | ++// #--- const GPUInfo* candidateGPU = nullptr; |
| 31 | ++// #--- |
| 32 | ++// #--- // First pass: Look for Intel or AMD integrated graphics with low memory |
| 33 | ++// #--- for (const auto& gpu : gpus) { |
| 34 | ++// #--- const auto& desc = gpu.desc; |
| 35 | ++// #--- |
| 36 | ++// #--- // Skip software adapters (zero dedicated memory) |
| 37 | ++// #--- if (desc.DedicatedVideoMemory == 0) { |
| 38 | ++// #--- continue; |
| 39 | ++// #--- } |
| 40 | ++// #--- |
| 41 | ++// #--- // Check for integrated GPU characteristics |
| 42 | ++// #--- bool isLikelyiGPU = false; |
| 43 | ++// #--- |
| 44 | ++// #--- // Check by vendor ID (Intel or AMD APU) |
| 45 | ++// #--- if (desc.VendorId == intelVendorId || desc.VendorId == amdVendorId) { |
| 46 | ++// #--- // Intel HD/UHD graphics typically have specific naming patterns |
| 47 | ++// #--- wstring name = desc.Description; |
| 48 | ++// #--- if (name.find(L"Intel") != wstring::npos && |
| 49 | ++// #--- (name.find(L"HD") != wstring::npos || name.find(L"UHD") != wstring::npos)) { |
| 50 | ++// #--- isLikelyiGPU = true; |
| 51 | ++// #--- } |
| 52 | ++// #--- // Check if it has low dedicated memory (typical for iGPU) |
| 53 | ++// #--- if (desc.DedicatedVideoMemory < iGPUMemoryThreshold) { |
| 54 | ++// #--- isLikelyiGPU = true; |
| 55 | ++// #--- } |
| 56 | ++// #--- } |
| 57 | ++// #--- |
| 58 | ++// #--- // Track the GPU with least dedicated memory (usually iGPU) |
| 59 | ++// #--- if (desc.DedicatedVideoMemory < minDedicatedMemory) { |
| 60 | ++// #--- minDedicatedMemory = desc.DedicatedVideoMemory; |
| 61 | ++// #--- // Prioritize Intel/AMD candidates, but also consider low memory GPUs |
| 62 | ++// #--- if (isLikelyiGPU || desc.DedicatedVideoMemory < iGPUMemoryThreshold) { |
| 63 | ++// #--- candidateGPU = &gpu; |
| 64 | ++// #--- } |
| 65 | ++// #--- } |
| 66 | ++// #--- } |
| 67 | ++// #--- |
| 68 | ++// #--- // If we found a candidate with Intel/AMD or low memory, return it |
| 69 | ++// #--- if (candidateGPU != nullptr) { |
| 70 | ++// #--- return candidateGPU->desc.AdapterLuid; |
| 71 | ++// #--- } |
| 72 | ++// #--- |
| 73 | ++// #--- // Fallback: If no clear iGPU found by vendor, return the GPU with least memory |
| 74 | ++// #--- // (assuming discrete GPUs typically have more memory) |
| 75 | ++// #--- if (minDedicatedMemory != UINT64_MAX && minDedicatedMemory < iGPUMemoryThreshold) { |
| 76 | ++// #--- for (const auto& gpu : gpus) { |
| 77 | ++// #--- if (gpu.desc.DedicatedVideoMemory == minDedicatedMemory) { |
| 78 | ++// #--- return gpu.desc.AdapterLuid; |
| 79 | ++// #--- } |
| 80 | ++// #--- } |
| 81 | ++// #--- } |
| 82 | ++// #--- |
| 83 | ++// #--- return std::nullopt; |
| 84 | ++// #--- } |
| 85 | ++ |
| 86 | ++// #--- // Get iGPU name if available |
| 87 | ++// #--- inline wstring getiGPUName() { |
| 88 | ++// #--- auto luidOpt = findiGPU(); |
| 89 | ++// #--- if (!luidOpt.has_value()) { |
| 90 | ++// #--- return L""; |
| 91 | ++// #--- } |
| 92 | ++// #--- |
| 93 | ++// #--- auto gpus = getAvailableGPUs(); |
| 94 | ++// #--- for (const auto& gpu : gpus) { |
| 95 | ++// #--- if (gpu.desc.AdapterLuid.LowPart == luidOpt.value().LowPart && |
| 96 | ++// #--- gpu.desc.AdapterLuid.HighPart == luidOpt.value().HighPart) { |
| 97 | ++// #--- return gpu.name; |
| 98 | ++// #--- } |
| 99 | ++// #--- } |
| 100 | ++// #--- |
| 101 | ++// #--- return L""; |
| 102 | ++// #--- } |
| 103 | +@@ -132,6 +226,11 @@ public: |
| 104 | + bool hasTargetAdapter{}; // Indicates if a target adapter is selected |
| 105 | + LUID adapterLuid{}; // Adapter's unique identifier (LUID) |
| 106 | + wstring target_name{}; // Target adapter name |
| 107 | ++ |
| 108 | ++// #--- // --- iGPU SUPPORT --- |
| 109 | ++// #--- bool hasiGPU{}; // Indicates if an iGPU was detected |
| 110 | ++// #--- LUID iGPULuid{}; // Integrated GPU's unique identifier (LUID) |
| 111 | ++// #--- wstring iGPU_name{}; // Integrated GPU name |
| 112 | ++// #--- // --- END iGPU SUPPORT --- |
| 113 | +@@ -188,6 +287,39 @@ public: |
| 114 | + IddCxAdapterSetRenderAdapter(adapter, &arg); |
| 115 | + } |
| 116 | + } |
| 117 | ++ |
| 118 | ++// #--- // --- iGPU DETECTION METHODS --- |
| 119 | ++// #--- // Detect and select the integrated GPU (iGPU) |
| 120 | ++// #--- // Returns true if iGPU is found and set, false otherwise |
| 121 | ++// #--- bool selectiGPU() { |
| 122 | ++// #--- auto luidOpt = findiGPU(); |
| 123 | ++// #--- if (luidOpt.has_value()) { |
| 124 | ++// #--- iGPULuid = luidOpt.value(); |
| 125 | ++// #--- iGPU_name = getiGPUName(); |
| 126 | ++// #--- hasiGPU = true; |
| 127 | ++// #--- return true; |
| 128 | ++// #--- } |
| 129 | ++// #--- hasiGPU = false; |
| 130 | ++// #--- return false; |
| 131 | ++// #--- } |
| 132 | ++// #--- |
| 133 | ++// #--- // Get the iGPU LUID if available |
| 134 | ++// #--- std::optional<LUID> getiGPULuid() const { |
| 135 | ++// #--- if (hasiGPU) { |
| 136 | ++// #--- return iGPULuid; |
| 137 | ++// #--- } |
| 138 | ++// #--- return std::nullopt; |
| 139 | ++// #--- } |
| 140 | ++// #--- |
| 141 | ++// #--- // Check if iGPU is available |
| 142 | ++// #--- bool hasIntegratedGPU() const { |
| 143 | ++// #--- return hasiGPU; |
| 144 | ++// #--- } |
| 145 | ++// #--- |
| 146 | ++// #--- // Get iGPU name |
| 147 | ++// #--- wstring getiGPUName() const { |
| 148 | ++// #--- return iGPU_name; |
| 149 | ++// #--- } |
| 150 | ++// #--- // --- END iGPU DETECTION METHODS --- |
| 151 | + |
| 152 | + private: |
| 153 | + // Find and set the adapter by name, optionally using "name,bus" where bus is the PCI bus number. |
0 commit comments