Partilhar via


Visão geral do DXGI

O Microsoft DirectX Graphics Infrastructure (DXGI) reconhece que algumas partes dos gráficos evoluem mais lentamente do que outras. O objetivo principal do DXGI é gerenciar tarefas de baixo nível que podem ser independentes do tempo de execução de gráficos DirectX. DXGI fornece uma estrutura comum para futuros componentes gráficos; o primeiro componente que tira proveito do DXGI é o Microsoft Direct3D 10.

Em versões anteriores do Direct3D, tarefas de baixo nível, como enumeração de dispositivos de hardware, apresentação de quadros renderizados para uma saída, controle de gama e gerenciamento de uma transição de tela inteira eram incluídas no tempo de execução do Direct3D. Essas tarefas agora são implementadas no DXGI.

O objetivo do DXGI é se comunicar com o driver do modo kernel e o hardware do sistema, como mostrado no diagrama a seguir.

diagrama da comunicação entre aplicações, DXGI, drivers e hardware

Um aplicativo pode acessar o DXGI diretamente ou chamar as APIs do Direct3D em D3D11_1.h, D3D11.h, D3D10_1.h ou D3D10.h, que lida com as comunicações com o DXGI para você. Você pode querer trabalhar com DXGI diretamente se seu aplicativo precisa enumerar dispositivos ou controlar como os dados são apresentados a uma saída.

Este tópico contém as seguintes seções.

Para ver quais formatos são suportados pelo hardware Direct3D 11:

Enumerando adaptadores

Um adaptador é uma abstração do hardware e da capacidade de software do seu computador. Geralmente há muitos adaptadores na sua máquina. Alguns dispositivos são implementados em hardware (como sua placa de vídeo) e alguns são implementados em software (como o rasterizador de referência Direct3D). Os adaptadores implementam a funcionalidade usada por um aplicativo gráfico. O diagrama a seguir mostra um sistema com um único computador, dois adaptadores (placas de vídeo) e três monitores de saída.

diagrama de um computador com duas placas de vídeo e três monitores

Ao enumerar essas peças de hardware, o DXGI cria uma interface deIDXGIOutput1para cada saída (ou monitor) e uma interface deIDXGIAdapter2para cada placa de vídeo (mesmo que seja uma placa de vídeo embutida em uma placa-mãe). A enumeração é feita usando uma IDXGIFactory chamada de interface, IDXGIFactory::EnumAdapters, para retornar um conjunto de IDXGIAdapter interfaces que representam o hardware de vídeo.

DXGI 1.1 adicionou o IDXGIFactory1 interface. IDXGIFactory1::EnumAdapters1 retorna um conjunto de IDXGIAdapter1 interfaces que representam o hardware de vídeo.

Se você quiser selecionar recursos específicos de hardware de vídeo ao usar APIs do Direct3D, recomendamos que você chame iterativamente a D3D11CreateDevice ou função de D3D11CreateDeviceAndSwapChain com cada identificador de adaptador e possíveis de nível de recurso dede hardware . Esta função terá êxito se o nível de recurso for suportado pelo adaptador especificado.

Novas informações sobre como enumerar adaptadores para o Windows 8

A partir do Windows 8, um adaptador chamado "Microsoft Basic Render Driver" está sempre presente. Este adaptador tem um VendorId de 0x1414 e um DeviceID de 0x8c. Este adaptador também tem o valor DXGI_ADAPTER_FLAG_SOFTWARE definido no Flags membro da sua estrutura DXGI_ADAPTER_DESC2. Este adaptador é um dispositivo somente de renderização que não tem saídas de vídeo. DXGI nunca retorna DXGI_ERROR_DEVICE_REMOVED para este adaptador.

Se o driver de vídeo de um computador não estiver funcionando ou estiver desativado, o adaptador principal (NULL) do computador também pode ser chamado de "Microsoft Basic Render Driver". Mas este adaptador tem saídas e não tem o valor DXGI_ADAPTER_FLAG_SOFTWARE definido. O sistema operativo e as aplicações utilizam este adaptador por predefinição. Se um driver de vídeo estiver instalado ou habilitado, os aplicativos poderão receber DXGI_ERROR_DEVICE_REMOVED para esse adaptador e, em seguida, deverão enumerar novamente os adaptadores.

