Dispositivos perdidos (Direct3D 9)

Um dispositivo Direct3D pode estar em um estado operacional ou um estado perdido. O estado operacional é o estado normal do dispositivo no qual o dispositivo é executado e apresenta toda a renderização conforme o esperado. O dispositivo faz uma transição para o perdido estado quando um evento, como perda de foco do teclado em um aplicativo de tela inteira, faz com que a renderização para se tornar impossível. O estado perdido é caracterizado pela falha silenciosa de todas as operações de renderização, ou seja, os métodos de renderização podem retornar códigos de sucesso mesmo em caso de falha das operações de renderização. Nessa situação, o código de erro D3DERR_DEVICELOST é retornado por IDirect3DDevice9::P resent.

Por padrão, o conjunto completo de cenários que pode provocar a perda do dispositivo não é especificado. Alguns exemplos típicos incluem perda do foco, como quando o usuário pressionar ALT + TAB ou quando uma caixa de diálogo do sistema é inicializada. Os dispositivos também podem ser perdidos devido a um evento de gerenciamento de energia ou quando outro app assume a operação de tela inteira. Além disso, qualquer falha de IDirect3DDevice9::Reset coloca o dispositivo em um estado perdido.

Todos os métodos derivados de IDesconhecido têm garantia de funcionar depois que um dispositivo é perdido. Após a perda de dispositivo, cada função geralmente tem três opções:

  • Falha com D3DERR_DEVICELOST – isso significa que o aplicativo precisa reconhecer que o dispositivo foi perdido, para que o aplicativo identifique que algo não está acontecendo conforme o esperado.
  • Falha silenciosamente, retornando S_OK ou quaisquer outros códigos de retorno – se uma função falhar silenciosamente, o aplicativo geralmente não poderá distinguir entre o resultado de "êxito" e uma "falha silenciosa".
  • A função retorna um código de retorno.
Diferenças entre Direct3D 9 e Direct3D 9Ex:
Um dispositivo Direct3D 9 retorna D3DERR_DEVICELOST. Depois que ele tiver sido retornado de IDirect3DDevice9::P resent, o comportamento de emulação não funcionará mais e todas as chamadas futuras falharão até que o dispositivo seja redefinido com êxito.
Um dispositivo Direct3D 9Ex nunca retorna D3DERR_DEVICELOST, mas pode retornar novas mensagens de status (consulte alterações de comportamento do dispositivo).

 

Responder a um dispositivo perdido

Um dispositivo perdido deve recriar recursos (incluindo os recursos de memória de vídeo) depois que for redefinido. Se um dispositivo for perdido, o app consulta o dispositivo para verificar se é possível restaurar o estado operacional. Caso contrário, o app aguarda até que o dispositivo poder ser restaurado.

Se for possível restaurar o dispositivo, o app o prepara ao destruir todos os recursos de memória de vídeo e qualquer cadeias de permuta. Em seguida, o aplicativo chama o método IDirect3DDevice9::Reset . Reset é o único método que tem um efeito quando um dispositivo é perdido e é o único método pelo qual um aplicativo pode alterar o dispositivo de um perdido para um estado operacional. A redefinição falhará, a menos que o aplicativo libere todos os recursos alocados em D3DPOOL_DEFAULT, incluindo aqueles criados pelos métodos IDirect3DDevice9::CreateRenderTarget e IDirect3DDevice9::CreateDepthStencilSurface .

Na maioria das vezes, as chamadas de alta frequência do Direct3D não retornam informações sobre a perda do dispositivo. O aplicativo pode continuar a chamar métodos de renderização, como IDirect3DDevice9::D rawPrimitive, sem receber notificação de um dispositivo perdido. Internamente, essas operações serão descartadas depois que o dispositivo for redefinido para o estado operacional.

O aplicativo pode determinar o que fazer ao encontrar um dispositivo perdido consultando o valor retornado do método IDirect3DDevice9::TestCooperativeLevel .

Operações de bloqueio

Internamente, o Direct3D trabalha o suficiente para garantir que uma operação de bloqueio será bem-sucedida depois que um dispositivo for perdido. No entanto, não é garantido que os dados do recurso de memória de vídeo serão precisos durante a operação de bloqueio. É garantido que nenhum código de erro será retornado. Isso permite que os apps sejam gravados sem se preocupar com a perda de dispositivo durante uma operação de bloqueio.

Recursos

Os recursos podem consumir a memória de vídeo. Como um dispositivo perdido está desconectado da memória de vídeo do adaptador, não é possível garantir a alocação da memória de vídeo quando o dispositivo for perdido. Como resultado, todos os métodos de criação de recursos são implementados para ter êxito retornando D3D_OK, mas de fato alocam apenas memória fictícia do sistema. Como qualquer recurso de memória de vídeo deve ser destruído antes de redimensionar o dispositivo, não há nenhum problema em sobrealocar a memória de vídeo. Essas superfícies fictícias permitem que as operações de bloqueio e cópia apareçam para funcionar normalmente até que o aplicativo chame IDirect3DDevice9::P resent e descubra que o dispositivo foi perdido.

Toda a memória de vídeo deve ser liberada antes que um dispositivo possa ser restaurado de um estado perdido para operacional. Isso significa que o aplicativo deve liberar quaisquer cadeias de troca criadas com IDirect3DDevice9::CreateAdditionalSwapChain e quaisquer recursos colocados na classe de memória D3DPOOL_DEFAULT. O aplicativo não precisa liberar recursos nas classes de memória D3DPOOL_MANAGED ou D3DPOOL_SYSTEMMEM. Outros dados de estado são destruídos automaticamente pela transição para um estado operacional.

É recomendado desenvolver apps com um único caminho de código para responder à perda de dispositivo. Esse caminho de código é provavelmente semelhante, ou idêntico, ao caminho de código necessário para inicializar o dispositivo durante a inicialização.

Dados recuperados

O Direct3D permite que os aplicativos validem a textura e renderizem estados em relação à renderização de passagem única pelo hardware usando IDirect3DDevice9::ValidateDevice. Esse método, que normalmente é invocado durante a inicialização do aplicativo, retornará D3DERR_DEVICELOST se o dispositivo tiver sido perdido.

O Direct3D também permite que apps copiem imagens geradas ou gravadas anteriormente de recursos de memória de vídeo para recursos de memória não volátil do sistema. Como as imagens de origem dessas transferências podem ser perdidas a qualquer momento, o Direct3D permite que essas operações de cópia falhem quando o dispositivo for perdido.

Em relação a consultas assíncronas, IDirect3DQuery9::GetData retornará D3DERR_DEVICELOST se o sinalizador FLUSH for especificado, a fim de indicar ao aplicativo que IDirect3DQuery9::GetData nunca retornará S_OK.

A operação de cópia, IDirect3DDevice9::GetFrontBufferData, pode falhar com D3DERR_DEVICELOST, pois não há nenhuma superfície primária quando o dispositivo é perdido. IDirect3DDevice9::CreateAdditionalSwapChain também pode falhar com D3DERR_DEVICELOST porque um buffer de fundo não pode ser criado quando o dispositivo é perdido. Observe que esses casos são a única instância de D3DERR_DEVICELOST fora dos métodos IDirect3DDevice9::P resent, IDirect3DDevice9::TestCooperativeLevel e IDirect3DDevice9::Reset .

Sombreadores programáveis

No Direct3D 9, sombreadores de vértice e sombreadores de pixel não precisam ser recriados após a redefinição. Eles serão lembrados. Em versões anteriores do DirectX, um dispositivo perdido exigia que os sombreadores fossem recriados.

Dispositivos Direct3D