3 pontos por GN⁺ 2024-02-11 | 1 comentários | Compartilhar no WhatsApp

Desenvolvendo um compilador de shaders DirectX melhor que o da Microsoft

  • Uma história sobre o estado complexo do compilador de shaders DirectX da Microsoft e os esforços para oferecer uma experiência melhor para desenvolvedores de jogos.
  • Para o engine Mach, está sendo desenvolvida com Zig uma API gráfica experimental chamada sysgpu, sucessora do WebGPU, com suporte planejado a backends Metal, Vulkan, Direct3D e OpenGL.
  • É necessário compilar programas de shader utilizáveis no Direct3D 12.

Breve história do DirectX

  • A API gráfica DirectX usa HLSL como linguagem de sombreamento.
  • No passado, antes do Direct3D 11, era usado um compilador chamado FXC, conhecido por ser notoriamente lento e por gerar código menos otimizado.

FXC não é mais usado, e o DXC surgiu com o Direct3D 12

  • Com o lançamento do Direct3D 12 e do Shader Model 6.0 (SM6), a Microsoft descontinuou o FXC e apresentou um novo compilador chamado DXC.
  • O DXC é um fork oficial da Microsoft de LLVM/Clang v3.7, com as alterações claramente marcadas por comentários.

O que os drivers DirectX consomem no café da manhã: DXBC ou DXIL

  • Embora HLSL seja a linguagem escolhida para programação em Direct3D, na prática as GPUs têm arquiteturas de computação e requisitos variados.
  • A Microsoft fornece uma API de frontend amigável para desenvolvedores, e os fabricantes independentes de hardware escrevem drivers que convertem isso para algo o mais próximo possível da ISA real do hardware.
  • Com a chegada do DirectX 12 e do Shader Model 6.0, passou-se a usar um novo formato chamado DXIL no lugar de DXBC.

DXIL

  • DXIL é o formato oficial atualmente usado pelos fabricantes de drivers para DirectX 12.
  • Desenvolvedores de jogos usam o compilador DXC para gerar bytecode DXIL, que é então enviado ao driver gráfico para ser convertido no código de máquina real executado no hardware da GPU.

Modificações no fork de LLVM da Microsoft

  • A Microsoft reconhece que não é ideal que fabricantes independentes de drivers usem um formato específico de bitcode LLVM, e admite que manter um fork de LLVM não é algo agradável.
  • A Microsoft começou a trabalhar para integrar diretamente ao LLVM/Clang o suporte à compilação de HLSL.

Desafios para desenvolvedores de jogos, WebGPU etc.

  • Camadas de abstração gráfica precisam fornecer uma linguagem de sombreamento unificada, e atualmente a maioria das implementações de WebGPU usa uma abordagem de compilar HLSL para DXBC ou DXIL.

Um desvio simples: SPIR-V

  • Vulkan/SPIR-V usa uma abordagem semelhante, e cabe aos fabricantes de GPU decidir se o SPIR-V foi otimizado ou não.

Usar ou não usar dxcompiler.dll?

  • Um runtime de WebGPU precisa decidir entre usar o novo compilador HLSL DXC ou usar o compilador FXC, oficialmente descontinuado, com pior desempenho e menor qualidade na geração de código.

Por que não é possível fazer link estático?

  • O fork de LLVM da Microsoft não oferece suporte a link estático, e isso se deve à complexidade do sistema de build.

Apresentando dxil.dll - blob proprietário de assinatura de código para shaders DirectX

  • dxil.dll não é compilado a partir do código-fonte e depende de blobs proprietários de código específicos por plataforma dentro do repositório “open source” da Microsoft.

Problemas de suporte de plataforma

  • A Microsoft distribui dxil.dll apenas para Windows (x86/arm) e Linux (x86), sem fornecer binários para macOS ou Linux aarch64.

Resumo

  • Não é possível compilar o DXC como biblioteca estática, e restaurar a funcionalidade do LLVM por causa do blob proprietário de assinatura de código seria um trabalho de grande escala.
  • Não é possível fazer compilação offline de shaders para jogos multiplataforma em pipelines de CI em macOS ou Linux arm.

Melhorias no sistema de build

  • Está sendo explorada uma forma de trocar o sistema de build em CMake por build.zig para compilar tudo como uma única biblioteca estática.

Resolvendo dependências de bibliotecas dinâmicas

  • Foi feito um fork da base de código do DXC e o código C++ foi modificado para remover dependências de bibliotecas dinâmicas.

Resolvendo a assinatura de código proprietária

  • Foi encontrada uma forma de compilar shaders HLSL sem depender de dxil.dll.

Resultado

  • São fornecidos a biblioteca dxcompiler e a CLI dxc em binários estáticos que não dependem do dxil.dll proprietário.
  • Binários para macOS, Linux e Windows são compilados no pipeline de CI.

Observações

  • Alguns binários ainda não foram compilados ou testados, e há planos de usar o próprio Zig como linguagem de sombreamento em vez de HLSL.

