Games for Windows and the DirectX SDK blog

Technical tips, tricks, and news about game development for Microsoft platforms including desktop, Xbox, and UWP


Project maintained by walbourn Hosted on GitHub Pages — Theme by mattgraham
Home | Posts by Tag | Posts by Month

Dual-use Coding Techniques for Games, part 2

win10, win8, winphone, xbox

Originally posted to Chuck Walbourn's Blog on MSDN,

Writing shared code for Windows Store, Xbox One, Universal Windows Platform (UWP) apps, and Win32 desktop apps

(continued from part 1)

Win32 APIs

The majority of the “core” API family are new Windows Runtime (WinRT) style APIs which are not available for down-level Win32 desktop applications. Therefore the overlap is in Win32 APIs that are available to both kinds of applications. In many cases, the Windows Store apps ‘core’ API family contains a Win32 API that is very recent. Therefore, a key technique for writing dual-use code properly is learning to leverage the _WIN32_WINNT control define for Windows Headers.

  • For Windows 8.1 support, _WIN32_WINNT is 0x0603 which is the default with the Windows 8.1 SDK / VS 2013 and is the value you expect to use for Windows Store apps for Windows 8.1 and Windows phone 8.1.
  • For Windows 8.x support, _WIN32_WINNT is 0x0602 which is the default with the Windows 8.0 SDK / VS 2012 and is the value you expect to use for Windows Store apps for Windows 8.0, Windows phone 8.0, and Xbox One.
  • For Windows 7 and Windows 8.x Win32 desktop support, _WIN32_WINNT should be 0x0601.
  • For Windows Vista, Windows 7, and Windows 8.x Win32 desktop support, _WIN32_WINNT should be 0x0600.
  • For Windows XP SP3 or Windows Server 2003 SP2, you must set _WIN32_WINNT to 0x0501 and use a Platform Toolset of “v110_xp” or “v120_xp” which selects the Windows 7.1 SDK that has limited DirectX integration. The Windows 8.x SDK does not support any platform prior to Windows Vista.

Windows 10: For Windows 10 support, _WIN32_WINNT is 0x0A00 which is the default with the Windows 10 SDK / VS 2015 and is the value you expect to use for Universal Windows Platform (UWP) apps.

Note: There are defines for these version constants, but be aware of the mix of Windows SDK versions you are building your code against. For example, _WIN32_WINNT_WIN10 is only defined for Windows 10 SDK, _WIN32_WINNT_WINBLUE is missing from the Windows 8.0 SDK, and _WIN32_WINNT_WIN8 is not in the Windows 7.1 SDK. You can define your own symbol if it is not already defined, but particularly in ‘public’ headers the direct use of the version numbers is the most robust choice.

Note: For Win32 APIs, you should prefer the use of the standard _WIN32_WINNT control define to conditional compile for Windows Store apps rather than symbol trying to make use of WINAPI_FAMILY macros directly.

For example, for Windows Store apps CreateFile2 must be used which is a Windows 8 only API. For down-level support, you will want to use CreateFile.

#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
ScopedHandle hFile(safe_handle(
    CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ,
        OPEN_EXISTING, nullptr)));
