Pular para o conteúdo principal

Compilação de objetos de estado de pipeline

O D3D12 fornece a interface PSO (Pipeline State Object, objeto de estado de pipeline) para configurar a GPU com shaders e estado de renderização. O fluxo de trabalho multiplataforma padrão para criar PSOs é pré-compilar shaders usando o DXC em um processo no momento do build e, em seguida, preencher um descritor de estado de pipeline gráfico ou de computação (por exemplo, D3D12_GRAPHICS_PIPELINE_STATE_DESC) com bytecode de shader e estado em tempo de execução. A validação do driver garante a congruência de entradas/saídas e do estado para cada estágio sucessivo do pipeline. No PC, a compilação de PSOs em tempo de execução é necessária, pois a GPU do usuário final geralmente é desconhecida no momento do build. Portanto, o processo offline do DXC deve compilar para um formato de bytecode intermediário, a representação intermediária baseada em LLVM, DXIL (DirectX Intermediate Language). Criar o PSO em tempo de execução com uma das APIs disponíveis (abaixo) faz com que o driver da GPU finalize o código do shader, compilando o bytecode DXIL em instruções de GPU que podem então ser executadas na GPU. Em tempo de execução:
APIs pertinentes:

Objetos de estado de pipeline serializados

A plataforma XBOX consolida a configuração de hardware, tornando desnecessário distribuir uma representação intermediária do código de shader. Isso permite que o processo de compilação de PSOs seja movido para um evento no momento do build, eliminando a sobrecarga gasta na criação de PSOs durante a inicialização do título. Extensões da API do XBOX foram adicionadas para serializar PSOs em um formato de blob binário que pode ser salvo diretamente em disco. Em tempo de execução, esses blobs podem ser carregados do disco e desserializados de volta em um estado de pipeline funcional. Os PSOs ainda podem ser criados em tempo de execução usando a funcionalidade padrão do D3D12, mas a serialização oferece um caminho para otimizar a velocidade de inicialização. Como os PSOs serializados são distribuídos em builds de pacote, um pilar de design é minimizar o consumo de memória. Os blobs gerados por SerializeGraphicsPipelineStateX devem ser desduplicados entre todos os PSOs pré-compilados para reduzir os requisitos de memória. Outros metadados irrelevantes para a execução são descartados na serialização, o que impede a capacidade de serializar novamente PSOs desserializados anteriormente, operação que falha com uma mensagem de validação. As APIs de serialização (abaixo) não estão disponíveis em builds de varejo. Observe que o processo usado para pré-compilar PSOs deve usar um ID3D12Device criado a partir de uma biblioteca direcionada à plataforma. A função D3D12CreateDevice pode ser encontrada na pasta toolkit da instalação do GDK, em d3d12_x.h para XBOX One ou d3d12_xs.h para XBOX Series X|S; vincule-a com a d3d12_x.lib ou d3d12_xs.lib correspondente. Essas bibliotecas esperam que as DLLs do GDK estejam acessíveis a partir do diretório de trabalho ou por meio da variável de sistema PATH. As DLLs ficam na pasta bin da versão correspondente do GDK, por exemplo, C:\Program Files (x86)\Microsoft GDK\200804\GXDK\bin para o QFE 4 de agosto de 2020. No momento do build:
Em tempo de execução:
Veja uma breve descrição do conteúdo de cada parte dos dados serializados: D3D12XBOX_SERIALIZE_GRAPHICS_PIPELINE_STATE::pPacket
  • Informações de execução do Command Processor
  • Estado da GPU para estados de blend/raster/profundidade-estêncil
  • Estado da GPU para configurações de RTV/DSV
  • Estado da GPU para processamento de vértices/índices, tessellation e stream out
  • Estado da GPU para cada estágio de HW
D3D12XBOX_SERIALIZE_GRAPHICS_PIPELINE_STATE::pMetadata
  • Hash CRC32 do PSO serializado
  • Número de versão da estrutura serializada
  • Dados de validação
  • Forma compacta dos argumentos de criação do PSO
  • Configurações de Input Layout e Stream Output
D3D12XBOX_SERIALIZE_SHADER::pGpuInstructions
  • Instruções de GPU pré-compiladas do shader de HW
D3D12XBOX_SERIALIZE_SHADER::pMetaData
  • Número de versão da estrutura serializada
  • Metadados do compilador de shader
  • Informações de shader do PIX
APIs pertinentes:

Objetos de estado de pipeline derivados

Outro recurso exposto por meio da API D3D12.X são os objetos de estado de pipeline ‘derivados’. Esse recurso cria variantes leves de PSOs existentes, que diferem apenas pelo estado de hardware (estado de profundidade-estêncil, estado do rasterizador, estado de blend, máscara de amostra e limites de shader). Derivar um PSO exige uma quantidade trivial de sobrecarga em tempo de execução em comparação com a compilação de PSOs. Isso permite que o desenvolvedor crie um único PSO, vinculado a um conjunto comum de shaders, e depois gere um número arbitrário de variantes, pagando o custo total em tempo de execução apenas pela criação do PSO inicial.
APIs pertinentes:

Objetos de estado de pipeline serializados e derivados

Usados em conjunto, PSOs serializados e derivados trazem benefícios adicionais para reduzir o tamanho do pacote. Os PSOs derivados permitem que os títulos minimizem o número de PSOs serializados a um subconjunto do conjunto total usado pelo título. Ao desduplicar os PSOs com base nas propriedades imutáveis às substituições de PSOs derivados, chega-se a um conjunto ‘base’, a partir do qual todos os outros PSOs do título podem ser derivados. O caso de uso canônico desses dois recursos seria:
  • Identificar os PSOs com combinações exclusivas de assinatura raiz, input layout, estágios de shader, saídas de stream e destinos de renderização.
  • Serializar esse conjunto desduplicado de PSOs base em um processo offline e distribuí-lo como parte do pacote.
  • Carregar os PSOs base do arquivo na inicialização e derivar todas as variantes de PSO necessárias para o título.

Restrições dos objetos de estado de pipeline derivados

Uma restrição notável dos PSOs derivados é que eles não podem modificar o código de shader compilado. É por isso que input layouts, formatos de destino de renderização e configurações de stream output não são opções em D3D12XBOX_DERIVED_GRAPHICS_STATE_DESC, pois exigiriam modificar as instruções de GPU do PSO compilado. O driver escolhe os tipos de dados de exportação de shader apropriados durante a compilação do PSO; os tipos de exportação de shader compatíveis são uint, sint, unorm, snorm ou float de 16 ou 32 bits. O driver seleciona o menor tipo cuja precisão seja maior ou igual à precisão do destino de renderização, desde que também se ajuste à configuração do hardware de blending. Para implementar sua escolha, o driver modifica o código de shader compilado com as instruções de exportação apropriadas, que convertem o tipo usado nas operações do shader para o tipo de exportação selecionado pelo driver. Depois dessa modificação, o driver não altera mais essas instruções de GPU finalizadas. A escolha final das instruções de exportação do shader é determinada por alguns fatores principais:
  • Tipos e quantidade de destinos nos quais o código HLSL grava (SV_TargetN)
  • Formatos e quantidade de destinos de renderização do PSO
  • Configuração de alpha-to-coverage
  • Configurações de estado de blend
Na renderização opaca (blending desabilitado), os tipos de saída podem ser qualquer um dos tipos de exportação de shader compatíveis: uint, sint, unorm, snorm ou float de 16 ou 32 bits. O valor é exportado do shader, convertido para o tipo do destino de renderização pelo Color Block (CB) e, por fim, gravado na memória. Com o blending habilitado, o driver é obrigado a limitar os tipos de exportação de shader a float de 16 ou 32 bits, pois esses são os únicos tipos compatíveis que o CB aceita como entradas para a operação de blending. O valor resultante do blending é então convertido para o tipo do destino de renderização e gravado na memória. Esses detalhes levam a restrições sutis sobre as substituições de estado de blend aplicáveis a PSOs derivados. O estado de blend substituído pode fazer com que os requisitos de exportação do PSO derivado sejam inconsistentes com a escolha de instrução de exportação determinada durante a compilação do PSO base, que foi incorporada às instruções de GPU. Se qualquer exportação calculada for incompatível entre os PSOs base e derivado, um erro de validação será gerado. Alguns exemplos que geram tipos de exportação incompatíveis e falhariam na validação: Exemplo 1 -
Exemplo 2 -
Exemplo 3 -

Os PSOs serializados são adequados para você?

Embora os PSOs serializados tenham sido criados para reduzir o tamanho do pacote e os custos em tempo de execução do conteúdo de shaders do jogo, certamente há um custo de desenvolvimento não trivial para criar e manter essa etapa de build. Os desenvolvedores frequentemente descobrem que distribuir shaders pré-compilados com DXIL removido oferece desempenho adequado para seus propósitos, algo que muitas vezes já é compatível com os pipelines de conteúdo existentes. O back-end do driver do XBOX foi otimizado com vários mecanismos de cache para reduzir os requisitos de memória em tempo de execução e o tempo de compilação de PSOs, facilitando esse caminho. Dependendo do conteúdo de shaders de um título, os desenvolvedores podem considerar um método preferível em termos de tamanho do pacote, memória em tempo de execução ou tempo de compilação de PSOs. Evitar a manutenção de um pipeline de conteúdo para serialização de PSOs é outro ponto a ser considerado. Testar ambas as opções com o conteúdo do seu título fornecerá uma visão mais clara da melhor escolha para ele.
Última modificação em 6 de outubro de 2026