Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As cadeias de troca controlam a rotação do buffer traseiro, formando a base da animação gráfica.
Visão geral
O modelo de programação para cadeias de troca no Direct3D 12 não é idêntico ao das versões anteriores do D3D. A conveniência de programação, por exemplo, de oferecer suporte à rotação automática de recursos, presente no D3D10 e no D3D11, não é mais oferecida. A rotação automática de recursos permitia aos aplicativos renderizar o mesmo objeto da API, enquanto a superfície real renderizada mudava a cada quadro. O comportamento das cadeias de troca é alterado com o Direct3D 12 para permitir que outros recursos do Direct3D 12 tenham baixa sobrecarga de CPU. A chave de cor automática e multiamostragem não são compatíveis, embora, notadamente, alongamento e rotação ainda sejam.
Tempo de vida do buffer
Os aplicativos podem armazenar descritores pré-criados que fazem referência a back buffers. Isso é habilitado garantindo que o conjunto de buffers pertencentes a uma cadeia de troca nunca mude durante o tempo de vida da cadeia de troca. O conjunto de buffers retornados por IDXGISwapChain::GetBuffer não é alterado até que determinadas APIs sejam chamadas:
A ordem dos buffers retornados por GetBuffer nunca é alterada.
IDXGISwapChain3::GetCurrentBackBufferIndex retorna o índice do buffer de fundo atual para o aplicativo.
Efeitos de troca
Os únicos efeitos de troca com suporte são DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL e DXGI_SWAP_EFFECT_FLIP_DISCARD, o que exige que a contagem de buffers seja maior que uma.
Dica
Para jogos que segmentam a latência de entrada mínima, crie a cadeia de troca com DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING e, em seguida, chame Present(0, DXGI_PRESENT_ALLOW_TEARING). Isso contorna o vsync do compositor e proporciona a menor latência entre a apresentação e a exibição. Em runtime, verifique o suporte à divisão chamando IDXGIFactory5::CheckFeatureSupport com DXGI_FEATURE_PRESENT_ALLOW_TEARING antes de usar esse caminho.
Aviso
Um bug no ritmo de quadros comum consiste em chamar Present(1, 0) (vsync-on) sem sincronizar devidamente o trabalho da CPU com o limite de GPU. Isso faz com que a CPU seja executada com antecedência, acumulando uma fila de quadros que aumenta a latência de entrada. Sempre use um limite de contagem de quadros para restringir quadros de CPU em versão piloto (normalmente à contagem do buffer menos um).
Transição entre os modos de janela e tela inteira
O Direct3D 12 não dá suporte ao FSE (modo exclusivo de tela inteira). Em vez disso, quando um jogo é o único aplicativo visível na tela, o sistema operacional usa uma estratégia chamada FSO (otimizações de tela inteira) para obter um efeito semelhante ao FSE sem as desvantagens de desempenho. Para obter mais informações sobre o FSO, consulte Desmistificando as otimizações de tela inteira.
O Direct3D 12 mantém a restrição de que os aplicativos devem chamar ResizeBuffers após alternar entre os modos de janela e tela inteira (as swap chains do modelo flip do D3D11 têm as mesmas restrições).
As transiçõesIDXGISwapChain::SetFullscreenStatenão alteram o conjunto de buffers visíveis do aplicativo na cadeia de troca. Somente as chamadas ResizeBuffers e ResizeTarget criam ou destroem buffers visíveis para o aplicativo. No entanto, no Direct3D 12 IDXGISwapChain::SetFullscreenState não entra no modo exclusivo de tela inteira e simplesmente altera as resoluções e as taxas de atualização para permitir otimizações de tela inteira. Essas alterações podem ser feitas por um aplicativo sem o uso desse método
Quando IDXGISwapChain::P ent ou IDXGISwapChain1::P resent é chamado, o contrabuffer a ser apresentado deve estar no estado D3D12_RESOURCE_STATE_PRESENT. O presente falhará com DXGI_ERROR_INVALID_CALL se esse não for o caso.
As cadeias de troca em tela inteira continuam sujeitas à restrição de que SetFullscreenState(FALSE, NULL) deva ser chamado antes da liberação final da cadeia de troca. SetFullscreenState(FALSE) é bem-sucedido em cadeias de troca em execução em dispositivos Direct3D 12.
As operações presentes ocorrem na fila 3D fornecida na criação de swapchain e os aplicativos estão livres para apresentar simultaneamente várias cadeias de troca e registrar e executar listas de comandos.
Quando a parte final do trabalho gráfico (por exemplo, o pós-processamento de quadros) é executada em uma fila de computação, ou não envolve a fila de gráficos do dispositivo, criar uma segunda fila 3D para apresentação pode ser benéfico e evitar que a latência da apresentação atrase o início do próximo quadro.
Exemplo
O código de exemplo a seguir estaria presente no loop de renderização principal:
Aviso
O exemplo a seguir é simplificado para maior clareza. O loop principal de um jogo em produção deve separar atualizações de simulação da frequência de renderização – por exemplo, usando um timestep fixo para a simulação durante a renderização o mais rápido possível – e usar um limite para restringir os quadros em versão piloto. Sem a limitação da versão piloto do quadro, o Present pode ser concluído imediatamente em cadeias de troca do modelo flip, permitindo que a CPU enfileire quadros sem limite e aumente a latência de entrada.
void Present()
{
m_swapChain->Present(0, m_presentFlags);
m_backBufferIndex = (m_backBufferIndex + 1) % m_backBufferCount;
}
Criando cadeias de troca
Ao usar as chamadas CreateSwapChainForHwnd, CreateSwapChainForCoreWindow ou CreateSwapChainForComposition, observe que o parâmetro pDevice na verdade requer um ponteiro para uma fila de comandos diretos no Direct3D 12, e não um dispositivo.
Apresentando no Windows 7
Ao usar o Direct3D 12 no Windows 7, os tipos DXGI necessários para o Direct3D 12 não estão disponíveis, logo, você deve usar ID3D12CommandQueueDownLevel fornecido pelo D3D12On7 (obtido na fila de comandos diretos), para fazer a apresentação.
Você fornece uma lista de comandos em aberto ao método de apresentação do Windows 7, que então será usada, fechada e enviada automaticamente ao dispositivo em seu nome. Você deve fornecer um buffer de fundo que deve ser criado pelo aplicativo, deve ser um recurso confirmado, deve ser de amostra única e deve ser um dos seguintes formatos.
- DXGI_FORMAT_R16G16B16A16_FLOAT
- DXGI_FORMAT_R10G10B10A2_UNORM
- DXGI_FORMAT_R8G8B8A8_UNORM
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
- DXGI_FORMAT_B8G8R8X8_UNORM
- DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
- DXGI_FORMAT_B8G8R8A8_UNORM
- DXGI_FORMAT_B8G8R8A8_UNORM_SRGB