Quando o adaptador de vídeo principal de um computador é o "Microsoft Basic Display Adapter" (adaptadorWARP), esse computador também possui um segundo adaptador. Este segundo adaptador é o dispositivo somente de renderização que não tem saídas de exibição e para o qual o DXGI nunca retorna DXGI_ERROR_DEVICE_REMOVED.

Se você quiser usar o WARP para renderização, computação ou outras tarefas de longa execução, recomendamos usar o dispositivo somente renderização. Você pode obter um ponteiro para o dispositivo somente para renderização chamando o método IDXGIFactory1::EnumAdapters1. Você também cria o dispositivo exclusivo para renderização quando especifica D3D_DRIVER_TYPE_WARP no parâmetro DriverType de D3D11CreateDevice, porque o dispositivo WARP também usa o adaptador WARP exclusivo para renderização.

Apresentação

O trabalho do seu aplicativo é renderizar quadros e pedir ao DXGI para apresentar esses quadros à saída. Se o aplicativo tiver dois buffers disponíveis, ele poderá renderizar um buffer enquanto apresenta outro. O aplicativo pode exigir mais de dois buffers, dependendo do tempo necessário para renderizar um quadro ou da taxa de quadros desejada para apresentação. O conjunto de buffers criado é chamado de cadeia de permuta, conforme mostrado aqui.

ilustração de uma cadeia de permuta

Uma cadeia de permuta tem um buffer frontal e um ou mais buffers traseiros. Cada aplicativo cria sua própria cadeia de permuta. Para maximizar a velocidade da apresentação dos dados para uma saída, uma cadeia de permuta é quase sempre criada na memória de um subsistema de exibição, que é mostrado na ilustração a seguir.

ilustração de um subsistema de exibição

O subsistema de exibição (que geralmente é uma placa de vídeo, mas pode ser implementado em uma placa-mãe) contém uma GPU, um conversor digital para analógico (DAC) e memória. A cadeia de permuta é alocada dentro desta memória para tornar a exibição muito rápida. O subsistema de exibição apresenta os dados no buffer frontal para a saída.

Uma cadeia de troca é configurada para desenhar em modo de ecrã completo ou janela, eliminando a necessidade de saber se a saída está em janela ou em ecrã completo. Uma cadeia de troca de modo de ecrã inteiro pode otimizar o desempenho ao alterar a resolução do ecrã.

Criar uma cadeia de permuta

Diferenças entre o Direct3D 9 e o Direct3D 10: O Direct3D 10 é o primeiro componente gráfico a usar o DXGI. O DXGI tem alguns comportamentos diferentes da cadeia de permuta.
  • No DXGI, uma cadeia de permuta é vinculada a uma janela quando a cadeia de permuta é criada. Esta alteração melhora o desempenho e poupa memória. As versões anteriores do Direct3D permitiam que a cadeia de permuta alterasse a janela à qual a cadeia de permuta está vinculada.
  • No DXGI, uma cadeia de permuta é vinculada a um dispositivo de renderização na criação. O objeto de dispositivo que as funções de criação de dispositivo do Direct3D retornam implementa a interface IUnknown. Você pode chamar QueryInterface para consultar a interface correspondente IDXGIDevice2 do dispositivo. Uma alteração no dispositivo de renderização requer que a cadeia de permuta seja recriada.
  • No DXGI, os efeitos de swap disponíveis são DXGI_SWAP_EFFECT_DISCARD e DXGI_SWAP_EFFECT_SEQUENTIAL. A partir do Windows 8, o método de permuta DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL também está disponível. A tabela a seguir mostra um mapeamento do Direct3D 9 para os efeitos de troca do DXGI definidos.

    Efeito de permuta D3D9 Efeito Swap DXGI
    D3DSWAPEFFECT_DISCARD DXGI_SWAP_EFFECT_DISCARD
    D3DSWAPEFFECT_COPY DXGI_SWAP_EFFECT_SEQUENTIAL com 1 buffer
    D3DSWAPEFFECT_FLIP DXGI_SWAP_EFFECT_SEQUENTIAL com 2 ou mais buffers
    D3DSWAPEFFECT_FLIPEX DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL com 2 ou mais buffers

