Heresy 這邊有在透過 C++ / Qt / OpenGL 開發自己的 OpenVR 程式,在部屬給別人用的時候,一個很常見的問題,就是現在的電競筆電的顯示系統大多會是 iGPU(CPU 整合顯示晶片)加上 dGPU(獨立顯示晶片)的設計。
這樣的設計概念,主要是希望在一般使用較省電的 iGPU 來延長電池的使用時間,等到真的有需求的時候,再使用 dGPU 來拉高效能。
而一般來說,Windows 會優先使用 iGPU,如果要使用 dGPU 的話,則會需要使用者自行修改設定;修改的方法是在 Windows 的「設定」、「系統」、「顯示器」的頁面中,點選最下方的「圖形」,然後在「應用程式的自訂選項」修改既有設定、或手動加入應用程式。
下面就是設定的畫面:
但是,如果是以程式開發者的角度來說,其實不會希望還要使用者自己去修改設定啊!畢竟有的使用者根本不知道要怎麼改、也有可能改錯。(附帶一提,更早期應該是要在顯示卡驅動程式設定)
那該怎麼做呢?在GitHub Gist 上的《Trick to tell AMD and Nvidia drivers to use the most powerful GPU instead of a lower-performance (such as integrated) GPU》這個檔案,算是提供了一個 C++ 裡面很簡單的做法。
NVIDIA 的方案
以 NVIDIA 來說,可以參考滿早期就有的 NVIDIA Optimus 的相關文件(連結);裡面的說法是說在 302 版的驅動程式以後,都可以透過在程式中定義 NvOptimusEnablement
的值來做設定。
具體的寫法是:
extern "C" { __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; }
如此一來,在 NVIDIA dGPU 搭配其他 iGPU 的系統上、應該就會預設改用 NVIDIA 的獨立顯示晶片了。
AMD 的方案
AMD 的話,對應的技術是 PowerXpress ,官方的說明則可以參考《Selecting the Best Graphics Device to Run a 3D Intensive Application》;他的方法類似,不過是變數名稱改成 AmdPowerXpressRequestHighPerformance
而已。
寫法是:
extern "C" { _declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; }
理論上也是這樣就可以了~
而如果兩個想一起考慮的話,其實可以寫成:
#ifdef _WIN32 // Use discrete GPU by default. extern "C" { // https://docs.nvidia.com/gameworks/content/technologies/desktop/optimus.htm __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; // https://gpuopen.com/learn/amdpowerxpressrequesthighperformance/ _declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; } #endif
基本上,Heresy 這邊測試應該是只要把這段程式加在程式碼裡面就可以了;而加上 #ifdef _WIN32
則是因為這個設定應該也只對 Windows 平台有用,其他平台該怎麼辦?恩,不知道。
以 NVIDIA dGPU + Intel iGPU 或 NVIDIA dGPU + AMD iGPU 的系統上,這樣做確實是可以如預期地運作的!至於 AMD 的部分,由於 Heresy 這邊沒有 AMD 顯卡,就只能跳過了。
另外,在 AMD 的文件也有提到,這個方法主要是針對 OpenGL 與 DirectX 的程式,對於 Vulkan 或 OpenCL 的程式來說,由於本來就需要自行決定要使用的裝置,所以不適用這個方法。
不過,個人其實比較好奇,這部分的管理目前應該已經從早期的顯示卡驅動程式變成是 Windows 系統了,那不知道 Windows 有沒有提供對應的 API 可以使用?找了一下,好像沒看到?
附帶一提,Windows 針對個別應用程式設定的資料會儲存在 registry 中,他的路徑是:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\DirectX\UserGpuPreferences
機碼名稱是應用程式的執行檔路徑加上檔名,而值則是「GpuPreference=0;
」這樣的形式;這邊的數值,0 是代表由 Windows 判斷、1 是省電(iGPU)、2 是高效能(dGPU)。
所以如果要玩的話,或許也可以透過自動加入機碼的方法、來指定要使用的 GPU?
感謝Heresy大的分享,沒想到原來這部分是可以透過顯示器的圖形自己調整,原本以為只能用關閉硬體或是用顯卡APP的方式處理,一直活在Win7時期的腦袋真的該更新了,沒想到現在系統本身已經可以自行調配內外顯設定,這樣真的很方便,不然有時候出去談案子不一定都有插座可以用,使用獨顯的時候耗電速度真的夭壽快,還好有看到這篇,不然我可能一輩子都不知道這個東西 哈哈。
Windows 10 / 11 現在對於多顯示卡的支援性已經算是相對好的了,使用上算是滿彈性的。