#else
ScopedHandle hFile(safe_handle(
    CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr,
        OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif
if (!hFile)
{
    return HRESULT_FROM_WIN32(GetLastError());
}

There’s one more detail in this particular case. For Windows Store/UWP apps, the typical default dwShareMode of 0 is likely to cause problems when you are trying to open a file for read-only access because ‘exclusive’ mode is only granted for files which the app has write privileges. If using a dwDesiredAccess of GENERIC_READ, you want to use dwShareMode of FILE_SHARE_READ as shown here.

Dual-use shared code should always make use of Unicode to support Windows Store apps (UNICODE and _UNICODE are defined) and is fully supported on down-level Win32 desktop apps. Universal use of Unicode and wchar_t is recommended, although TCHAR is still available if legacy ASCII/multi-byte support is required for some Win32 desktop scenario.

Use of TCHAR is definitely discouraged, and while “W” (UTF-16LE) versions of Win32 APIs is recommended/required for broad support, you might also want to adopt UTF-8 for your own interfaces. See UTF-8 Everywhere

Here are a number of Win32 APIs that are available to Windows Store apps when using the latest version.

Older API "Core" Win32 API `_WIN32_WINNT` Required
GetDiskFreeSpace \* GetDiskFreeSpaceEx
GetFileAttributes \* GetFileAttributesEx
FindFirstFile \* FindFirstFileEx
LockFile LockFileEx
MoveFile MoveFileEx
SetFilePointer \* SetFilePointerEx
UnlockFile UnlockFileEx
WaitForMultipleObjects \* WaitForMultipleObjectsEx
WaitForSingleObject \* WaitForSingleObjectEx
CreateEvent \* CreateEventEx 0x0600 (Windows Vista)
CreateMutex \* CreateMutexEx 0x0600 (Windows Vista)
CreateSemaphore \* CreateSemaphoreEx 0x0600 (Windows Vista)
GetFileSize GetFileSizeEx \* GetFileInformationByHandleEx 0x0600 (Windows Vista)
GetTickCount timeGetTime GetTickCount64 0x0600 (Windows Vista)
InitializeCriticalSection \* InitializeCriticalSectionAndSpinCount \* InitializeCriticalSectionEx 0x0600 (Windows Vista)
CopyFile, CopyFileEx CopyFile2 0x0601 (Windows 7)
CoCreateInstance \* CoCreateInstanceEx \* CoCreateInstanceFromApp 0x0602 (Windows 8)
CreateFile CreateFile2 0x0602 (Windows 8)
CreateFileMapping \* CreateFileMappingFromApp 0x0602 (Windows 8)
GetOverlappedResult \* GetOverlappedResultEx 0x0602 (Windows 8)
MapViewOfFile \* MapViewOfFileEx MapViewOfFileFromApp 0x0602 (Windows 8)

Windows 10: The APIs denoted by * above were added back for Universal Windows Platform (UWP) apps as of the Windows 10 Anniversary Update SDK (14393) to reduce porting changes.

Note: ReadFile and WriteFile are available for Windows Store apps and Windows phone 8, but ReadFileEx and WriteFileEx are not. They are supported for Universal Windows Platform (UWP) apps as of the Windows 10 Anniversary Update SDK (14393).

Here are some additional notes on Win32 APIs commonly used by games.

Win32 API Description
CreateThread SetThreadIdealProcessor SetThreadPriority Sleep(Ex) TlsAlloc

Windows Store apps for Windows 8.0 do not support POSIX-style threading APIs. These applications must use the Windows Runtime (WinRT) ThreadPool API in Windows.System.Threading.

For dual-use coding, you can make use of the C++11 Standard Library threading support and/or the Concurrency Runtime (ConcRT) which is supported for both Windows Store apps and Win32 desktop apps.

Update: Windows Store apps for Windows 8.1 can now use these threading APIs as of VS 2013 Update 4. They are also supported for Windows phone 8.1, Xbox One apps, and Universal Windows Platform (UWP) apps for Windows 10.

CreateProcess GetCommandLine GetEnvironmentStrings

Windows Store apps do not support POSIX-style process, command-line or environment variable APIs. These applications must use the Launcher class in the Windows.System namespace.

Note: Xbox One XDK supports some of these Win32 process APIs.

FindResource(Ex) LoadResource LockResource etc. Windows Store apps do not use Win32 style resource files. The recommendation is to include the required data as part of the AppX package and use standard file I/O to access them.
RegOpenKey(Ex) RegQueryKey(Ex) RegSetKey(Ex) etc. Windows Store apps do not use the Win32 registry. The recommendation is to store settings data in the application local directory using standard file I/O.
GlobalMemoryStatus(Ex)

There is no Windows Store app function available that will return physical or virtual memory information.

Windows 10: This is now supported for Universal Windows Platform (UWP) apps as of the Windows 10 Anniversary Update SDK (14393).

HeapAlloc

This is the standard memory allocation routine family is available for all applications.

LocalAlloc, GlobalAlloc are only available for Win32 desktop applications.

VirtualAlloc is not available for Windows 8.x Store apps or Windows phone 8.x apps.

Note: Xbox One XDK does support VirtualAlloc but does not allow EXECUTE page-level permission.

Windows 10: VirtualAlloc is supported for Universal Windows Platform (UWP) apps for Windows 10 as a remap for the new VirtualAllocFromApp.

LoadLibrary(Ex)

Windows Store apps must use LoadPackagedLibrary and the target DLL must be present in the application package or listed in the AppX manifest. The target DLL must therefore pass the Windows App Certification Kit (WACK) tool validation.

You have to use implicit linking with system DLLs, although you can use /DELAYLOAD if desired.

LoadString

Windows Store apps do not use Win32 style resource files for localization. These applications use ResourceLoader in the Windows.ApplicationModel.Resources namespace. See Microsoft Docs for more details.

Dual-use shared code should avoid directly displaying strings and should leave localization to the client application.

GetLogicalProcessorInformation

Windows store apps can't call GLPI. They can use GetNativeSystemInfo to get a rough count of the number of logical processors, and CPU Sets offers more details.

Windows 10: This is now supported for Universal Windows Platform (UWP) apps as of the Windows 10 Anniversary Update SDK (14393). CPU Sets is still a better option for UWPs running on non-Desktop family devices.

OpenGL

OpenGL is not supported for Windows Store apps, Windows phone 8.x, Xbox One, or Universal Windows Platform (UWP) apps for Windows 10.

Note: For OpenGL ES applications, you may find the Angle project useful.

QueryPerformanceCounter QueryPeformanceFrequency These functions are supported for all applications as the basis for high-resolution timers.
timeBeginPeriod timeEndPeriod Windows Store apps cannot change the global system timer resolution as this can negatively impact power-saving modes.
WinSock

The Windows Sockets 2 API is not available for Windows Store apps for Windows 8.0 and they must use the Windows Runtime (WinRT) API Windows.Networking.Sockets instead. TCP and UDP layer network communications are therefore not a good candidate for dual-use shared code, although an abstraction could be written with two different implementations.

Update: Windows Store apps for Windows 8.1 can now use WinSock 2.x as of VS 2013 Update 3. See this post. Winsock 2.x is also supported for Windows phone 8.x, Xbox One apps, and Universal Windows Platform (UWP) apps for Windows 10. Note that this support requires an IP-neutral dual-stack implementation (i.e. not legacy IPv4 only)

DirectPlay is not supported for Windows Store apps, Windows phone 8.x, Xbox One, or Universal Windows Platform (UWP) apps for Windows 10. DirectPlay is not recommended for Win32 desktop apps.

DirectX and Media Technologies

One of the reasons that dual-use shared code is possible for game technology is because many of the traditional DirectX Win32 APIs are available for Windows Store apps as well as down level for Win32 desktop apps.

DirectX Technology Notes
Direct3D 11.0, DXGI 1.1, Direct2D, and DirectWrite

These technologies are available for Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, and Win32 desktop apps for Windows 10, Windows 8.x, Windows 7, and Windows Vista SP2+KB971644.

Direct3D 9 and Direct3D 10.x are not supported for Windows Store apps, Windows phone 8.x, Universal Windows Platform (UWP) apps for Windows 10, or Xbox.

Note: Windows phone 8.0, Xbox One XDK, and Microsoft GDKX do not support Direct2D or DirectWrite.

Direct3D 11.1, DXGI 1.2, improved Direct2D and DirectWrite

These technologies are available for Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, and Win32 desktop apps on Windows 8.x and Windows 10. Partial support for these APIs is available for Win32 desktop applications on Windows 7 Service Pack 1 via KB 2670838.

Windows Store apps can rely on these technologies always being present, while Win32 desktop applications need to provide suitable fallbacks for older versions of Windows.

Direct3D 11.2, DXGI 1.3

These technologies are available for Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, and Win32 desktop apps for Windows 8.1 and Windows 10.

Windows Store apps for Windows 8.1 can rely on these technologies always being present, while Win32 desktop applications need to provide suitable fallbacks for older versions of Windows.

Note: Windows phone 8.0, Xbox One XDK, and Microsoft GDKX do not support Direct3D 11.2 / DXGI 1.3

Diret3D 12, Direct3D 11.3/11.4, DXGI 1.4/1.5

These technologies are available for Universal Windows Platform (UWP) apps for Windows 10 and Win32 desktop apps for Windows 10.

Universal Windows Platform (UWP) apps for Windows 10 can rely on these technologies always being present, while Win32 desktop applications need to provide suitable fallbacks for older versions of Windows.

Note: Microsoft GDKX for Xbox One and Xbox Series X|S only supports Direct3D 12.

D3DX

All versions of the D3DX utility library (D3DX9, D3DX10, and D3DX11) are deprecated, and are not supported for Windows Store apps, Windows phone 8, Xbox, or Universal Windows Platform (UWP) apps for Windows 10.

DirectX Tool Kit (DX11 / DX12), DirectXTex, DirectXMesh, and DirectXMath support Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, Windows phone 8.x, Xbox One, and Win32 desktop applications on Windows 10, Windows 8.x, Windows 7, and Windows Vista. These provide replacements for much of the functionality in D3DX for Direct3D 11. See "Direct3D 11 Textures and Block Compression" for more information.

The D3DCSX Compute Shader helper utility is available for Win32 desktop applications, but not for Windows Store apps or Windows phone 8.

The D3DX12 C++ helper library is header-only, supported on all DirectX 12 platforms, and is available on GitHub.

HLSL Compiler / D3DCompile

The HLSL compiler (FXC.EXE) and the D3DCompile (D3DCompiler_*.DLL) APIs are supported for both Windows Store apps and Win32 desktop apps.

Note that for Windows Store apps on Windows 8.0 and Windows phone 8.0, the HLSL compiler / D3DCompile APIs are only supported for development and not for deployment.

Windows Store apps for Windows 8.1, Windows Phone 8.1, Xbox One, and Universal Windows Platform (UWP) apps for Windows 10 have complete support for D3DCompile APIs. See "HLSL, FXC, and D3DCompile" for more information.

DirectX 12 on Windows 10 and Xbox via the Microsoft GDK use the DXIL Shader Model 6 Compiler (DXCompile API / DXC.EXE). See GitHub for more information.

Effects 11 (FX11)

The Effects 11 technology relies on runtime shader reflection via D3DReflect in the D3DCompiler. Due to the limitations above, this makes Effects 11 library unsuited to use in Windows Store apps for Windows 8.0 or Windows phone 8.0.

Note: HLSL Compiler support for the fx_5_0 profile required to use Effects 11 is deprecated.

DirectXMath

The DirectXMath library is supported for Windows Store, Universal Windows Platform (UWP) apps for Windows 10, Windows phone 8.x, Xbox, and Win32 desktop apps. This library provides SSE/SSE2 optimizations for Windows x86 and x64 native, as well as ARM-NEON optimizations for Windows RT and Windows phone 8.x. See "Introducing DirectXMath" for more information.

Note: DirectXMath on Xbox also makes use of SSE3, SSSE3, SSE 4.1, AVX, AVX2, and F16C as described in this blog series.

XAudio2

Windows 8.x and Windows 10 includes XAudio 2.8/2.9 which is supported for Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, Windows phone 8.x, and Xbox One. See "XAudio2 and Windows 8" for more details.

Windows 7 SP1 or later can use XAudio 2.9 via XAudio2Redist.

Windows Core Audio (WASAPI) is also available for use by low-level audio libraries.

DirectSound is not supported for Windows Store apps, Windows phone 8.x, Xbox, or Universal Windows Platform (UWP) apps for Windows 10.

XINPUT

Windows 8.x and Windows 10 includes XInput 1.4 which is supported for Windows store apps and Win32 desktop apps. Windows Vista, Windows 7, Windows 8.x, and Windows 10 also include XInput 9.1.0 which is supported for Win32 desktop applications. See "XInput and Windows 8" for more details.

DirectInput is not supported for Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, Windows phone 8.x, or Xbox.

Note: XINPUT is not supported by Windows phone 8.x or Xbox.

Xbox and Universal Windows Platform (UWP) apps for Windows 10 make use of a gamepad API which has similar functionality.

Windows Imaging Component (WIC)

This technology is available for Windows Store apps,Universal Windows Platform (UWP) apps for Windows 10, and Win32 desktop apps for Windows 10, Windows 8, Windows 7, and Windows Vista. Be sure to set the _WIN32_WINNT definition properly to ensure use of the correct version of the WIC factory. See "Windows Imaging Component and Windows 8" for more information.

Note: Windows phone 8.0 does not support WIC, but this is supported for Windows phone 8.1. Xbox One XDK / Microsoft GDKX does not support the JPEG XR / HD Photo codec and a few other aspects of 'standard' WIC.

Windows Media Foundation (MF)

The Windows Media Foundation is available for Windows Store apps, Universal Windows Platform (UWP) apps for Windows 10, and Win32 desktop applications on Windows 10, Windows 8, Windows 7, and Windows Vista. Be sure to read this post for some additional guidance.

DirectShow is not supported for Windows Store apps, Windows phone 8.x, Xbox, or Universal Windows Platform (UWP) apps for Windows 10.

Note: Windows phone 8.0 has partial support for the Media Foundation API, specifically IMFMediaEngine. Xbox One XDK and Microsoft GDKX also have partial support for the Media Foundation API.

(continued in part 3)