Os buffers de uma cadeia de permuta são criados em um determinado tamanho e em um formato específico. O aplicativo especifica esses valores (ou você pode herdar o tamanho da janela de destino) na inicialização e, opcionalmente, pode modificá-los à medida que o tamanho da janela muda em resposta à entrada do usuário ou eventos do programa.

Depois de criar a cadeia de permuta, você normalmente desejará renderizar imagens nela. Aqui está um fragmento de código que configura um contexto Direct3D para renderizar num swap chain. Esse código extrai um buffer da cadeia de permuta, cria um render-target-view desse buffer e o define no dispositivo:

ID3D11Resource * pBB;
ThrowFailure( pSwapChain->GetBuffer(0, __uuidof(pBB),    
  reinterpret_cast<void**>(&pBB)), "Couldn't get back buffer");
ID3D11RenderTargetView * pView;
ThrowFailure( pD3D11Device->CreateRenderTargetView(pBB, NULL, &pView), 
  "Couldn't create view" );
pD3D11DeviceContext->OMSetRenderTargets(1, &pView, 0);
        

Depois de o seu aplicativo renderizar um fotograma em um buffer de corrente de troca, chame IDXGISwapChain1::Present1. O aplicativo pode então renderizar a próxima imagem.

Cuidados e alimentação da cadeia de permuta

Depois de renderizar a sua imagem, chame IDXGISwapChain1::Present1 e prossiga para renderizar a próxima imagem. Essa é a extensão da sua responsabilidade.

Se tiver anteriormente chamado IDXGIFactory::MakeWindowAssociation, o utilizador pode pressionar a combinação de teclas Alt-Enter e o DXGI fará a transição do seu aplicativo entre o modo de janela e o modo de ecrã inteiro. IDXGIFactory::MakeWindowAssociation é recomendado, porque um mecanismo de controle padrão para o usuário é altamente desejado.

Embora você não precise escrever mais código do que o descrito, algumas etapas simples podem tornar seu aplicativo mais responsivo. A consideração mais importante é o redimensionamento dos buffers da cadeia de permuta em resposta ao redimensionamento da janela de saída. Naturalmente, a melhor rota do aplicativo é responder a WM_SIZE e chamar IDXGISwapChain::ResizeBuffers, passando o tamanho contido nos parâmetros da mensagem. Esse comportamento obviamente faz com que seu aplicativo responda bem ao usuário quando ele arrasta as bordas da janela, mas também é exatamente o que permite uma transição suave em tela cheia. Sua janela receberá uma mensagem WM_SIZE sempre que essa transição acontecer, e chamar IDXGISwapChain::ResizeBuffers é a chance da cadeia de permuta realocar o armazenamento dos buffers para uma apresentação ideal. É por isso que o aplicativo é obrigado a liberar quaisquer referências que tenha nos buffers existentes antes de chamar IDXGISwapChain::ResizeBuffers.

A falha ao chamar IDXGISwapChain::ResizeBuffers em resposta à mudança para o modo de tela cheia (mais naturalmente, em resposta a WM_SIZE), pode impedir a otimização da inversão, em que o DXGI pode simplesmente trocar qual buffer está sendo exibido, em vez de copiar os dados de uma tela cheia.

IDXGISwapChain1::Present1 irá informá-lo se a sua janela de saída está totalmente ocluída via DXGI_STATUS_OCCLUDED. Quando isso ocorre, recomendamos que o seu aplicativo entre em modo de espera (chamando IDXGISwapChain1::Present1 com DXGI_PRESENT_TEST), uma vez que os recursos usados para renderizar o quadro são desperdiçados. O uso do DXGI_PRESENT_TEST impedirá que quaisquer dados sejam apresentados, enquanto ainda se realiza o teste de oclusão. Assim que IDXGISwapChain1::Present1 retornar S_OK, deve sair do modo de espera; Não use o código de retorno para entrar no modo de espera, pois isso pode deixar o swap chain incapaz de abandonar o modo de ecrã completo.

O tempo de execução do Direct3D 11.1, que está disponível a partir do Windows 8, fornece uma cadeia de permuta de modelo invertido (ou seja, uma cadeia de permuta que tem o valor DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL definido no SwapEffect membro de DXGI_SWAP_CHAIN_DESC ou DXGI_SWAP_CHAIN_DESC1). Quando você apresenta quadros para uma saída com uma cadeia de permuta de modelo invertido, o DXGI desvincula o buffer traseiro de todos os locais de estado do pipeline, como um destino de renderização de fusão de saída, que grava no buffer back 0. Portanto, recomendamos que você chame ID3D11DeviceContext::OMSetRenderTargets imediatamente antes de renderizar para o buffer traseiro. Por exemplo, não chame OMSetRenderTargets e depois execute trabalho de sombreador de computação que não resulte em renderização para o recurso. Para obter mais informações sobre as cadeias de permuta do modelo flip e os seus benefícios, consulte DXGI Flip Model.

Observação

No Direct3D 10 e no Direct3D 11, não é necessário chamar IDXGISwapChain::GetBuffer para recuperar o buffer traseiro 0 depois de chamar IDXGISwapChain1::Present1 porque, por conveniência, as identidades dos buffers traseiros mudam. Isso não acontece no Direct3D 12 e, em vez disso, seu aplicativo deve rastrear manualmente os índices de buffer.

Manipulação do redimensionamento de janelas

Você pode usar o método IDXGISwapChain::ResizeBuffers para lidar com o redimensionamento de janelas. Antes de chamar ResizeBuffers, você deve liberar todas as referências pendentes aos buffers da cadeia de permuta. O objeto que normalmente contém uma referência ao buffer de uma cadeia de permuta é um render-target-view.

O código de exemplo a seguir mostra como chamar ResizeBuffers de dentro do manipulador WindowProc para mensagens WM_SIZE:

    case WM_SIZE:
        if (g_pSwapChain)
        {
            g_pd3dDeviceContext->OMSetRenderTargets(0, 0, 0);

            // Release all outstanding references to the swap chain's buffers.
            g_pRenderTargetView->Release();

            HRESULT hr;
            // Preserve the existing buffer count and format.
            // Automatically choose the width and height to match the client rect for HWNDs.
            hr = g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
                                            
            // Perform error handling here!

            // Get buffer and create a render-target-view.
            ID3D11Texture2D* pBuffer;
            hr = g_pSwapChain->GetBuffer(0, __uuidof( ID3D11Texture2D),
                                         (void**) &pBuffer );
            // Perform error handling here!

            hr = g_pd3dDevice->CreateRenderTargetView(pBuffer, NULL,
                                                     &g_pRenderTargetView);
            // Perform error handling here!
            pBuffer->Release();

            g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL );

            // Set up the viewport.
            D3D11_VIEWPORT vp;
            vp.Width = width;
            vp.Height = height;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            g_pd3dDeviceContext->RSSetViewports( 1, &vp );
        }
        return 1;

Escolher a saída DXGI e o tamanho

Por padrão, o DXGI escolhe a saída que contém a maior parte da área do cliente da janela. Esta é a única opção disponível para o DXGI quando ele entra em modo de ecrã completo em resposta às teclas Alt-Enter. Se o aplicativo optar por ir automaticamente para o modo de tela cheia, ele pode chamar IDXGISwapChain::SetFullscreenState e passar um explícito IDXGIOutput1 (ou NULL, se preferir deixar que o DXGI decida).

Para redimensionar a saída em tela cheia ou em janela, recomendamos chamar IDXGISwapChain::ResizeTarget, já que esse método também redimensiona a janela de destino. Como a janela de destino é redimensionada, o sistema operacional envia WM_SIZEe seu código naturalmente chamará IDXGISwapChain::ResizeBuffers em resposta. Portanto, é um desperdício de esforço redimensionar seus buffers e, posteriormente, redimensionar o alvo.

Depuração no modo de ecrã inteiro

