Filosofia de design de filas de comando e listas de comando

As metas de habilitar a reutilização do trabalho de renderização e do dimensionamento multithread exigiram alterações fundamentais na forma como os aplicativos Direct3D enviam o trabalho de renderização para a GPU. No Direct3D 12, o processo de envio do trabalho de renderização difere das versões anteriores de três maneiras importantes:

  1. Eliminação do contexto imediato. Isso habilita o multi-threading.
  2. Os aplicativos agora possuem como as chamadas de renderização são agrupadas em itens de trabalho de GPU (unidade de processamento gráfico). Isso permite o reutilizar.
  3. Os aplicativos agora controlam explicitamente quando o trabalho é enviado para a GPU. Isso habilita os itens 1 e 2.

Remoção do contexto imediato

A maior alteração do Microsoft Direct3D 11 para o Microsoft Direct3D 12 é que não há mais um contexto único e imediato associado a um dispositivo. Em vez disso, para renderizar, os aplicativos criam listas de comandos nas quais as APIs de renderização tradicionais podem ser chamadas. Uma lista de comandos é semelhante ao método render de um aplicativo Direct3D 11 que usou o contexto imediato em que ele contém chamadas que desenham primitivos ou alteram o estado de renderização. Assim como os contextos imediatos, cada lista de comandos não tem thread livre; no entanto, várias listas de comandos podem ser registradas simultaneamente, o que aproveita processadores modernos de vários núcleos.

Normalmente, as listas de comandos são executadas uma vez. No entanto, uma lista de comandos poderá ser executada várias vezes se o aplicativo garantir que as execuções anteriores sejam concluídas antes de enviar novas execuções. Para obter mais informações sobre a sincronização de lista de comandos, consulte Executando e sincronizando listas de comandos.

Agrupamento de itens de trabalho de GPU

Além das listas de comandos, o Direct3D 12 aproveita a funcionalidade presente em todo o hardware atualmente adicionando um segundo nível de listas de comandos, que são chamadas de pacotes. Para ajudar a distinguir esses dois tipos, as listas de comandos de primeiro nível podem ser chamadas de listas de comandos diretos. A finalidade dos pacotes é permitir que os aplicativos agrupem um pequeno número de comandos de API para execução repetida posterior de dentro de listas de comandos diretos. No momento da criação de um pacote, o driver executará o máximo de pré-processamento possível para tornar a execução posterior eficiente. Os pacotes podem ser executados de dentro de várias listas de comandos e várias vezes dentro da mesma lista de comandos.

O reutilização de pacotes é um grande driver de eficiência aprimorada com threads de CPU únicos. Como os pacotes são pré-processados e podem ser enviados várias vezes, há certas restrições sobre quais operações podem ser executadas em um pacote. Para obter mais informações, consulte Criando e gravando listas de comandos e pacotes.

Envio de trabalho de GPU

Para executar o trabalho na GPU, um aplicativo deve enviar explicitamente uma lista de comandos para uma fila de comandos associada ao dispositivo Direct3D. Uma lista de comandos diretos pode ser enviada para execução várias vezes, mas o aplicativo é responsável por garantir que a lista de comandos diretos tenha terminado de ser executada na GPU antes de enviá-la novamente. Os pacotes não têm restrições de uso simultâneo e podem ser executados várias vezes em várias listas de comandos, mas os pacotes não podem ser enviados diretamente a uma fila de comandos para execução.

Qualquer thread pode enviar uma lista de comandos para qualquer fila de comandos a qualquer momento e o runtime serializará automaticamente o envio da lista de comandos na fila de comandos, preservando a ordem de envio.