> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Suporte do Direct3D para suspensão e retomada

> Suporte do Direct3D para suspensão e retomada

Este tópico descreve o processo de suspensão e retomada da renderização gráfica do Direct3D em um título do Game OS.

* [Eventos de suspensão e retomada](#ID4EN)
* [Implicações para o agendamento de quadros e as estatísticas](#ID4FrameSchedulingResume)
* [Padrão de chamada](#ID4EEC)
* [Teste](#ID4EBF)

<a id="ID4EN" />

## Eventos de suspensão e retomada

No XBOX One, os aplicativos do Game OS podem ser suspensos e retomados pelo gerenciamento do tempo de vida do processo (PLM). No estado suspenso, a memória do aplicativo permanece intacta, mas o aplicativo não tem recursos de CPU nem de GPU. Um dos Requisitos do XBOX (XRs) para o XBOX One é que os aplicativos do Game OS implementem suspensão e retomada.

Se um aplicativo receber o evento **Suspending**, ele deverá chamar **SuspendX**. Caso contrário, o aplicativo será encerrado. As chamadas **SuspendX** e **ResumeX** devem operar no thread de renderização do título para garantir que o estado da GPU seja salvo corretamente pela chamada **SuspendX**.

Quando o título está suspenso, ele não pode renderizar nada até que a GPU seja retomada. Chamar qualquer API do Direct3D entre as chamadas **SuspendX** e **ResumeX** do Direct3D, como os métodos **ID3D12GraphicsCommandList::DrawInstanced** ou **ID3D12CommandQueue::ExecuteCommandLists**, gera uma exceção.

Veja a seguir os métodos de suspensão e retomada do Direct3D no XBOX One.

* [ID3D12CommandQueue::SuspendX](/pt-BR/reference/graphics/d3d12_x/interfaces/id3d12commandqueue/methods/id3d12commandqueue_suspendx)
* [ID3D12CommandQueue::ResumeX](/pt-BR/reference/graphics/d3d12_x/interfaces/id3d12commandqueue/methods/id3d12commandqueue_resumex)

Esses métodos devem ser invocados na fila de comandos gráficos, pois não são compatíveis com filas de computação e de cópia.

<a id="ID4FrameSchedulingResume" />

## Implicações para o agendamento de quadros e as estatísticas

A suspensão do aplicativo introduz uma interrupção não determinística no agendamento de quadros estabelecido. Considerando a natureza imprevisível do momento em que um evento de suspensão pode ocorrer, não é possível que o sistema restaure com segurança o agendamento estabelecido e seu estado temporal após o evento de retomada subsequente. Para oferecer um comportamento robusto e previsível, o agendamento de quadros do aplicativo é limpo pelo sistema durante o processamento da chamada **SuspendX**. A fila de apresentação é liberada para a tela, e todos os quadros iniciados por **WaitFrameEventX**, mas ainda não enviados à tela por meio de **PresentX**, são descartados.

Consequentemente, após retornar da chamada **ResumeX**, o aplicativo deve restabelecer o agendamento de quadros desejado por meio de chamadas para **ID3D12Device::SetFrameIntervalX** e **ID3D12Device::ScheduleFrameEventX** antes de prosseguir para aguardar a próxima origem de quadro. O aplicativo deve presumir um pipeline de quadros vazio após ser retomado.

<Note>
  Pode ser comum que um aplicativo receba um evento de suspensão enquanto aguarda que uma origem de quadro (ou outro evento de quadro) seja sinalizada durante uma chamada para **ID3D12Device::WaitFrameEventX**. Se o thread do aplicativo responsável por chamar **SuspendX** na fila de comandos gráficos for diferente daquele usado para aguardar eventos de quadro, a chamada **ID3D12Device::WaitFrameEventX** (embora iniciada antes da chamada **SuspendX**) poderá falhar com D3DERR\_DEVICEREMOVED.
</Note>

As estatísticas de quadros não persistem entre os limites de suspensão/retomada. Todos os tokens de quadro originados antes de uma suspensão serão considerados inválidos após a retomada, e as chamadas **ID3D12Device::GetFrameStatisticsX** que fizerem referência a eles para obter as informações estatísticas associadas falharão.

<a id="ID4EEC" />

## Padrão de chamada

Os aplicativos do Game OS recebem notificações por meio de retornos de chamada registrados. Há apenas um evento de suspensão e um de retomada, e não há mais uma fase de ativação explícita. Uma abordagem de implementação simples é lidar com a suspensão e a retomada publicando uma mensagem WM\_USER.

```cpp theme={null}
#include <appnotify.h>

PAPPSTATE_REGISTRATION hPLM = {};
HANDLE plmSuspendComplete = nullptr;
HANDLE plmSignalResume = nullptr;

// Create a window.

plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
plmSignalResume = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
if (!plmSuspendComplete || !plmSignalResume)
    return 1;

if (RegisterAppStateChangeNotification([](BOOLEAN quiesced, PVOID context)
{
    if (quiesced)
    {
        ResetEvent(plmSuspendComplete);
        ResetEvent(plmSignalResume);

        // To ensure we use the main UI thread to process the notification, we self-post a message.
        PostMessage(reinterpret_cast<HWND>(context), WM_USER, 0, 0);

        // To defer suspension, we must wait to exit this callback.
        (void)WaitForSingleObject(plmSuspendComplete, INFINITE);
    }
    else
    {
        SetEvent(plmSignalResume);
    }
}, hwnd, &hPLM))
    return 1;

// Message loop

UnregisterAppStateChangeNotification(hPLM);

CloseHandle(plmSuspendComplete);
CloseHandle(plmSignalResume);
```

Se a bomba de mensagens for executada em um thread de renderização com acesso exclusivo à fila de comandos gráficos, isso permitirá uma chamada direta a **SuspendX** e **ResumeX** do Direct3D de dentro do manipulador de mensagens WM\_USER. Todos os threads separados que enviam trabalho para filas de comandos assíncronas de computação ou de cópia devem ser instruídos a interromper as operações de fila antes da chamada para **SuspendX**.

```cpp theme={null}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
    switch (message)
    {
    case WM_USER:
        // Notify any threads using other command queues to halt operations and wait for acknowledgement.

        // Call SuspendX(0) on the graphics command queue, and cease all GPU submissions. This API is asynchronous so
        // that the game can continue doing work below.
        pGraphicsQueue->SuspendX(0);

        // Complete deferral.
        SetEvent(plmSuspendComplete);

        (void)WaitForSingleObject(plmSignalResume, INFINITE);

        // Before picking up rendering again, call ResumeX on the graphics command queue.
        pGraphicsQueue->ResumeX();

        // Notify any threads using other command queues that it's safe to resume operations.

        // Register again for frame events via SetFrameIntervalX and ScheduleFrameEventX.
        break;
    }
```

Se a bomba de mensagens for executada em um thread diferente de um ou mais daqueles com acesso à fila de comandos gráficos, ela deverá instruir o thread de renderização a fazer a chamada **SuspendX** e interromper o uso da fila (e, da mesma forma, lidar com **ResumeX** e as operações associadas).

Quando a chamada **SuspendX** é feita, o runtime do Direct3D salva o estado dos registradores de contexto, da CE RAM, da ESRAM, do armazenamento de dados global (GDS), dos buffers de índice, de alguns registradores da GPU (nem todos os registradores da GPU podem ser lidos) e da memória interna do CP. Esse estado é restaurado na chamada **ResumeX**.

O sistema PLM define quatro estados em que um aplicativo pode estar: **Unconstrained**, **Constrained**, **Suspended** e **Terminated**.

Para obter mais informações, consulte [Gerenciamento do tempo de vida do processo (Materiais de treinamento para desenvolvedores, Todos os white papers sob NDA)](https://aka.ms/xgddl).

<a id="ID4EBF" />

## Teste

Para permitir testes realistas de suspensão e retomada, há opções para o comando remoto [Gerenciamento de aplicativos (xbapp.exe)](/pt-BR/tools/tools-console/commandlinetools/xbapp). Consulte a seção sobre **xbapp suspend** nesse tópico e observe o arquivo em lotes de exemplo.

<a id="ID4EOF" />


## Related topics

- [Guia de programação do Direct3D 12](/pt-BR/build/gdk-and-engines/guides/directx-12-programming-guide.md)
- [Requisitos do XBOX para jogos do XBOX](/pt-BR/publishing/certification/xbox-requirements.md)
- [XR-112 Estabelecimento de um usuário e um controle durante a ativação inicial e a retomada](/pt-BR/publishing/certification/xr/xr-112.md)
- [Diretório de tópicos NDA: links ativos do Microsoft Learn](/pt-BR/nda/nda-topic-directory.md)
- [XR112 Estabelecimento de usuário e controle durante a ativação inicial e a retomada](/pt-BR/publishing/certification/fma/xr-112.md)