Nota pessoal

  • Depois de conseguir um emprego técnico em tempo integral sob o nome Stephen, ele passou a atuar online para construir o engine Mach.
  • Tem raízes em FOSS e acredita que é preciso possuir as próprias ferramentas e ser capacitado por elas.
  • O sonho é construir o Mach para todos e ganhar a vida vendendo jogos de alta qualidade.

Obrigado pela leitura

  • Confira machengine.org.
  • Considere apoiar o desenvolvimento para tornar mais trabalho possível.
  • Entre no servidor Discord do Mach.
  • Apoie no GitHub.
  • machengine.org

Opinião do GN⁺

  • O ponto mais importante deste texto é o esforço da comunidade de desenvolvedores para superar a complexidade e as limitações do DXC, o compilador de shaders DirectX da Microsoft.
  • Ao melhorar o sistema de build do DXC com Zig e apresentar uma nova abordagem para compilar shaders HLSL sem depender do dxil.dll proprietário, o desenvolvedor do engine Mach faz uma contribuição importante para o desenvolvimento de jogos multiplataforma.
  • O texto destaca a importância do software de código aberto e a necessidade de desenvolvedores poderem possuir e controlar suas próprias ferramentas, mostrando o valor da colaboração e da inovação dentro da comunidade técnica.

1 comentários

 
GN⁺ 2024-02-11
Comentários do Hacker News
  • Excelente visão geral da complexidade da compilação de shaders de APIs 3D

    • É apresentada uma visão geral do problema complexo da compilação cruzada de shaders entre APIs 3D.
    • Embora o foco esteja em D3D e na Microsoft, a situação não melhora muito em outras APIs 3D.
    • Por exemplo, não é possível fazer compilação cruzada de shaders Metal em um host Linux, sendo isso possível apenas no macOS e, mais recentemente, no Windows.
    • Se a equipe do Mach conseguir fazer dar certo a ideia de "usar Zig como compilador de shaders cross-3D-API" e fazê-la funcionar tão bem quanto "usar Zig como toolchain de compilação cruzada", isso será o maior acontecimento em computação gráfica desde 1995.
  • Problemas relacionados ao Godot

    • O suporte a Direct3D 12 atualmente depende da biblioteca proprietária dxil.dll do DirectX Shader Compiler distribuído junto com o Godot.
    • Distribuir software proprietário vai contra a missão do projeto Godot.
  • Discussão sobre a distribuição adicional de .dll

    • Não é necessário distribuir uma .dll adicional, assim como já acontece com middlewares proprietários usados por muitos videogames (Bink, SpeedTree, PhysX etc.).
    • A maioria dos launchers de jogos (Steam, GOG, Epic etc.) também exige suas próprias .DLL.
    • Muitos jogos usam D3D11On12, e muitos jogos já lançados incluem dxil.dll nos arquivos de instalação.
    • O trabalho de engenharia reversa e reimplementação da assinatura de código é impressionante, especialmente porque o resultado é idêntico bit a bit à saída de dxil.dll.
    • Ainda assim, quem preferir o caminho mais fácil pode simplesmente optar por distribuir a DLL.
  • Pergunta sobre a assinatura do DXIL.dll

    • A assinatura feita por DXIL.dll é apenas um MD5 modificado?
  • Mudanças do DXC nas camadas de geração de código e na infraestrutura do LLVM

    • O fork do LLVM usado pelo DXC remove ou danifica a camada de geração de código e a infraestrutura do LLVM.
    • Corrigir esse problema e restaurar os recursos quebrados do LLVM seria um trabalho gigantesco.
    • Por limitações de recursos, não há planos de resolver isso no novo compilador DXC.
    • No futuro, o Clang pode até vir a oferecer suporte à geração de DXBC, mas esse trabalho só deve começar daqui a alguns anos, já que o foco primeiro é oferecer suporte à geração de DXIL e SPIR-V.
    • Há agradecimentos à Microsoft por deixar as expectativas claramente definidas.
  • Conselho sobre o ecossistema Mach

    • Recomenda-se investigar especialmente o mach-sysgpu, uma reimplementação completa do WebGPU, escrita principalmente por Ali Chraghi, de 17 anos.
  • Discussão sobre SDL_gpu e SDL3

    • A equipe do SDL está desenvolvendo uma nova linguagem de shader chamada SDL_gpu, que será lançada no SDL3.
    • Isso deve oferecer uma forma de trabalhar entre plataformas em relação aos gráficos 3D em jogos.
  • Uso da linguagem Zig

    • Usar o próprio Zig como linguagem de shading seria algo muito legal.
    • Zig é uma linguagem de verdade, além de sistema de build e linguagem de shading.
  • Agradecimento pelo trabalho de infraestrutura

    • É um prazer ler sobre esse tipo de trabalho de infraestrutura, porque ele abre muitas portas.
  • Observação sobre a pronúncia de DXIL

    • DXIL é pronunciado como "dixel", como "pixel" trocando o 'p' por 'd'.