Skip to content

DeviceResources

Chuck Walbourn edited this page Dec 27, 2019 · 80 revisions

The DeviceResources class is an abstraction for the device & swapchain, and optionally a depth buffer. It's used in a number of DirectX Visual Studio Templates and samples as it simplifies the code by moving 'boilerplate' to a distinct set of files.

Related tutorial: Using DeviceResources

Header

#include "DeviceResources.h"

Interfaces

The Win32 and UWP versions both implement an abstract interface to simplify handling of "lost device" scenarios.

interface IDeviceNotify
{
    virtual void OnDeviceLost() = 0;
    virtual void OnDeviceRestored() = 0;
};

The Game class derives from this interface, and you should call RegisterDeviceNotify to provide the instance to the DR abstraction.

Xbox One XDK applications do not encounter "device removed" or "lost device" scenarios, so that version of DeviceResources does not have this interface.

Initialization

Typically the DR is used as follows:

Game::Game() noexcept(false)
{
    m_deviceResources = std::make_unique<DX::DeviceResources>();
    m_deviceResources->RegisterDeviceNotify(this);
}

Game::~Game()
{
    if (m_deviceResources)
    {
        m_deviceResources->WaitForGpu();
    }
}

void Game::Initialize(HWND window, int width, int height)
{
    m_deviceResources->SetWindow(window, width, height);

    m_deviceResources->CreateDeviceResources();
    // Create device-dependent resources

    m_deviceResources->CreateWindowSizeDependentResources();
    // Create windows-size dependent resourcdes
}

Methods

Accessors

  • GetD3DDevice: Returns the Direct3D device.

  • GetCommandQueue: Returns the Direct3D command queue.

  • GetCommandList: Returns the Direct3D graphics command list.

  • GetRenderTargetView: Returns the render target view for the swap chain back-buffer.

  • GetDepthStencilView: Returns the depth/stencil buffer created for the back-buffer.

  • GetScreenViewport: Returns a viewport for the swap chain back-buffer.

  • GetScissorRect: Returns a default scissor rectangle for the swap chain back-buffer.

  • GetCommandAllocator: Returns the Direct3D command allocator.

  • GetOutputSize: Returns the output size of the presentation window associated with the device.

  • GetSwapChain: Returns the DXGI swap chain interface.

  • GetDeviceFeatureLevel: Returns the Direct3D hardware feature level in use.

  • GetBackBufferFormat: Returns the format of the render target returned by GetBackBufferRenderTargetView.

  • GetDepthBufferFormat: Returns the format of the depth/stencil buffer returned by GetDepthStencilView.

  • GetCurrentFrameIndex: Returns the current present frame index (0-based).

  • GetBackBufferCount: Returns the number of back-buffers in the swap chain.

  • GetRenderTarget, GetDepthStencil: Returns the resource objects for the swap chain & depth/stencil buffer.

  • GetDeviceOptions: Returns the device options based on the ctor flags. If the system does not support the option, the flag will be cleared.

Threading model

The DeviceResources class methods are intended to be called from the main presenting thread, and not from other threads. The command-queue and command-list associated with DeviceResources is intended for use by this 'main' thread. Per the DirectX Graphics Infrastructure (DXGI): Best Practices, this presenting thread should also be the same thread as the main window message processing.

Platform notes

Universal Windows Platform apps

The UWP version includes GetRotation and GetOrientationTransform3D to simplify handling of display orientation.

m_spritesBatch->SetRotation( m_deviceResources->GetRotation() );

Matrix perspectiveMatrix = Matrix::CreatePerspectiveFieldOfView(
    fovAngleY, aspectRatio, nearDist, farDist );
m_projection = perspectiveMatrix * m_deviceResources->GetOrientationTransform3D();

-or-

XMMATRIX projection = XMMatrixPerspectiveFovLH(
    fovAngleY, aspectRatio, nearDist, farDist );
XMMATRIX orient = XMLoadFloat4x4( &m_deviceResources->GetOrientationTransform3D() );
projection *= orient;

This platform also uses an additional methods:

  • ValidateDevice is called from the DisplayInformation::DisplayContentsInvalidated handler, which can trigger a 'device removed' event.

The version of DeviceResources in the Visual Studio Universal Windows platform "Direct3D 12 App" template is a little different than the one linked above, although the basic design is the same. The primary difference is that the "Direct3D 12 App" template has a 'polling' model for device removed instead of using the IDeviceNotify callback.

Xbox One

The Xbox One XDK version of DeviceResources does not include the 'device lost' handling, and always uses a fixed back-buffer size. The DR version for Xbox One also uses DXGIX_SWAP_CHAIN_FLAG_QUANTIZATION_RGB_FULL rather than DXGIX_SWAP_CHAIN_MATCH_XBOX360_AND_PC.

Notes

Since the DeviceResources class is now in it's own file and no longer directly impacts the readability of the rest of the template, it has a few enhancements compared to the handling in non-DR templates.

  • If the SDK Debug Layer is not present on the target system when running Debug configurations, it will automatically fallback to creating the device without debugging.
  • If no hardware device is available, the DR version will fall back to using WARP in non-production builds as this is useful for debugging and validation.
  • In Debug configurations, additional diagnostic messages are output to the debug window.
  • Rather than always using the default Direct3D device, the DR version will filter out the Microsoft Basic Render Driver adapter as this fallback software device is seldom acceptable performance for games.
  • Since the Visual Graphics Diagnostics event-markup has been standardized for the Windows 10 SDK, the DirectX 12 DR templates are pre-populated with some basic mark-up to improve debugging.

Source

Next lesson: Adding the DirectX Tool Kit

Wide-gamut HDR rendering

If the ctor is created with the c_EnableHDR option flag, then the GetColorSpace property (on PC/UWP) needs to be used to determine if the swapchain is currently using sRGB (DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709), Linear (DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709), or HDR10 (DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) values. This can change whenever the window is moved or the HDR mode of the TV is modified, so should be checked each frame.

The HDR display support requires the Windows 10 Creators Update (15063) and must be built with the Windows 10 Creators Update SDK (15063).

The backBufferFormat for PC/UWP should be DXGI_FORMAT_R10G10B10A2_UNORM for rendering in HDR10 or DXGI_FORMAT_R16G16B16A16_FLOAT for rendering linear float values. The ToneMapPostProcess class supports the required color transformations for preparing an HDR10 signal, or tone-mapping for non-HDR displays.

For Xbox One, the backBufferFormat is actually the GameDVR SDR swapchain format which can be any 8:8:8:8 or 10:10:10:2 UNORM format. The HDR swapchain in this case is always DXGI_FORMAT_R10G10B10A2_UNORM using HDR10. You would typically use ToneMapPostProcess with the MRT mode enabled to generate both HDR10 and SDR signals at the same time.

See the tutorial Using HDR rendering for example usage.

Further reading

Direct3D Win32 Game Visual Studio template (Redux)
Anatomy of Direct3D 12 Create Device

Linear-Space Lighting (i.e. Gamma)
Chapter 24. The Importance of Being Linear, GPU Gems 3
Gamma-correct rendering

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Xbox One
  • Xbox Series X|S

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectXMesh

DirectXTex

DirectXMath

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally