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

DirectX and UWP on Xbox One

uwp, xbox

Originally posted to Chuck Walbourn's Blog on MSDN,

With the release of the Fall Creators Update (October 2017) for Xbox One, UWP apps can now opt into expanded resources as was announced in this Windows Blog post. Details about UWP on Xbox One can be found on Microsoft Docs, but in this blog post I’ll be talking about a few technical issues and specifics I encountered while updating the UWP samples on the Xbox-ATG-Samples GitHub and working with the UWP versions of my Direct3D Game template.

Game mode

By default all UWP apps run on the Xbox One (which must support either the “Universal” or “Xbox” device family and be built for the x64 architecture) run in a shared system mode with a subset of system resources with the remainder of the system resources reserved for games. With the latest version of the OS, a UWP app can declare itself a ‘Game’ which will give it access to additional memory, CPU, and GPU resources.

When an application is published, this is handled by Windows Store metadata that indicates it is a ‘Game’ rather than an ‘App’. During development, you manually set the package’s type to ‘Game’ via the DevHome interface.

First, build & deploy the application package to the Xbox One. Then using the Xbox One game controller, highlight the package in DevHome’s Games & apps list:

Then press the View button to bring up the context menu:

Go down to the bottom to View details and press the A button:

This brings up the App details page and the App type field should be selected. Use the combo box to set it to “Game” by pressing A, down on the D-pad, and then pressing A again. Then press B to return to the main page.

When you start the application, it will be running in Game mode.

Note that the “expandedResources” restricted capability in the Appx manifest still exists, but it’s use is deprecated. While I make use of it in some of the ATG samples to simplify deployment, any UWP submitted to the Windows Store will fail submission if it makes use of this restricted capability.

Note: You can also use the Xbox Device Portal (Windows Device Portal on Xbox) to configure your Xbox One to default to “Game” rather than “App” for newly deployed development apps as of the November 2017 update. If you change this setting, keep in mind that if you also want to develop a non-game application, you should explicitly set it to ‘App’ using the instructions above.

DirectX 11

For UWP on Xbox One, the DirectX 11 device is supported using Direct3D Feature Level 10.0. This is still true in Game mode, although you have significantly more GPU resources available to you than when you run as an ‘App’.

The default DirectX 11 device creation for a UWP app typically includes the 9.3 and later Direct3D feature levels:

D3D_FEATURE_LEVEL lvl[] =
{
    D3D_FEATURE_LEVEL_11_1,
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
    D3D_FEATURE_LEVEL_9_3
};

In practice Direct3D Hardware Feature Level 10.0 provides a significant set of capabilities suitable for many games:

Supported for DirectX 11 (UWP on Xbox One) Not supported
Shader Model 4.0 Shader Model 5 DirectCompute
Geometry Shader and Stream Out Tessellation/Hull Shaders
BC1/BC2/BC3/BC4/BC5 BC6H/BC7
1D, 2D, 3D Textures 1D and 2D Texture Arrays Cubemaps Cubemap arrays
Instancing, Alpha-to-coverage, Event queries MSAA texture per-sample shaders
8092 maximum texture size

Note that in development mode, if you try to create a DirectX 11 device and do not provide the option of using D3D_FEATURE_LEVEL_10_0, then you will end up with a WARP software device rather than the much faster hardware device. Remember also that WARP it not supported for retail Xbox One machines.

Xbox Series X|S: When using UWP on Xbox Series X|S, Direct3D Hardware Feature Level 11.0 is supported for DirectX 11 for both App and Game mode. See this blog post for updates.

See Anatomy of Direct3D 11 Create Device for more details on DirectX 11 device creation.

DirectX 12

For UWP on Xbox One, DirectX12 is supported as Direct3D Hardware Feature Level 11.0 while in Game mode. It supports Shader Model 5.1 and Shader Model 6.4 shaders.

Note that in development mode, if you try to create a DirectX 12 device while not in Game mode, you will end up with a WARP software device rather than the much faster hardware device. Remember also that WARP it not supported for retail Xbox One machines.

See Anatomy of Direct3D 12 Create Device for more details on DirectX 12 device creation.

Xbox Series X|S: When using UWP on Xbox Series X|S, Direct3D Hardware Feature Level 11.0 is supported for DirectX 12 for both App and Game mode. See this blog post for updates.

Game controller usage

If you are using the Direct3D app model for your game rather than XAML or Direct3D+XAML, an important thing to note is that you need to handle the BackRequested navigation event. This event is generated whenever the B button is pressed on the Xbox One game controller, and if not handled it will result in the application being suspended as control is returned to DevHome (or the previous app). Typically Direct3D games would use Windows.Gaming.Input (or the XINPUT emulator library xinput_uap.lib) to react directly to the use of the B button as appropriate to the game control scheme rather than rely on the notion of a ‘page stack’.

See also GamePad in the DirectX Tool Kit (DX11 / DX12).