Uma cadeia de troca DXGI abandona o modo de ecrã completo apenas quando é absolutamente necessário. Isso significa que você pode depurar um aplicativo em tela cheia usando vários monitores, desde que a janela de depuração não se sobreponha à janela de destino da cadeia de permuta. Como alternativa, você pode impedir completamente a troca de modo não definindo a flag DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH.

Se a comutação de modo for permitida, uma cadeia de permuta abandonará o modo de tela cheia sempre que sua janela de saída for ocluída por outra janela. A verificação de oclusão é realizada durante IDXGISwapChain1::Present1, ou por um thread separado cuja finalidade é verificar se a aplicação deixou de responder (e não chama mais IDXGISwapChain1::Present1). Para desativar a capacidade do thread separado de provocar uma comutação, defina a seguinte chave do registo para qualquer valor diferente de zero.

HKCU\Software\Microsoft\DXGI\DisableFullscreenWatchdog

Destruindo uma cadeia de permuta

Você não pode liberar uma cadeia de permuta no modo de tela cheia porque isso pode criar contenção de thread (o que fará com que o DXGI gere uma exceção não continuável). Antes de liberar uma cadeia de permuta, primeiro alterne para o modo de janela (usando IDXGISwapChain::SetFullscreenState( FALSE, NULL )) e, em seguida, chame IUnknown::Release.

Usando um monitor girado

Um aplicativo não precisa se preocupar com a orientação do monitor, o DXGI girará um buffer de cadeia de permuta durante a apresentação, se necessário. É claro que essa rotação adicional pode afetar o desempenho. Para obter o melhor desempenho, cuide da rotação em seu aplicativo fazendo o seguinte:

  • Utilize o DXGI_SWAP_CHAIN_FLAG_NONPREROTATED. Isso notifica o DXGI de que o aplicativo produzirá uma imagem girada (por exemplo, alterando sua matriz de projeção). Uma coisa a notar, este sinalizador só é válido enquanto estiver no modo de tela cheia.
  • Alocar cada buffer da cadeia de troca na sua dimensão rotacionada. Use IDXGIOutput::GetDesc para obter esses valores, se necessário.

Ao realizar a rotação em seu aplicativo, o DXGI simplesmente fará uma cópia em vez de uma cópia e uma rotação.

O tempo de execução do Direct3D 11.1, que está disponível a partir do Windows 8, fornece uma cadeia de permuta de modelo invertido (ou seja, uma cadeia de permuta que tem o valor DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL definido no SwapEffect membro do DXGI_SWAP_CHAIN_DESC1). Para maximizar as otimizações de apresentação disponíveis com uma cadeia de permuta de modelo invertido, recomendamos que você faça com que seus aplicativos orientem o conteúdo para corresponder à saída específica na qual o conteúdo reside quando esse conteúdo ocupa totalmente a saída. Para obter mais informações sobre as cadeias de permuta do modelo flip e os seus benefícios, consulte DXGI Flip Model.

Alternar modos

A cadeia de permuta DXGI pode alterar o modo de exibição de uma saída ao fazer uma transição para ecrã completo. Para habilitar a alteração automática do modo de exibição, você deve especificar DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH na descrição da cadeia de permuta. Se o modo de exibição mudar automaticamente, o DXGI escolherá o modo mais modesto (tamanho e resolução não mudarão, mas a profundidade de cor pode). O redimensionamento de buffers de cadeia de permuta não causará uma troca de modo. A cadeia de permuta faz uma promessa implícita de que, se você escolher um buffer traseiro que corresponda exatamente a um modo de exibição suportado pela saída de destino, ele alternará para esse modo de exibição ao entrar no modo de tela cheia nessa saída. Consequentemente, você escolhe um modo de exibição escolhendo o tamanho e o formato do buffer traseiro.

Dica de desempenho em tela cheia

