Caminho da apresentação DXGI
O DXGI fornece aos aplicativos uma metodologia de apresentação que "apenas funciona". Por exemplo, os aplicativos não são necessários para executar operações especiais para fazer a transição entre o modo de janela e o modo de tela inteira. Essa metodologia de apresentação é possível porque o DXGI e o driver de exibição do modo de usuário trabalham juntos para preservar a apresentação entre combinações de MSAA (Multi Sample Anti Aliasing), monitorar as diferenças de rotação, buffer traseiro e frontal no tamanho e no formato e modos de tela inteira versus janelas. Outra vantagem do DXGI é que ele permite que um adaptador de vídeo tenha capacidade limitada de verificar MSAA e superfícies giradas porque o DXGI fornece uma DDI "sem estado". Em uma DDI sem estado, o driver do adaptador não é necessário para registrar dados em chamadas DDI.
A tarefa básica da apresentação é mover dados de um buffer de fundo renderizado para a superfície primária para exibição. Essa tarefa é executada nas diferentes situações descritas nas seções a seguir.
Modo em janela com DWM ativado
No modo em janelas com o caso dwm (Gerenciador de Windows) da área de trabalho, o DXGI se comunica com DWM e abre uma exibição de um recurso compartilhado que é um destino de renderização para o produtor DXGI e uma textura para DWM. Esse recurso compartilhado existe além dos buffers de fundo que o aplicativo cria. O DXGI chama a função BltDXGI do driver para mover dados de qualquer um dos buffers traseiros para a superfície compartilhada. Essa operação pode exigir alongamento, conversão de cores e resolve MSAA. No entanto, essa operação nunca requer sub-retângulos de origem e destino. Na verdade, esses subtângulos não podem ser expressos na chamada para BltDXGI. Essa transferência de bloco de bits (bitblt) sempre tem o sinalizador Present definido no membro Flags da estrutura DXGI_DDI_ARG_BLT para a qual o parâmetro pBltData aponta. Definir o sinalizador Present indica que o driver deve executar a operação atomicamente. O driver executa a operação bitblt atomicamente para minimizar a possibilidade de rasgar enquanto o DWM lê o recurso compartilhado para composição.
Modo de janela com DWM desativado
No modo de janela com o caso DWM-off, o DXGI chama a função PresentDXGI do driver com o sinalizador Blt definido no membro Flags da estrutura DXGI_DDI_ARG_PRESENT para a qual o parâmetro pPresentData aponta. Nesta chamada PresentDXGI , o DXGI pode especificar qualquer um dos buffers back criados pelo aplicativo nos membros hSurfaceToPresent e SrcSubResourceIndex do DXGI_DDI_ARG_PRESENT. Não há nenhuma superfície compartilhada adicional.
Modo de tela inteira
A caixa de tela inteira é mais complicada do que o modo em janelas com DWM ativado ou desativado.
Quando o DXGI faz a transição para o modo de tela inteira, ele tenta explorar uma operação de inversão para reduzir a largura de banda e obter sincronização de sincronização vertical. As seguintes condições podem impedir o uso de uma operação de inversão:
O aplicativo não realocou seus buffers de fundo de uma forma que correspondam à superfície primária.
O driver especificou que ele não verificará o buffer de fundo (por exemplo, porque o buffer traseiro é girado ou é MSAA).
O aplicativo especificou que não pode aceitar o descarte do runtime do Direct3D do conteúdo do buffer de fundo e solicitou apenas um buffer (total) na cadeia. (Nesse caso, o DXGI aloca uma superfície traseira e uma superfície primária; no entanto, o DXGI usa a função PresentDXGI do driver com o sinalizador Blt definido.)
Quando uma das condições anteriores ocorreu, impedindo assim uma operação de inversão e uma chamada para a função PresentDXGI do driver com o conjunto de sinalizadores Blt também não é apropriada (porque o buffer traseiro não corresponde exatamente ao buffer frontal), o DXGI aloca a superfície do proxy. Essa superfície de proxy corresponde ao buffer frontal. Portanto, uma inversão entre a superfície do proxy e o buffer frontal torna-se possível. Se a superfície de proxy existir, o DXGI usará a função BltDXGI do driver com o sinalizador Present limpo (0) para copiar os buffers de fundo do aplicativo para a superfície de proxy. Nesta chamada BltDXGI , o DXGI pode solicitar a conversão, alongamento e resolução. Em seguida, o DXGI chama a função PresentDXGI do driver com o sinalizador Flip definido no membro Flags da estrutura DXGI_DDI_ARG_PRESENT para mover os bits da superfície do proxy para verificação.
Para notificar o driver de exibição do modo de usuário de que o driver pode recusar a verificação, o driver receberá chamadas de criação de recursos para classes opcionais e não opcionais de superfícies de verificação. As superfícies de verificação opcionais são designadas pelo sinalizador DXGI_DDI_PRIMARY_OPTIONAL. As superfícies de verificação não opcionais não têm o sinalizador DXGI_DDI_PRIMARY_OPTIONAL definido. Para obter mais informações sobre esses tipos de chamadas de criação de recursos, consulte Passando informações de DXGI no momento da criação de recursos.
O DXGI define o sinalizador DXGI_DDI_PRIMARY_OPTIONAL para criar todas as superfícies de buffer de fundo (ou seja, superfícies opcionais) e não define o sinalizador para nenhuma superfície de proxy ou buffer frontal (ou seja, superfície não opcional).
Se DXGI_DDI_PRIMARY_OPTIONAL estiver definido para um buffer de fundo, o driver poderá definir o sinalizador DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT. Para obter mais informações sobre como definir esse sinalizador, consulte Passando informações de DXGI no momento da criação do recurso. Se o driver definir DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT para um buffer opcional, ele não terá nenhum efeito além de fazer com que o DXGI chame a função PresentDXGI do driver com o sinalizador Blt definido em vez de com o sinalizador Flip definido.
Se DXGI_DDI_PRIMARY_OPTIONAL não estiver definido para um buffer frontal ou a superfície de proxy, o driver ainda poderá recusar a verificação falhando na chamada de criação de recursos com o código de erro DXGI_DDI_ERR_UNSUPPORTED e definindo DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT.
Nota Falha na chamada de criação sem definir DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT é reservado para casos de falha reais, como falta de memória.
O DXGI explora essa metodologia de recusa quando tenta criar uma cadeia de apresentação em tela inteira para um MSAA ou buffer de fundo girado. Se o driver não verificar nenhum ou ambos os tipos, o driver recusará. O DXGI tentará criar uma superfície não girada, uma superfície não MSAA ou ambas até que o driver aceite a criação do recurso. Portanto, o DXGI retornará progressivamente até que a superfície não opcional corresponda exatamente ao formato do buffer frontal, à contagem de exemplos, à rotação e ao tamanho.
Se o driver recusar qualquer superfície não opcional, o DXGI ainda deverá ter uma maneira de mover bits do buffer traseiro para a superfície primária. Consequentemente, se o driver recusar a verificação para MSAA e rotação, o driver aceitará resolver, girar ou ambos quando o DXGI chamar a função BltDXGI do driver. Quando o driver recusar, o DXGI criará uma superfície de proxy e chamará BltDXGI para mover dados dos buffers traseiros para essa superfície de proxy. O driver não deve ter nenhum motivo para recusar essa superfície de proxy porque o proxy corresponde exatamente ao buffer frontal.
As seguintes situações incomuns ocorrem quando o aplicativo não recria suas superfícies após uma transição para dentro ou fora do modo de tela inteira:
Se o aplicativo não recriar suas superfícies quando entrar no modo de tela inteira, o DXGI determinará que os buffers traseiros não correspondem ao buffer frontal, mesmo que realmente correspondam ao formato, ao tamanho, à rotação e à contagem de exemplos. O motivo para essa determinação é que o sistema operacional requer que buffers de fundo sejam marcados para verificação em um monitor específico quando esses buffers são criados. Os buffers traseiros em janelas ainda não podem ser atribuídos definitivamente a um monitor específico porque o monitor é escolhido dinamicamente quando a tela inteira é inserida. Portanto, o DXGI não deve enviar esses buffers de volta para o driver para verificação (por meio de uma operação de inversão). Aplicativos desse tipo normalmente forçam o DXGI a criar a superfície de proxy.
Se o aplicativo não recriar seus buffers de fundo quando retornar ao modo de janela, o DXGI poderá chamar o BltDXGI do driver ou PresentDXGI (com blt definido) para executar um bitblt em uma superfície que foi criada anteriormente para uma operação de inversão. Essa situação não deve ser um problema, mas é mencionada aqui para fins de integridade. Observe que o DXGI sempre destrói a superfície de proxy quando o aplicativo faz a transição para o modo em janelas.
Além disso, observe que os aplicativos podem redimensionar seus buffers de fundo dinamicamente enquanto os aplicativos estão no modo de tela inteira. Essa ação faz com que a lógica descrita nas situações anteriores ocorra novamente. Portanto, a superfície de proxy pode ser criada e destruída e a recusa pode ou não ser necessária ao longo do tempo, mesmo que o aplicativo permaneça no modo de tela inteira. O aplicativo também pode transferir sua saída para outro monitor dinamicamente sem sair do modo de tela inteira. Portanto, o aplicativo incorre em uma alternância de volta para o modo bitblt porque os buffers de fundo do aplicativo foram marcados para um monitor diferente.
Por fim, você deve estar ciente da situação que ocorre em relação aos buffers de fundo MSAA se o driver não recusar a verificação do MSAA. Nessa situação, o driver opta pela verificação da MSAA. Portanto, o DXGI troca o buffer de fundo MSAA e o buffer frontal MSAA por meio de operações de inversão e executa uma operação de resolve pelo que é equivalente ao DAC (conversor digital para analógico). Nessa situação, o aplicativo pode redimensionar seus buffers traseiros dinamicamente enquanto estiver no modo de tela inteira, o que força o DXGI a alternar para chamar a função BltDXGI do driver. Como as características do MSAA do buffer traseiro e do buffer frontal ainda correspondem, o DXGI especificará que o driver execute um bitblt estendido não resolvido, possivelmente convertido por cores. Em seguida, o driver deve replicar, sem resolve, várias amostras para o buffer frontal, o que é necessário se um driver optar por verificar o MSAA.