適用於 XBOX One 的 Microsoft Game Development Kit 移植指南
本主題概述將現有程式碼基底移植至 XBOX 的 Microsoft Game Development Kit (GDK) 平台的技術。對於已在進行 XBOX One 開發的開發人員而言,大部分子系統都很熟悉,只是採用了不同的 API 設計。某些領域 (例如 Direct3D 圖形) 大致上沒有變更。本主題提供整體移植流程的高階概觀、特定領域的連結,以及一些可避免常見陷阱的技巧與秘訣。 對本指南有任何意見反應嗎?請在 Microsoft Game Development Kit (GDK) 開發人員論壇告訴我們。 如果您是使用 Microsoft Game Development Kit (GDK) 平台開發新遊戲,而不是移植現有遊戲,請參閱「使用 GDK 開發新遊戲」。關於 Microsoft Game Development Kit (GDK)
身為我們遊戲開發合作夥伴的您,已向 Microsoft 遊戲團隊提供了寶貴的意見反應,讓我們了解哪些地方做得好,以及哪些地方需要改進。我們推出 Microsoft Game Development Kit (GDK) 的主要目標,是直接回應您的意見反應,並確保您能夠:- 完全依照您目前的方式繼續開發遊戲
- 在每一項 Microsoft 遊戲計畫與方案之間輕鬆共用盡可能多的程式碼:包括我們目前的主機與 PC,以及未來的主機與 XBOX Game Streaming
- 信任我們的開發工具與平台能提供快速、可靠且以開發人員為中心的環境
- 盡可能快速且輕鬆地利用全新的多平台服務與體驗
內容
- 規劃您的移植專案
- 開發環境
- 應用程式啟動
- 初始化應用程式
- Windows 訊息迴圈
- 建立 Direct3D 裝置
- 呈現
- 處理程序生命週期管理 (PLM)
- 記憶體管理
- 程式設計模型
- HLSL 著色器
- 使用者管理
- 網路與 XBOX services 整合
- 後續步驟
- 技巧與秘訣
- 二進位相容性與元件重複使用
- 程式碼撰寫風格與最佳做法
- 另請參閱
在本移植指南中,我們假設您的目標是 Gaming.Xbox.XboxOne.x64 和/或 Gaming.Xbox.Scarlett.x64 平台。Microsoft Game Development Kit (GDK) 也包含 Gaming.Desktop.x64 平台。它是標準 x64 Win32 平台的變體,本移植指南不會加以說明。Gaming.Desktop.x64 的主要價值,在於以 PC 為目標時,能在建置設定、Visual Studio 整合、鬆散配置行為等方面提供與 Gaming.Xbox.*.x64 類似的體驗。或者,您也可以使用「原生」x64 平台,並直接為 PC 實作所有設定/封裝。
規劃您的移植專案
將現有程式碼基底移植至 Microsoft Game Development Kit (GDK) 時,您通常會從現有的 XBOX One Software Development Kit 專案或傳統 Win32 桌面應用程式開始。對於許多已有 XBOX One 遊戲的開發人員而言,只要 Windows 執行階段 API 的使用相對獨立,就會發現從Durango 程式碼基底開始是較好的選擇。傳統 Win32 桌面程式碼基底與 Microsoft Game Development Kit (GDK) 程式設計模型更為接近,但通常預設採用以桌面為中心的 UI 與控制配置,必須針對主機進行修改。傳統 Win32 桌面程式碼基底也往往有大量以桌面為中心的整合,特別是當它們作為遊戲編輯工具套件的一部分時,會使用 XBOX 上的 Microsoft Game Development Kit (GDK) 不支援的 API 集。從這兩者開始各有優缺點。在某些情況下,您可能會發現針對程式碼基底的不同部分分別從兩種類型取用會比較容易。
從 XBOX One Software Development Kit 移植
如果您的程式碼基底已透過 XBOX One Software Development Kit (也稱為Durango 平台) 支援 XBOX One,表示您已完成大部分將應用程式 API 使用方式現代化的工作。程式碼也應該已針對主機的特定限制進行良好的最佳化,而且可能大量使用下列 XBOX One 專屬擴充功能。
- 需要 DirectX 12.X。如果您的 XBOX One 遊戲已在使用 DirectX 12.X,除了呈現 API 之外,您的 Direct3D 使用方式應該不需要任何變更。
如果您目前使用的是 DirectX 11.X,請先升級至 DirectX 12.X。在移至 Microsoft Game Development Kit (GDK) 之前,使用現有的 XBOX One Software Development Kit 建置來進行升級可能會比較容易。如需詳細資訊,請參閱下列主題:從 Direct3D 11 移植至 Direct3D 12 和 Introduction to Direct3D 12 on XBOX One Xfest 演講 (XBOX Developer Downloads->Conference Material->Xfest 2015 GPU Track Videos),以及 Porting from Direct3D 11 to Direct3D 12 Xfest 演講 (XBOX Developer Downloads->Conference Material->Xfest 2015 GPU Track Videos)。
- 您的呈現邏輯必須使用 PresentX API,而不是使用 DXGI 交換鏈結。
- Microsoft Game Development Kit (GDK) GDK Game OS 的記憶體子系統已有一些重大變更。請重新檢視您的記憶體管理員實作。
- 針對控制器輸入,請使用新的 GameInput API,而不是
Windows.Xbox.Input。 - 由於大多數情況下已不再使用 Windows 執行階段 API,請將現有的 C++/CX 或 C++/WinRT 程式碼取代為新的 Win32 樣式或 DirectX 樣式 COM API。
- Core Audio 功能沒有變更。不過,可能需要依照音訊 API 比較中所述進行一些 API 變更。支援搭配 XMA 擴充功能的 XAudio2、WASAPI 和
ISpatialAudioClient。 - 在 Visual Studio 中建置時,請新增
Gaming.Xbox.XboxOne.x64和/或Gaming.Xbox.Scarlett.x64平台組態以取代Durango平台組態,並升級至 Visual Studio 2019 或 Visual Studio 2022。
為了協助新增平台組態,我們製作了名為 SolutionUpdater 的範例。此範例工具會讀取現有的 Visual Studio 方案檔,並自動為方案所參考的所有相關專案檔建立新的平台組態,大幅加快流程並降低人為錯誤的可能性。如需詳細資訊,請參閱範例隨附的文件。
如果您的程式碼基底支援通用 Windows 平台 (UWP) 應用程式模型,您的移植路徑與從 XBOX One Software Development Kit 移植類似。
從傳統 Win32 桌面移植
如果您的程式碼基底僅支援傳統 Win32 桌面,則移植流程可能會相當繁複,取決於程式碼基底在已淘汰 API 及其他功能方面的新舊程度。請記住,傳統 Win32 桌面程式碼基底可能涵蓋非常廣泛的 API,甚至可追溯到 Windows 9x/ME 時代。此清單並未完整列出您可能遇到的所有潛在問題。以 XBOX 為目標時,您也會面臨從 PC 移植到主機的一般考量:UI、輸入模型、固定解析度顯示、受限的記憶體等等。- 需要 x64 原生。如需詳細資訊,請參閱適用於遊戲開發人員的 64 位元程式設計。
- 需要 DirectX 12.X。無法使用 DirectX 11、Direct3D 10、Direct3D 9 或更早版本。此外,也不支援 OpenGL 和 Vulkan。如需詳細資訊,請參閱 DirectX11 和 DirectX12 的移植指南。
- 無法使用舊版 DirectX SDK 元件 D3DX9、D3DX10、D3DX11 和 XACT。如需詳細資訊,請參閱 Microsoft Docs、Where is the DirectX SDK (2021 Edition)?、Living without D3DX 和 The Zombie DirectX SDK。
WINAPI_FAMILY_GAMES是完整 Win32 API 系列的子集。請僅使用這些 API。- 需要 AppX 封裝。請更新您的封裝與部署流程。
- 針對控制器輸入,請使用新的 GameInput API,而不是
Windows.Gaming.Input或 DirectInput。 - 針對音訊,請使用 XAudio2、WASAPI、ISpatialAudioClient 或相容的音訊中介軟體。
- 移除所有使用登錄的地方。
- 應減少對
WndProc訊息的處理。許多訊息 (特別是處理視窗定位、大小調整和殼層整合的訊息) 並不適用於 XBOX 上的 Microsoft Game Development Kit (GDK)。 - 如果您使用 Visual Studio 建置,請將程式碼升級為可搭配 Visual Studio 2019 或 Visual Studio 2022 運作。否則,請確定您的建置使用新的前置處理器定義,並與
GXDK\gameKit\lib\amd64中的程式庫連結,例如xgameplatform.lib總括程式庫。 - 針對 COM 元件,僅支援多執行緒 Apartment (MTA) 執行緒模型。請注意,
COINITBASE_MULTITHREADED是 Direct3D 應用程式的典型設定。 - 僅支援單一視窗執行個體。不支援多個並行的視窗執行個體或對話方塊。
開發環境
Visual Studio 2019 (16.11 更新) 或 Visual Studio 2022 是 Microsoft Game Development Kit (GDK) 支援的開發環境。 請安裝下列項目:- 工作負載:使用 C++ 的遊戲開發,用於核心工具集
- 工作負載:UWP 開發,用於封裝工具。
- 工作負載 (選用):使用 C++ 的桌面開發,用於 PC 端工具與範例。
使用 Visual Studio 2017 進行 XBOX One Software Development Kit 開發時,也需要選用元件 Windows 8.1 SDK 和 UCRT SDK。Microsoft Game Development Kit (GDK) 不需要此元件。如果您仍在使用 Visual Studio 2015 或更早版本,移植工作的第一步就是升級至 Visual Studio 2019 或更新版本。
Visual Studio 平台
Microsoft Game Development Kit (GDK) 與 Visual Studio 整合,提供Gaming.Xbox.XboxOne.x64 和 Gaming.Xbox.Scarlett.x64 平台,以 XBOX 上的 Microsoft GDK Game OS 為目標。這會取代 XBOX One Software Development Kit 的 Durango 平台。
自訂建置解決方案
若要在 Visual Studio 之外建置程式碼,用於指出位置的環境協助程式已有所變更。 XBOX One Software Development Kit:在上述範例路徑中,build_number 代表您系統上安裝的組建 (例如 190700)。
%GameDKLatest%\GXDK\gameKit 包含主機專屬擴充功能的所有標頭和程式庫,以及用於連結 Microsoft Game Development Kit (GDK) 二進位檔的主要平台總括程式庫。%GameDKLatest%\GRDK\gameKit 同樣包含所有非主機開發專屬功能的標頭和程式庫。Microsoft Game Development Kit (GDK) 需要安裝 Windows 10 SDK (10.0.19041.0) 或更新版本作為相依元件。%GameDKLatest%\GXDK\toolKit 中另有一些適用於 PC 端主機工具的標頭/程式庫。
自 2023 年 10 月版本起,Windows 11 SDK (10.0.22000.0) 是支援的最低版本。您也應該使用一些選項和定義。如需所有詳細資訊,請參閱「Visual C++ 編譯器與連結器參數建議」,以及 CMakeExample 範例。
編譯器 (cl.exe)
/D_GAMING_XBOX會取代/D_XBOX_ONE /D_TITLE和/D_DURANGO。/D_GAMING_XBOX_XBOXONE只會針對Gaming.Xbox.XboxOne.x64平台定義。/D_GAMING_XBOX_SCARLETT只會針對Gaming.Xbox.Scarlett.x64平台定義。/DWINAPI_FAMILY=WINAPI_FAMILY_GAMES會控制 API 分割,以取代WINAPI_FAMILY_TV_TITLEAPI 系列。- 您應該定義
/DWIN32_LEAN_AND_MEAN、/D_ATL_NO_DEFAULT_LIBS和/D__WRL_NO_DEFAULT_LIB__ - 針對 Microsoft Game Development Kit (GDK),您不再使用任何 Windows 執行階段參數,例如
/AI、/FU或/ZW。 - 繼續使用
/favor:AMD64、/EHsc和/fp:fast。 - 針對
Gaming.Xbox.XboxOne.x64平台,繼續使用/arch:AVX - 針對
Gaming.Xbox.Scarlett.x64平台,請使用/arch:AVX2
使用 VS 2019 Update 3 或更新版本以及Gaming.Xbox.Scarlett.x64平台時,也請使用/d2vzeroupper。如果您使用全程式最佳化 (WPO) / 連結時產生程式碼 (LTCG),則必須使用/d2:-vzeroupper。
使用 VS 2022 和Gaming.Xbox.XboxOne.x64平台時,也請使用/d2vzeroupper-。如果您使用全程式最佳化 (WPO) / 連結時產生程式碼 (LTCG),則必須使用/d2:-vzeroupper-。
連結器 (link.exe)
- 連結
xgameplatform.lib、xgameruntime.lib、d3d12_x.lib或d3d12_xs.lib、xmem.lib和pixevt.lib。請勿使用kernel32.lib、kernelx.lib、onecore.lib或WindowsApp.lib。 - 針對 XGraphics 程式庫,請使用
xg_x.lib或xg_xs.lib。 - 您不需要使用
/WINMD或/WINMDFILE,這些是用於 Windows 執行階段 API。 - XBOX 上的 Microsoft Game Development Kit (GDK) 不使用內嵌資訊清單,因此請使用
/MANIFEST:NO。 - 繼續使用
/DYNAMICBASE、/NXCOMPAT。
您應該考慮使用/NODEFAULTLIB,以確保您不會連結任何不支援的 Win32 程式庫,包括advapi32.lib comctl32.lib comsupp.lib dbghelp.lib gdi32.lib gdiplus.lib guardcfw.lib kernel32.lib mmc.lib msimg32.lib msvcole.lib msvcoled.lib mswsock.lib ntstrsafe.lib ole2.lib ole2autd.lib ole2auto.lib ole2d.lib ole2ui.lib ole2uid.lib ole32.lib oleacc.lib oleaut32.lib oledlg.lib oledlgd.lib oldnames.lib runtimeobject.lib shell32.lib shlwapi.lib strsafe.lib urlmon.lib user32.lib userenv.lib wlmole.lib wlmoled.lib onecore.lib。
最佳化 Windows 標頭的使用
Microsoft Game Development Kit (GDK) 使用標準的<Windows.h> 標頭。除了先前提到的 WIN32_LEAN_AND_MEAN 之外,定義各種精簡前置處理器定義也很有用,可讓您引入的 Win32 系統標頭總數維持在可控範圍內。
Visual C++ 執行階段
在 XBOX One Software Development Kit 中,Visual C++ 執行階段標頭和程式庫是 XBOX One Software Development Kit 的一部分,而執行階段 DLL 則放在 Game OS 內。這需要更新至較新的 XBOX One Software Development Kit 版本或 QFE 層級,以符合用來建置程式碼的 Visual Studio 次要更新版本。 在 Microsoft Game Development Kit (GDK) 中,Visual C++ 執行階段 DLL 會包含在您的遊戲套件中,並與建置電腦上本機安裝的 Visual Studio 版本相符。VCRuntime*.dll和msvcp*.dll是 Visual C++ 編譯器執行階段和標準 C++ 程式庫 DLL。Game OS 中也包含並使用ucrtbase.dll。- 針對偵錯組建,您的套件會包含
VCRuntime*d.dll、msvcp*d.dll和ucrbased.dll
如果您使用 ERA 移轉程式庫,也需要vccorlib*.dll,這是編譯器使用/ZW建置時所使用的檔案。
XBOX 不支援 AMP,且 AMP 已在最新的 Visual C++ 版本中淘汰。
應用程式啟動
Microsoft Game Development Kit (GDK) 專案使用精簡版的 Win32 桌面樣式應用程式啟動與訊息迴圈,而不是 Windows 執行階段樣式的 CoreWindow 事件。您現有的程式碼基底應該具有下列其中一個進入點。Win32 桌面開發
使用 C++/CX 的 XBOX One Software Development Kit 或 UWP 應用程式
使用 C++/WinRT 的 XBOX One Software Development Kit 或 UWP 應用程式
XBOX 上的 Microsoft Game Development Kit (GDK)
對於 GDK 遊戲,進入點與 Win32 傳統桌面相同。初始化應用程式
典型且非常基本的 Win32 進入點函式如下所示。- 盡量少用視窗類別和樣式
- 使用 UTF-8 而非 UTF-16LE 字串
- 初始化 Game Runtime 子系統
對於 XBOX 上的 Microsoft Game Development Kit (GDK) 遊戲,您只能有一個 Win32 視窗。
Windows 訊息迴圈
由於許多訊息並不適用,XBOX 上的 Microsoft Game Development Kit (GDK) 應用程式可以使用非常基本的 Win32 訊息迴圈。建立 Direct3D 裝置
使用 XBOX 上的 Microsoft Game Development Kit (GDK) 建置的遊戲會使用 Direct3D 12.X API,此 API 實作為單體式執行階段,與 XBOX One Software Development Kit 中的實作方式相同。
使用 XBOX 上的 Microsoft Game Development Kit (GDK) 建置的遊戲不支援原生 Direct3D 12 和 Direct3D 11。為 DirectX 12.X 建立 Direct3D 12 裝置時,請使用
D3D12XboxCreateDevice 方法。
XMem* API
任何使用XMEM_GRAPHICS 的 XMem* API 呼叫,都需要在使用前先建立 Direct3D 裝置。或者,如果您需要在 Direct3D 裝置存在之前使用這些呼叫,可以呼叫 D3DConfigureVirtualMemory。
CPU/GPU 保留
所有 Microsoft Game Development Kit (GDK) 遊戲都會取得完整資源 (亦即沒有 Kinect GPU 保留) 以及第七個 CPU 核心。根據預設,您會得到相當於下列 XBOX One Software Development Kit 資訊清單設定的效果。XBOX One 與 XBOX Series X|S 的 Direct3D 差異
Gaming.Xbox.XboxOne.x64 平台的 Direct3D 12.x 單體式執行階段實作,與 XBOX One Software Development Kit 的 Direct3D 12.x 實作幾乎相同。對於初次移植至 XBOX 上的 Microsoft Game Development Kit (GDK),此平台可能是最容易的起點。
Gaming.Xbox.Scarlett.x64支援至 ID3D12Device8 和 ID3D12GraphicsCommandList5 介面或更新版本。Gaming.Xbox.XboxOne.x64支援至 ID3D12Device、ID3D12Device1、ID3D12Device2 和 ID3D12GraphicsCommandList。
Gaming.Xbox.Scarlett.x64 平台時,Direct3D 12.x 實作中有一些額外的功能以及一些差異。
- 您需要使用不同版本的 Direct3D 標頭和程式庫 (也就是
d3d12_xs.h、d3dx12_xs.h、xg_xs.h、d3d12_xs.lib等)。您無法在同一個二進位檔中混用兩個版本的 Direct3D 12.x。 - Direct3D 12.x 單體式執行階段最初實作時,是建置在 Direct3D 11.x 單體式執行階段之上,因此使用
Durango或Gaming.Xbox.XboxOne.x64平台建置時,會定義一些 Direct3D 11 類型。這些類型已從 XBOX Series X|S 實作中移除,因此若有任何殘留的d3d11_x.h標頭、D3D11_*定義、CD3D11_*類別或ID3D11*介面參考,您可能會遇到建置問題。可以移除這些參考,仍然能為兩個平台建置。 - ESRAM 並非 XBOX Series X|S 的功能,因此此平台未定義與 ESRAM 相關的擴充功能。這也表示
xgmemory.h(用於使用 ESRAM 的協助程式) 僅支援Gaming.Xbox.XboxOne.x64平台。
在 XBOX One / XBOX One S 裝置上使用 ESRAM 以獲得最佳轉譯效能仍然很重要。請參閱 SimpleESRAM 和 AdvancedESRAM 範例。
- GPU 記憶體配置有許多差異,特別是 H-tile 和 C-Mask 技術。如需詳細資訊,請參閱 CMaskDecode、HiZDecode、HiStencil 和 PrimeHTile 範例。
呈現
XBOX 上的 Microsoft Game Development Kit (GDK) 不支援使用舊版 DXGI 交換鏈結進行呈現,而是使用 PresentX API。新的 PresentX API 旨在解決 DXGI 交換鏈結的延遲問題,並讓開發人員能更直接地控制呈現緩衝區。此 API 的設計也能擴展以支援未來的串流應用程式。 使用 PresentX 的第一步,是在建立 Direct3D 裝置之後註冊畫面格事件。D3D12_HEAP_FLAG_ALLOW_DISPLAY 旗標建立背景緩衝區資源,而不是建立 DXGI 交換鏈結並要求這些資源。
WaitFrameEventX 設定管線權杖。
DXGI_ERROR_DEVICE_REMOVED 和 DXGI_ERROR_DEVICE_RESET 錯誤,而 PC 遊戲則必須處理這些錯誤。
其他一些相關的 DXGI 功能已移除,而先前提到的 ScheduleFrameEventX 函式取代了 XBOX One Software Development Kit 中的 DXGIXSetFrameNotification。
以下是 XBOX One Software Development Kit 中用於畫面格翻轉通知的程式碼。
處理程序生命週期管理 (PLM)
使用 XBOX 上的 Microsoft Game Development Kit (GDK) 建置的遊戲,使用與 XBOX One XDK 應用程式和 UWP 應用程式相同的基本處理程序生命週期管理 (PLM) 模型。應用程式會以不受限制、受限制、暫停或終止的狀態執行;也就是說,終止時不會執行任何程式碼,處理程序會直接被終結。 XBOX One Software Development Kit 應用程式和 UWP 應用程式會透過其 Windows 執行階段 CoreWindow 接收通知。XBOX 上的 Microsoft Game Development Kit (GDK) 遊戲則透過已註冊的回呼接收通知。請注意,只有暫停和繼續事件,不再有明確的啟用階段。 一個簡單的實作方式是透過張貼WM_USER 訊息來處理。
WM_USER 訊息,以確保迴圈暫停直到繼續為止,並確保適當的 GPU 暫停/繼續行為在轉譯迴圈中的安全時間點發生。
受限制與完整
受限制與完整資源的通知是透過類似的 API 處理。處理程序終止
對於零售版遊戲,處理程序終止的處理方式與舊版 XBOX One Software Development Kit 平台相同。處理程序會先暫停,然後終止。不會處理任何 C++ 解構函式或清除作業。即使您呼叫了Windows::ApplicationModel::Core::CoreApplication::Exit,情況也是如此。
在 Microsoft Game Development Kit (GDK) 中,您可以像傳統 Win32 桌面應用程式一樣,透過 PostQuitMessage 達成乾淨的結束。這會讓您的訊息迴圈結束,並進行一般的程式碼清除和處理程序卸除。這在開發期間很有用,可協助偵測洩漏和其他原本難以找出的清除問題。不過,此行為可能會叫用在舊版 XBOX One Software Development Kit 平台中從未執行過的程式碼路徑。
記憶體管理
如需記憶體管理的詳細資訊,請參閱「記憶體概觀」。記憶體模型的變更
Microsoft Game Development Kit (GDK) 平台包含許多相對於原始 XBOX One Game OS 記憶體模型的變更。這項工作大部分著重於改善遊戲所使用記憶體與系統所使用記憶體之間的隔離。改善隔離可讓遊戲和系統的記憶體使用量更容易預測,並防止系統呼叫造成非預期的使用量。 在這項工作中,我們正移至最新版本的 Windows 記憶體管理子系統。雖然許多遊戲不需要任何重大變更,但您應仔細檢查這些記憶體 API 的使用方式。旗標的意義和行為已有所變更。 如果您手動配置和對應實體頁面,請記住,對應上的某些限制已變更,而且 API 應遵循不同的模式。- 當實體頁面多次對應至虛擬位址空間時,所有配置都必須共用相同的快取一致性設定。例如,您無法在同一實體記憶體上混用 Write Combined 和一般 CPU 讀取/寫入頁面設定。
- 頁面設定和快取一致性值現在位於頁面所對應的虛擬位址區域中。必須事先呼叫 XMemVirtualAlloc 並使用
MEM_RESERVE模式來保留此區域。舊版 OS 中不需要此步驟。
MEM_LARGE_PAGES 常數的地方。其值和意義已變更,以符合整個 Windows 中使用的意義。
隨著大型頁面從 XBOX One Game OS 中的 4 MB 變更為 XBOX 上的 Microsoft Game Development Kit (GDK) OS 中的 2 MB,XMemAlloc 的大型頁面大小指定值也已從
XALLOC_PAGESIZE_4MB 變更為 XALLOC_PAGESIZE_2MB。
我們的記憶體對應也已變更,不再分割為 Legacy、Title、Graphics 和 Physical 區域。這些區域現在涵蓋整個 8-TB 位址空間。
API 的變更
Microsoft Game Development Kit (GDK) 記憶體 API 以 XMem 前置詞開頭,而且大部分都對應現有 XBOX One XDK OS 中既有的 API,即使其行為已有所變更。
下表列出新的 API。
使用 XMemVirtualAlloc 而非 VirtualAlloc
在 Microsoft Game Development Kit (GDK) 中,新的XMemVirtualAlloc API 會取代所有用於配置 XBOX 圖形記憶體的 VirtualAlloc 用法。請注意先前所述的需求:針對稍後由實體對應支援的保留,需要指定 GPU 頁面和快取一致性需求。
在 XBOX One Software Development Kit 上進行此類保留的比較:
使用 VirtualFree
由VirtualAlloc 或 XMemVirtualAlloc 配置的記憶體仍使用 VirtualFree 釋放。沒有 XMemVirtualFree API。
XMemAlloc 用法
Attributes 巨集現在多了一個參數。例如:XMemAllocatePhysicalPages 和 XMemMapPhysicalPages
由於頁面旗標和快取一致性已移至保留時指定,配置和對應實體記憶體的呼叫已簡化,但其他方面與 XBOX One Software Development Kit 類似。XMemAllocatePhysicalPages 會取代 AllocateTitlePhysicalPages。XMemMapPhysicalPages 會取代 MapTitlePhysicalPages。
此 XBOX One Software Development Kit 程式碼:
程式設計模型
如需程式設計模型的詳細資訊,請參閱「非同步程式設計模型」主題。使用 GameRuntime 的同步 (封鎖) 程式碼
對於封鎖是合理選項的 API,所有程式庫功能都提供了封鎖 (同步) 版本,即使呼叫可能會長時間執行。開發人員可以產生執行緒,並使用排程器管理並行,從這些執行緒呼叫封鎖函式,這通常比 C++11 樣式的 future 和 promise 更容易實作。在某些情況下 (例如網路呼叫),已知函式的執行時間是非決定性的,因此只提供非同步版本。使用 GameRuntime 的非同步程式碼
Microsoft Game Development Kit (GDK) 平台包含新的模型,用於執行非同步工作並透過回呼回報其結果。此模型取代了 Windows 執行階段。請使用 GameRuntime API 指定非同步工作和回呼發生的方式和位置。 下列範例程式碼包含簡單的樣板範例,說明如何設定 Game Runtime 工作佇列來處理您的系統呼叫。此佇列可用於處理系統工作,同時 作為執行回呼的位置。從概念上來說,回呼是一種為了回應系統動作而執行 您的 程式碼的工作。如有需要,您可以建立多個工作佇列,以管理不同核心上的工作,或依每個呼叫指定執行回呼的佇列。 分派佇列中的工作項目可以由您的程式碼手動推送 (類似於 Windows 訊息佇列),也可以自動推送。以下是建立並推送手動推送佇列的簡單範例。非同步 API 呼叫的一般命名模式
下表顯示 Microsoft Game Development Kit (GDK) 和 Game Runtime 用於命名非同步呼叫的一般模式。XAsyncBlock 取代 IAsyncOperation 和 IAsyncAction
呼叫非同步函式時,請建立XAsyncBlock 結構,該結構在呼叫期間必須保持有效,直到呼叫完成、取消或失敗為止。
XAsyncBlock 類型包含三個直接相關的參數。
使用範例:
請注意,建立 XAsyncBlock 結構時務必將其「以零填滿」,因此要使用{}而不是()。
時間敏感作業
Microsoft Game Development Kit (GDK) 程式庫可讓您指定呼叫所在的執行緒是否對時間敏感。如果您從時間敏感的執行緒呼叫 非 時間敏感的函式,可能會回報執行階段警告。SetTimeSensitiveThread(true)。您也可以從自己程式碼中長時間執行的函式內呼叫 VerifyNotTimeSensitiveThread(),以回報來自時間關鍵執行緒的不當使用。
HLSL 著色器
XBOX One Software Development Kit 平台使用自訂版本的FXC.EXE HLSL 編譯器,支援將 Shader Model 5.1 可程式化著色器預先編譯為 ATI 微碼。此外,也支援 Shader Model 6 的 DXC.EXE DXIL 編譯器預覽版。
針對 XBOX 上的 Microsoft Game Development Kit (GDK),建議透過 DXC.EXE 使用 DXIL 編譯器和 Shader Model 6。FXC.EXE Shader Model 5.1 編譯器現在被視為舊版。新的編譯器支援舊編譯器所支援的大部分命令列旗標,不過某些 XBOX 專屬擴充 defines 不適用或不受支援。如需 Shader Model 6 和 DXIL 的詳細資訊,請參閱 GitHub 專案。
關於在 PC 上使用 Shader Model 6:Windows 10 Creators Update 和更新版本支援 Shader Model 6.x DXIL 著色器,許多零售版驅動程式也支援。您需要直接從廠商安裝最新的驅動程式,而不是依賴 Windows Update WHQL 驅動程式來取得此功能。適用於 Windows 的
DXC.EXE 編譯器包含在 Windows 10 April 2018 Update SDK 和更新版本中。在執行階段,您可以透過使用 D3D12_FEATURE_SHADER_MODEL 的 CheckFeatureSupport 判斷您的 PC 是否支援 Shader Model 6.x,但呼叫函式之前務必先初始化 shaderModel.HighestShaderModel!%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe。
XBOX Series X|S 版本的 DXIL 編譯器位於:%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe。
D3DCompile API
針對 Shader Model 6,您應該使用dxcompiler_x.lib 或 dxcompiler_xs.lib 程式庫,而不是 d3dcompiler_x.lib。
使用者管理
Microsoft Game Development Kit (GDK) 的使用者模型與您在 XBOX One Software Development Kit 中可能習慣的模型有所不同。這部分是為了更妥善地管理使用者對隱私權的期望,並減輕必須隨時追蹤系統在背景中對遊戲不需關心之使用者所做事情的負擔。系統只會依需求公開使用者,而不是讓遊戲監視整個系統中哪些使用者和來賓已登入主機的集合。 若要為您的遊戲取得使用者 (例如,當使用者按下控制器上的 A 按鈕以開始遊戲工作階段,而該控制器尚未與使用者建立關聯時),請呼叫 XUserAddAsync。此呼叫會執行兩項重要動作:將使用者登入遊戲,以及更新使用者輸入裝置配對。 使用者一次可以配對任意數量的輸入裝置。不過,遊戲只會得知已透過 XUserAddAsync 登入之使用者的關聯。如果在遊戲之外使用系統指南登入使用者,或將關聯變更為遊戲不知道的使用者,則遊戲只會被告知該輸入裝置已取消配對。不過,遊戲之外的系統仍然知道該配對以供系統使用。 遊戲可以透過訂閱XUserChangeEvent,監視使用者狀態或使用者相關 資訊 (例如其玩家代號、玩家圖片或權限) 的變更 (雖然部分資訊 (例如使用者登入狀態) 可透過輪詢來監視)。您可以呼叫 XUserRegisterForChangeEvent 來完成此作業。
大多數遊戲應預期需要建立自己的使用者集合、追蹤使用者何時登入遊戲、追蹤輸入裝置關聯,以及處理使用者登出的情況。
如需這些變更的深入討論,請參閱「使用者和輸入裝置」。另請參閱 UserManagement 範例。
網路與 XBOX services 整合
網路傳輸
XBOX 上的 Microsoft Game Development Kit (GDK) 同時支援 WinSock2 和透過 CNG 的 BCrypt。如果使用 UDP,針對 Microsoft Game Development Kit (GDK),您應該使用這個新的扁平 C API,而不是將多人遊戲通訊端繫結的連接埠硬式編碼為 3074 之類的值:Windows.Networking.Connectivity 命名空間。如需範例程式碼,請參閱「網路初始化與連線能力」。
Microsoft Game Development Kit (GDK) 已移除安全通訊端 (
Windows.Xbox.Networking 命名空間)。透過 HTTP 的 Web 要求
Microsoft Game Development Kit (GDK) 不再支援IXMLHTTPRequest2 或 MessageWebSocket / StreamWebSocket (Windows.Networking.Sockets 命名空間)。您應該改用 WinHTTP。
如需詳細資訊,請參閱「Web 要求」。
XBOX services API
目前使用 Windows 執行階段或 C++ 版本 XSAPI 的開發人員,需要改用扁平 C 版本來實現 XBOX services 整合功能:- 成就
- 目前狀態
- 個人檔案
- 社交
- Social Manager
後續步驟
完成從 ERA 的初次移植之後,您就能很好地為 XBOX 上的 Microsoft Game Development Kit (GDK) 啟用許多功能。如果您的遊戲在 XBOX One S / XBOX One X 硬體上執行良好,以下是改善 XBOX Series X|S 主機體驗的簡單方法。 請注意,其中許多功能會針對舊版 ERA 遊戲自動啟用,但對於 XBOX 上的 Microsoft Game Development Kit (GDK) 遊戲則需選擇加入。既然您的遊戲現在是原生 XBOX 上的 Microsoft Game Development Kit (GDK) 遊戲,請務必啟用這些功能!- AutoHDR:此功能會在系統層級自動將 SDR 遊戲轉換為 HDR,在支援 HDR10 的顯示器上遊玩時提升遊戲的視覺品質。它使用 XBOX Series X|S 專屬硬體,因此不會產生額外的 CPU、GPU、記憶體、頻寬或延遲。視覺增強不會改變原始的藝術意圖,並可將亮度擴展至最高 1000 尼特,色彩擴展至 P3-D65 色彩空間。原生 HDR 實作永遠會更好,可提供完整的藝術控制,但如果您沒有資源或時間實作原生 HDR,AutoHDR 是達成增強體驗的簡單又有效的方式。
- Aniso Boost:在 XBOX Series X|S 主機上,將線性紋理篩選提升為完整的非等向性篩選,可改善影像品質。這是將額外 GPU 效能套用至現有遊戲的快速簡便方式。身為 XBOX 上的 Microsoft Game Development Kit (GDK) 遊戲,您可以在 XBOX Series X|S 上執行時,為取樣器狀態使用
D3D12_FILTER_ANISOTROPIC設定而不是D3D12_FILTER_MIN_MAG_MIP_LINEAR來達成此目的:
- FPS Boost:另一項簡單的改善是提高 XBOX Series X|S 主機上的轉譯畫面播放速率。如果您的遊戲在 XBOX One S / XBOX One X 上以 30 fps (
D3D12XBOX_FRAME_INTERVAL_30_HZ) 執行,通常就能在 XBOX Series X|S 上以 60 fps (D3D12XBOX_FRAME_INTERVAL_60_HZ) 執行。如果在 XBOX One S/X 上以 60 fps 執行,則可能可以在 XBOX Series X|S 上以 120 fps 執行。如需詳細資訊,請參閱「120Hz 支援」和 Simple120Hz 範例。
除了提升畫面播放速率之外,您可能也能在 XBOX One X 和 XBOX Series X 上以 4K 轉譯,且效能與在 XBOX One S / XBOX Series S 上以 1080p 轉譯相同。
- Quick Resume:只要您的遊戲正確實作處理程序生命週期管理 (PLM),此功能大部分是自動的。如需詳細資訊,請參閱 XBOX 遊戲生命週期。
技巧與秘訣
Microsoft Game Config 封裝檔案
Microsoft Game Development Kit (GDK) 在 Visual Studio 建置工具鏈期間,不再使用Package.appxmanifest 檔案來產生 AppxManifest.xml。而是在開發期間使用 MicrosoftGameConfig 檔案來存放所有應用程式套件設定。
Executable Name 元素必須與套件配置中的 EXE 名稱相符。
請注意,您可以使用 Visual Studio 建立新專案。選取 File、New Project,然後從 Microsoft Game Development Kit (GDK) 選取 Direct3D 12 XBOX Game 範本。接著,您可以將範本所建立的 MicrosoftGame.config 新增至您的專案。
您也可以選擇新增 <ShellVisuals> 區段,以新增套件中必須存在的各種 UI 和市集相關資產。
請注意,XBOX One Software Development Kit 有 WideLogo 元素,現在則以 Square480x480Logo 屬性來參考。
針對 XBOX services 整合,您還需要提供 Title ID。
.config 檔案。如需允許選項的完整定義,請參閱「MicrosoftGameConfig 檔案」。
取得裝置類型
Microsoft Game Development Kit (GDK) 無法使用 XBOX One Software Development Kit 中的 GetConsoleType 方法。請改用 GameRuntime API XSystemGetDeviceType。xdk.h 和 _XDK_VER 的 GDK 替代項目
在 XBOX One Software Development Kit 中,xdk.h 標頭提供了一些與 XDK 組建編號、QFE 層級等相關的建置符號。
針對 Gaming.*.x64 平台,您可以使用 grdk.h:
_GRDK_VER是用來建置二進位檔的 Gaming GDK 版本編碼 (HIWORD.LOWORD)。例如,0x4A610479是組建編號 19041.1145。- 此組建的
_GRDK_VER_STRING是 “April 2020 GRDK”。 _GRDK_VER_STRING_W是與_GRDK_VER_STRING對等的 UTF16-LE 寬字串。- 該組建的
_GRDK_VER_STRING_COMPACT_W是包含 “April 2020” 的 UTF16-LE 寬字串。
Gaming.Xbox.*.x64 平台,您也可以使用 gxdk.h:
_GXDK_VER是用來建置二進位檔的 Gaming GDK 版本編碼 (HIWORD.LOWORD)。例如,0x4A610479是組建編號 19041.1145。- 此組建的
_GXDK_VER_STRING是 “April 2020 GXDK”。 _GXDK_VER_STRING_W是與_GXDK_VER_STRING對等的 UTF16-LE 寬字串。- 該組建的
_GXDK_VER_STRING_COMPACT_W是包含 “April 2020” 的 UTF16-LE 寬字串。
取得預設音訊轉譯端點識別碼
XBOX 上的 Microsoft Game Development Kit (GDK) 不使用 Windows 執行階段 API Windows.Media.Devices 和 Windows.Devices.Enumeration。若要取得預設轉譯器,請使用下列程式碼。MapVirtualKey
XBOX 上的 Microsoft Game Development Kit (GDK) 不支援MapVirtualKey 和 MapVirtualKeyEx 方法。這些方法最常用於在處理鍵盤的程式碼中偵測左右 VK_SHIFT 鍵。
MultiByteToWideChar 和 WideCharToMultiByte
在寬字元字串 (UTF-16 LE) 與窄字元字串之間轉換時,Win32 開發人員通常會使用 MultiByteToWideChar 和 WideCharToMultiByte。對於現代程式碼基底,我們建議您使用CP_UTF8,而不是特定字碼頁或 CP_ACP。
下列程式碼適用於 Windows 7 Service Pack 1 和更新版本。
CP_ACP 會被視為 CP_UTF8 的別名。在現代的 Windows 10 上以及搭配 Microsoft Game Development Kit (GDK) 時,您通常可以使用尋找和取代,將所有 CP_ACP 取代為 CP_UTF8。為了簡化這類移植,已移除其他與 CP_UTF8 相關參數的驗證。
C++11 新增了 <codecvt> 標頭,作為轉換字串問題更具可攜性的解決方案,但此標頭已在 C++17 中淘汰。建議繼續使用平台字串函式。
當地語系化和全球化 API
在 ERA 中,除了簡單的字碼頁選取、字碼指標轉譯 (將多位元組轉換為寬字元) 以及系統/使用者地區設定回報之外,大部分內建的 Windows 當地語系化支援都不存在。對於 Microsoft Game Development Kit (GDK),此當地語系化功能已完全支援,GetCurrencyFormatEx、GetNumberFormatEx、日期和時間格式列舉以及其他功能也都受到支援。
XMA2 音訊注意事項
如果您缺少SHAPE_XMA_INPUT_BUFFER_ALIGNMENT 的定義,則必須明確新增 shapexmacontext.h 標頭的參考。
UI 訊息方塊支援
為了協助改善遊戲內當機和早期初始化失敗的偵錯,已將XGameUiShowMessageDialogAsync 新增至遊戲可呼叫 UI (TCUI) API 集合。此 API 可在呼叫 XGameRuntimeInitialize 之後的任何時間點使用,甚至在 D3D 初始化之前。此 API 會在系統分割區內轉譯,並合成在遊戲輸出之上。即使遊戲迴圈已停止或尚未轉譯,它仍然可以運作。這對於回報當機錯誤資訊非常有用,甚至可以在錯誤發生處封鎖時提示附加偵錯工具。它主要是作為開發期間的診斷工具。
此範例顯示封鎖樣式的錯誤對話方塊,提示開發人員附加以進行調查。
擴充程式庫
在使用 Windows 執行階段 API 的 XBOX One Software Development Kit 中,新增 XSAPI 或 Game Chat 等擴充程式庫需要使用 Visual Studio 中的「References…」對話方塊。Microsoft Game Development Kit (GDK) 不再使用此機制。而是可以透過 Visual Studio 專案屬性新增這些程式庫。這會編輯vcxproj 之 Globals 區段中的屬性元素:
二進位相容性與元件重複使用
Microsoft Game Development Kit (GDK) 的指導原則之一,是盡可能提升開發人員在桌面 Windows 與 XBOX 主機遊戲之間重複使用其成果的能力。其中先前未討論的一個層面,是已進行改善桌面 Windows 與 XBOX OS 上的 Microsoft Game Development Kit (GDK) 之間二進位相容性的工作。 與 XBOX One Software Development Kit 遊戲不同,XBOX 上的 Microsoft Game Development Kit (GDK) 可以重複使用原本為 x64 桌面 Windows 建置的各種元件。對於原型設計、工具或其他非效能關鍵的情況,這可能是很有價值的省時功能。 Microsoft Game Development Kit (GDK) 中沒有工具可判斷桌面 Windows 元件是否可重複使用,但這取決於該元件所使用的作業系統 API。 您可以對 Microsoft Game Development Kit (GDK) 隨附的程式庫執行dumpbin.exe /exports,取得 XBOX OS 上的 Microsoft Game Development Kit (GDK) 支援的 API。雖然某些特定領域的 API 位於其專屬的程式庫中 (例如 d3d12_x.lib 或 d3d12_xs.lib 中的 D3D12XboxCreateDevice),但大部分舊版 Win32 API 都彙總在名為 xgameplatform.lib 的單一程式庫中。從 Visual Studio 開發人員命令提示字元執行下列命令時,會顯示受支援 Win32 API 的主要集合 (位於其他匯入程式庫中的 API 除外)。
dumpbin.exe /exports "c:\Program Files (x86)\Microsoft GDK\build_number\GXDK\gameKit\lib\amd64\xgameplatform.lib"
在上述範例路徑中,build_number 代表您系統上安裝的組建 (例如 190700)。
程式碼撰寫風格與最佳做法
Code Generation for XBOX One - Best Practices (XBOX Developer Downloads->XBOX One->All XBOX One XDK CHMs) 中的指引適用於 Microsoft Game Development Kit (GDK)。編譯器設定的主要差異在於,這些專案不需要使用 C++/CX (/ZW) 或 C++/WinRT,因為大多數遊戲 API 都採用 Win32 或 DirectX 樣式的 COM。以下是一些一般建議:
- 善用 C++14 以及 (選擇性) C++17 語言一致性。請注意,Microsoft Game Development Kit (GDK) 的 API 設計假設使用 C++11 或更好的編譯器。
- 產生 x64 原生浮點程式碼的流程一律使用 SSE/SSE2。XBOX One 支援
/arch:AVX以及 F16C。 - C++ 例外狀況處理 (
/EHsc) 在 x64 原生程式碼中幾乎沒有額外負荷。不過,在執行階段擲回例外狀況並不是效能考量的情況,因此不應該用來控制流程。 - 強烈建議的最佳做法是使用例外狀況安全的程式碼撰寫技術,例如 Objects Own Resources (RAII) 和 Resource Acquisition Is Initialization 中所述的技術,並使用
std::unique_ptr、Microsoft::WRL::ComPtr和其他智慧型指標類別。 - 優先使用標準可攜式類型,例如
size_t、ptrdiff_t、int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t、intptr_t和uintptr_t。 - 若要將內部填補降到最低,請將指標群組到結構和類別中。
- 優先使用 C++ 轉型,例如
const_cast<>、static_cast<>、reinterpret_cast<>和dynamic_cast<>,而不是舊版 C 樣式轉型。 - 盡可能使用內建函式。x64 原生程式碼不支援內嵌組譯碼。
編譯器與連結器參數
請使用下列參數:/O1 /Oi用於一般最佳化,/O2用於熱門模組/fp:fast/arch:AVX用於 XBOX One 系列裝置;/arch:AVX2用於 XBOX Series X|S。/favor:AMD- 全程式最佳化和特性指引最佳化
/OPT:REF,ICF連結器參數
/Ox 與 /O2 幾乎相同,但缺少 /GF (消除重複字串) 和 /Gy (啟用函式層級連結)。請優先使用 /O2 而不是 /Ox。如果您使用 /Ox,請務必至少明確啟用 /Gy,這對於啟用連結器最佳化很重要。
自 XBOX One Software Development Kit 推出以來,Visual C++ 也新增了許多編譯器參數,因此請務必詳閱:/Zc:inline、/Zc:throwingNew、/Zc:__cplusplus、/volatile:iso、/permissive-、/Zc:twoPhase- 和 /Debug:FASTLINK。
條件式程式碼
對於路徑分歧的條件式程式碼,請記住下列慣例。
如果您的程式碼基底已支援 XBOX One Software Development Kit,建議從下列步驟開始:
- 在程式碼基底中搜尋所有
_XBOX_ONE的執行個體 - 變更程式碼使用 DirectX 12.X 擴充功能之處的執行個體,例如
#if defined(_XBOX_ONE) && defined(_TITLE),將這些情況改為:
#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
全面使用 UTF-8
在 Windows 平台的漫長歷史中,原始的 ANSI 函式早已淘汰,改用寬字元 Unicode 解決方案,也就是使用 CreateFileW 而不是 CreateFileA。這解決了處理大量不同字碼頁的問題,並將所有可當地語系化的字串簡化為wchar_t* (UTF-16 LE,小端序)。UTF-8 Everywhere 宣言主張,就記憶體使用量和可攜性而言,使用 char* 的 UTF-8 多位元組編碼是更好的解決方案。
對於 XBOX 上的 Microsoft Game Development Kit (GDK) 平台,預設字碼頁設定為 CP_UTF8,因此 Win32 平台 API 的任何 ANSI 版本都會使用 UTF-8。您可以繼續搭配 UTF-16 LE 使用寬字元 API,但也可以選擇使用 UTF-8。
Windows 的完整 UTF-8 支援是最近才新增的,因此尚未廣泛使用。目前這也是使用者必須選擇加入的功能,因此您可能會發現,在低階使用 Win32 API 時保持使用寬字元 API,是可攜性方面的最佳選擇。
- 優先在您的 API 中使用 UTF-8,並僅在呼叫 Win32 寬字元 API 時才轉換為 UTF-16 LE。使用
std::string和char*作為 UTF-8,而不是使用std::wstring和wchar_t*。 - 對於窄字串常值,請使用 C++ 前置詞
u8,而不是不加前置詞或使用L,以確保遵循 UTF-8。 - 保留現有的
UNICODE和_UNICODE建置前置處理器defines(在 Visual Studio 中,這是<CharSet>屬性) 作為安全措施,但不要依賴巨集,而是一律明確呼叫W()或A()版本。 - 避免使用
TCHAR、TEXT()、LPTSTR和其他舊版文字類型與巨集。如需詳細資訊,請參閱「Microsoft Game Development Kit (GDK) 中的 UTF-8 支援」。
命名慣例:效能與行為提示
XBOX 上的 Microsoft Game Development Kit (GDK) 平台的 API 在設計上,會讓函式名稱隱含說明所呼叫函式的效能。 名稱中包含Get 或 Set 的函式,預期會是低負荷且可預測的。其效能也預期與呼叫 C++ 屬性包裝函式並以任何 memcpy 作業複製結果大致相同。如果函式使用 Query 而不是 Get,則表示這是長時間執行的作業,可能會封鎖直到完成為止。
對於執行計算而非簡單查詢的函式,除非文件另有說明,否則我們通常假設其效能大致符合您在檢查其輸入參數和所執行作業類型之後的預期。
名稱以 Async 結尾的函式是非同步作業,可能需要非常長或不確定的時間才能完成。在大多數情況下,我們會為可能需要長時間執行的函式提供封鎖和非同步版本。我們讓您決定哪一種最適合您的程式碼基底。在某些情況下 (例如網路 API),我們可能會完全省略封鎖版本,因為提供封鎖版本沒有意義。
如果函式名稱以 Show 開頭並以 Async 結尾,該函式會顯示 UI 元素,而且通常需要使用者互動才會傳回。在某些情況下,系統可以取消 UI 作業。
另請參閱
- 什麼是 Microsoft Game Development Kit?
- 開始使用 Microsoft Game Development Kit (GDK)
