Direct3D Support for Suspend and Resume

Describes the process of suspending and resuming the Direct3D graphics rendering of a Game OS title.

Suspend and Resume events

On Xbox One, Game OS apps can be suspended and resumed by the Process Lifetime Manager (PLM). In the suspended state, the app’s memory is left intact, but the app has no CPU or GPU resources. It is an XR requirement for Xbox One that Game OS apps implement suspend and resume.

If an app receives the Suspending event, the app must call Suspend, otherwise the app will be terminated. Both the Suspend and Resume calls must operate on the title’s render thread, to ensure that GPU state is saved off correctly by the Suspend call.

When the title is suspended, the title cannot render anything until the GPU is resumed. Calling any Direct3D APIs in between Direct3D Suspend and Resume calls, such as calling ID3D11DeviceContext::Draw… methods, will throw an exception.

The interface and methods for suspend and resume for Monolithic Direct3D are:

The following are the suspend and resume methods for Direct3D on Xbox One:

Same thread call pattern

The following call pattern shows how the events might be handled if the render thread is on the same thread as the suspend and resume handlers. The game loop is setup to call ProcessEvents before calling Render, so the Suspend event will be received at the beginning of the render loop. m_pCurrentContext is a pointer to the current context (ID3D11DeviceContextX).

void ApplicationView::Run()
{
  CoreDispatcher^ dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;
  while (!m_windowClosed)
  {
    // Suspend will get called from within ProcessEvents
    dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
    m_game->Tick();
  }
}  

This enables a simple call to Direct3D Suspend from within a title’s suspend handler.

// Called when the application is suspending.
void ApplicationView::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
{
  // Call Direct3D Suspend. This API is asynchronous so that the game can continue doing work below.
  m_pCurrentContext->Suspend(0);
  // TODO: Save game progress using the ConnectedStroage API (seeSaving Data Using Connected Storage).
}  

After the OnSuspending method returns, the game threads will be frozen.

// Called when the application is resuming from suspended.
void ApplicationView::OnResuming(Platform::Object^ sender, Platform::Object^ args)
{
  // TODO: Handle any changes in users and input devices
  m_pCurrentContext->Resume();
}  

After the OnResuming method returns, the game loop will continue with the call to Tick().

When the Suspend call is made, the Direct3D runtime will save the state of the context registers, CE RAM, ESRAM, GDS, Index buffers, some GPU registers (not all the GPU registers are readable), and CP internal memory. This state will be restored on the Resume call.

The PLM system defines five states that an app can be in: Running, Constrained, Suspended, NotRunning, and Terminated.

Refer also to the white paper:

Different thread call pattern

If the render thread is on a different thread than the suspend and resume handlers, the handling of suspend and resume is a bit more complicated as it requires co-ordination between the render thread and the OnSuspending/OnResuming handlers.

To demonstrate this process a sample, GPU Suspend and Resume, is available from Samples.

In this sample the render thread is on a different thread than IFrameworkView::Run.

Testing

In order to enable realistic testing of suspend and resume, there are options for the remote command Application Management (xbapp.exe). See the section on xbapp suspend in that topic, and note the sample batch file.

See also

DirectX