Quando chamas IDXGISwapChain1::Present1 numa aplicação de ecrã inteiro, a cadeia de troca inverte, em oposição a blits, o conteúdo do buffer traseiro para o buffer frontal. Isso requer que a cadeia de permuta tenha sido criada usando um modo de exibição enumerado (especificado em DXGI_SWAP_CHAIN_DESC1). Se não conseguir enumerar os modos de exibição ou especificar incorretamente o modo de exibição na descrição, a cadeia de troca poderá executar uma transferência de blocos de bits (bitblt). O bitblt causa uma cópia de alongamento extra, bem como algum aumento do uso de memória de vídeo, e é difícil de detetar. Para evitar esse problema, enumere os modos de exibição e inicialize a descrição da cadeia de permuta corretamente antes de criar a cadeia de permuta. Isso garantirá o máximo desempenho ao alternar para o modo de tela cheia e evitará a sobrecarga adicional de memória.

Considerações sobre multithreading

Quando você usa DXGI em um aplicativo com vários threads, você precisa ter cuidado para evitar a criação de um deadlock, onde dois threads diferentes estão esperando um no outro para concluir. Há duas situações em que isso pode ocorrer.

  • O thread de renderização não é o thread da bomba de mensagem.
  • O thread que executa uma API DXGI não é o mesmo thread que criou a janela.

Tenha cuidado para nunca ter o thread da bomba de mensagens aguardando no thread de renderização quando você usa cadeias de permuta de tela cheia. Por exemplo, chamar IDXGISwapChain1::Present1 (do thread de renderização) pode fazer com que o thread de renderização espere no thread de processamento de mensagens. Quando ocorre uma alteração de modo, esse cenário é possível se Present1 chamar ::SetWindowPos() ou ::SetWindowStyle() e qualquer um desses métodos chamar ::SendMessage(). Nesse cenário, se o thread da bomba de mensagem estiver protegido por uma seção crítica ou se o thread de renderização estiver bloqueado, então os dois threads ficarão num impasse.

Para obter mais informações sobre como usar DXGI com vários threads, consulte Multithreading e DXGI.

Respostas DXGI de DLLMain

Como uma funçãoDllMainnão pode garantir a ordem em que carrega e descarrega DLLs, recomendamos que a função DllMain do seu aplicativo não chame funções ou métodos Direct3D ou DXGI, incluindo funções ou métodos que criam ou liberam objetos. Se a função de DllMain do seu aplicativo chamar um componente específico, esse componente poderá chamar outra DLL que não está presente no sistema operacional, o que faz com que o sistema operacional falhe. Direct3D e DXGI podem carregar um conjunto de DLLs, normalmente um conjunto de drivers, que difere de computador para computador. Portanto, mesmo que seu aplicativo não falhe em seus computadores de desenvolvimento e teste quando sua função DllMain chama funções ou métodos Direct3D ou DXGI, ele pode falhar quando é executado em outro computador.

Para evitar que você crie um aplicativo que possa causar falhas no sistema operacional, o DXGI fornece as seguintes respostas nas situações especificadas:

  • Se a função DllMain do seu aplicativo liberar sua última referência a uma fábrica DXGI, o DXGI gerará uma exceção.
  • Se a função DllMain do seu aplicativo criar uma fábrica DXGI, o DXGI retornará um código de erro.

Alterações no DXGI 1.1

Adicionamos a seguinte funcionalidade no DXGI 1.1.

Alterações no DXGI 1.2

Adicionamos a seguinte funcionalidade no DXGI 1.2.

  • Cadeia de permuta estéreo
  • Cadeia de permuta Flip-model
  • Apresentação otimizada (rolagem, retângulos sujos e rotação)
  • Recursos compartilhados e sincronização aprimorados
  • Duplicação de área de trabalho
  • Uso otimizado da memória de vídeo
  • Suporte para formatos de 16 bits por pixel (bpp) (DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM)
  • APIs para depuração

Para obter mais informações sobre o DXGI 1.2, consulte Melhorias do DXGI 1.2.

Compatibilidade de aplicações

DXGI pode aplicar modificações de comportamento do aplicativo para melhorar a compatibilidade do aplicativo.

  • As configurações de compatibilidade podem ser armazenadas no registro do usuário em HKCU\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers.
  • As configurações de compatibilidade podem ou não ser aplicadas dependendo da configuração do sistema ou de outros fatores.
  • Um exemplo de valor de configuração de compatibilidade de aplicativos é DXAllowModeChangeOnLaunch720.

Guia de programação para DXGI