C++/CX

If using C++/CX (a.k.a. /ZW) then you can implement this as follows:

virtual void SetWindow(CoreWindow^ window)
{
    ...
    auto navigation =
        Windows::UI::Core::SystemNavigationManager::GetForCurrentView();
    navigation->BackRequested +=
    ref new EventHandler<BackRequestedEventArgs^>(this,
        &ViewProvider::OnBackRequested);
}

void OnBackRequested(Platform::Object^,
    Windows::UI::Core::BackRequestedEventArgs^ args)
{
    // UWP on Xbox One triggers a back request whenever the B
    // button is pressed which can result in the app being
    // suspended if unhandled
    args->Handled = true;
}

C++/WinRT

If using the C++/WinRT projections, then you can implement this as:

void SetWindow(CoreWindow const & window)
{
    
    auto navigation = SystemNavigationManager::GetForCurrentView();
    // UWP on Xbox One triggers a back request whenever the B
    // button is pressed which can result in the app being
    // suspended if unhandled
    navigation.BackRequested([](const winrt::Windows::Foundation::IInspectable&,
        const BackRequestedEventArgs& args)
    {
        args.Handled(true);
    });
}

4K

For UWP on Xbox One apps, the system always indicates a window size of 1920 x 1080 (i.e. 1080p). If the TV is running as 4K on an Xbox One S or Xbox One X, the swapchain content is automatically scaled up by the display hardware.

It is also possible to create a native 4k swapchain, but it’s recommended you only do this while running on an Xbox One X. You can check which device the UWP is running on via a new Windows 10 Fall Creators Update SDK (16299) API:

#include "Gamingdeviceinformation.h"

GAMING_DEVICE_MODEL_INFORMATION info = {};
GetGamingDeviceModelInformation(&info);
if (info.vendorId == GAMING_DEVICE_VENDOR_ID_MICROSOFT)
{
    switch (info.deviceId)
    {
    case GAMING_DEVICE_DEVICE_ID_XBOX_ONE:
    case GAMING_DEVICE_DEVICE_ID_XBOX_ONE_S:
        // Keep swapchain at 1920 x 1080
        break;

    case GAMING_DEVICE_DEVICE_ID_XBOX_ONE_X:
    case GAMING_DEVICE_DEVICE_ID_XBOX_ONE_X_DEVKIT:
    default: // Forward compatibility
        m_outputWidth = 3840;
        m_outputHeight = 2160;
        break;
    }
}

Note that if your UWP app has a Target Platform Minimum Version before 10.0.0.16299, then you need to guard the use of GetGamingDeviceModelInformation as follows:

#include <libloaderapi2.h>
extern "C" IMAGE_DOS_HEADER __ImageBase;
...
// Requires the linker settings to include
// /DELAYLOAD:api-ms-win-gaming-deviceinformation-l1-1-0.dll

if (QueryOptionalDelayLoadedAPI(
    reinterpret_cast(&__ImageBase),
    "api-ms-win-gaming-deviceinformation-l1-1-0.dll",
    "GetGamingDeviceModelInformation",
    0))
{
    GAMING_DEVICE_MODEL_INFORMATION info = {};
    GetGamingDeviceModelInformation(&info);
    if (info.vendorId == GAMING_DEVICE_VENDOR_ID_MICROSOFT)
    {
        switch (info.deviceId)
        {
        case GAMING_DEVICE_DEVICE_ID_XBOX_ONE:
        case GAMING_DEVICE_DEVICE_ID_XBOX_ONE_S:
            // Keep swapchain at 1920 x 1080
            break;

        case GAMING_DEVICE_DEVICE_ID_XBOX_ONE_X:
        case GAMING_DEVICE_DEVICE_ID_XBOX_ONE_X_DEVKIT:
        default: // Forward compatibility
            m_outputWidth = 3840;
            m_outputHeight = 2160;
            break;
        }
    }
}

You set the delay load via the Visual C++ project settings:

If you use a native 4k swapchain on Xbox One X and the TV is in a 1080p mode, then image is downscaled automatically by the display hardware which does have the effect of ‘super-sampling’ for better image quality. In other words, if you decide to render at native 4k, you should do so regardless of the TV setting.

For Xbox Series S, you should use 1440p (2560 x 1440) instead of 4K, although there’s no easy way to detect this platform at the moment within UWP. 1080p is a reasonable default for this platform as well.

HDR

UWP on Xbox One apps have limited access to the High-Dynamic Range (HDR) capabilities of the Xbox One S and the Xbox One X. For games looking to implement HDR, contact the ID@Xbox program.

Tools

The Visual Studio Graphics Diagnostics (a.k.a. VSPIX) supports UWP on Xbox One.

Note that neither the Xbox PIX nor the “new” PIX tool currently support UWP on Xbox One.

Related: Windows 10 Fall Creators Update SDK