- Nas últimas décadas, APIs gráficas de baixo nível como DirectX 12, Vulkan e Metal aumentaram o desempenho da GPU, mas a complexidade e o custo de manutenção cresceram drasticamente
- GPUs modernas oferecem hierarquia completa de cache, ponteiros de 64 bits e recursos bindless, tornando desnecessários os antigos objetos de estado complexos e modelos de binding
- O design proposto simplifica drasticamente o pipeline de renderização com acesso à memória baseado em ponteiros C/C++ e um único ponteiro raiz de 64 bits
- Ele elimina explosão de PSO, barreiras de recursos e APIs de binding complexas, propondo uma estrutura que conecta diretamente a memória da GPU à linguagem de shader
- Essa abordagem aponta para uma API de próxima geração otimizada para arquiteturas modernas de GPU, indicando o caminho que DirectX 13 ou Vulkan 2.0 deveriam seguir
Mudanças nas APIs gráficas de baixo nível
- Em 2013, a arquitetura AMD GCN do Xbox One e do PS4 se tornou o padrão do desenvolvimento de jogos AAA, levando ao surgimento de APIs de baixo nível como Mantle, DirectX 12, Vulkan e Metal
- Em outras palavras, elas foram projetadas com base nas arquiteturas de GPU de por volta de 2013
- O antigo DirectX 11/OpenGL tinha limitações por causa da renderização em thread única e do alto overhead de driver
- Essas APIs reduziram o custo dos draw calls com objetos de pipeline pré-compilados (PSO), mas isso aumentou a complexidade por não se encaixar bem na estrutura dos engines
- Como resultado, surgiu outra “camada de driver de baixo nível” dentro dos engines, fragmentando ainda mais o papel dos programadores gráficos
Contexto histórico: por que isso ficou tão complexo
- As primeiras GPUs tinham memória separada e uma arquitetura centrada em pipelines de função fixa
- OpenGL e DirectX adotaram um design baseado em estado e objetos para abstrair a diversidade de hardware
- Mesmo até o DirectX 11, texturas e buffers eram gerenciados como descritores opacos
- Esse modelo de design continuou sendo mantido por inércia nas APIs posteriores
O descompasso entre GPUs modernas e APIs
- As GPUs atuais suportam hierarquia de cache coerente, PCIe ReBAR, ponteiros de 64 bits e texturas bindless
- Já é possível uma estrutura em que a CPU escreve diretamente na memória da GPU e a GPU lê imediatamente
- Nesse ambiente, estruturas como PSO, descriptor sets e tabelas de binding se tornam desnecessárias
- O problema da explosão de cache de PSO exige centenas de GB de cache, causando atrasos no carregamento e stuttering
- Uma nova API poderia remover essas estruturas ultrapassadas e migrar para uma abordagem simples baseada em ponteiros
Simplificação do gerenciamento de memória da GPU
- No Vulkan/DirectX 12 atual, é ineficiente precisar consultar compatibilidade de heap após criar recursos
- A proposta usa uma API simples no formato gpuMalloc/gpuFree para alocar memória da GPU diretamente
- A CPU pode mapear diretamente a memória da GPU para inicialização
- Dados grandes podem ser transferidos com comandos de cópia para realizar compressão DCC e processamento de swizzle
- O endereço mapeado pela CPU e o endereço da GPU são separados, com conversão via gpuHostToDevicePointer
Modernização dos dados e da linguagem de shader
- Usa-se uma linguagem de shader baseada em ponteiros C/C++, como CUDA, Metal e OpenCL
- O acesso à memória pode ser eficiente com wide loads em nível de struct (128 bits ou mais)
- ByteAddressBuffer do DirectX e texel buffers já não são mais a melhor opção
- GLSL/HLSL, por não suportarem ponteiros, carecem de um ecossistema de bibliotecas de shader reutilizáveis, enquanto CUDA evoluiu com um conjunto rico de bibliotecas
Argumentos raiz e estruturas de dados
- O kernel da GPU recebe um único ponteiro de 64 bits como entrada e o converte para struct
- CPU e GPU compartilham o mesmo header C/C++, garantindo consistência nas estruturas de dados
- As palavras-chave const/restrict orientam otimizações do compilador e eliminam a separação desnecessária entre UBO e SSBO
- Isso aproveita o pré-carregamento em registradores escalares e as otimizações dinâmicas de uniformes das GPUs modernas
Simplificação do binding de texturas
- Todas as texturas são gerenciadas em arrays de descritores de 256 bits (heap), com escrita direta por CPU e GPU
- O acesso baseado em índice de 32 bits permite amostragem de textura não uniforme (non-uniform)
- É mais simples que os descriptor heaps do DirectX 12 SM 6.6 e semelhante ao Vulkan VK_EXT_descriptor_buffer
- Criação, upload e sampling de texturas passam a ser unificados com base em ponteiros de memória da GPU
Pipeline de shaders e constantes
- A criação do pipeline se resume a carregar o shader IR e chamar gpuCreatePipeline
- Não há necessidade de root signature, descriptor sets ou definições de binding
- Constantes estáticas (baseadas em struct) substituem constantes de especialização de shader, reduzindo a explosão de combinações de PSO
- A struct de constantes pode incluir ponteiros de GPU, permitindo hardcode direto de endereços em tempo de execução
Simplificação de barreiras e sincronização
- As listas de barreiras por recurso das APIs atuais não combinam com a estrutura das GPUs modernas
- O modelo proposto usa apenas flags em bitfield por fila/estágio
- Isso é simplificado para o formato gpuBarrier(before, after, hazard), sem necessidade de rastreamento de recursos
- Os comandos gpuSignalAfter / gpuWaitBefore implementam sincronização GPU→GPU semelhante a timeline semaphores
Command buffers e renderização
- São usados apenas command buffers transitórios (transient), eliminando o modelo complexo de reutilização do Vulkan
- gpuBeginRenderPass / gpuEndRenderPass configuram os render targets e fazem o clear
- Não há barreiras automáticas entre render passes, permitindo otimizações de renderização paralela e depth pre-pass
Simplificação do pipeline de rasterização
- Vertex/pixel shaders acessam dados via ponteiros, removendo a necessidade de APIs de binding
- GpuDepthStencilState e GpuBlendState são separados do PSO para reduzir o número de combinações
- GPUs móveis oferecem blending programável por meio de framebuffer fetch intrinsic
- O PSO passa a conter apenas o estado mínimo, como topologia, formato e número de amostras
Draw indireto e renderização dirigida pela GPU
- Todos os argumentos (data, arguments) são passados como ponteiros de GPU
- gpuDrawIndexedInstancedIndirectMulti oferece suporte a multi-draw
- A própria GPU pode gerar os dados raiz e os argumentos de draw, viabilizando uma renderização totalmente GPU-driven
Ferramentas e compatibilidade
- Estruturas baseadas em ponteiros podem ser rastreadas por informações de símbolo, como em depuradores de CUDA/Metal
- A memória virtual oferece proteção, sem problemas de segurança, e acessos inválidos causam page fault
- Como em MoltenVK e Proton, APIs existentes como DirectX/Vulkan/Metal podem ser compatibilizadas por camadas de tradução
Requisitos mínimos e conclusão
- Nvidia Turing (2018), AMD RDNA1 (2019), Intel Xe1 (2022) e Apple M1 (2020) já suportam todos os recursos propostos
- As GPUs atuais já migraram para uma estrutura de bindless, ponteiros de 64 bits e cache coerente
- Só a API continua presa às abstrações do passado
- Uma nova API seria mais simples que DirectX 11, mais rápida que Vulkan e mais flexível que Metal
- A próxima geração de Vulkan 2.0 / DirectX 13 deveria migrar para esse design totalmente bindless e expandir o ecossistema com uma linguagem de shader baseada em ponteiros C/C++ no lugar de HLSL/GLSL
1 comentários
Comentários no Hacker News
Este é um excelente texto que mostra bem as partes desnecessárias do Vulkan e do DX12
Hoje em dia, o DX12 nem sequer suporta ponteiros de buffer, então passa a sensação de estar praticamente abandonado, e o Vulkan também não foi organizado em um 2.0, então há muitos drivers com extensões mal implementadas
Se uma nova API assim existisse, daria para emular o OpenGL muito mais rápido por cima dela, e algo como o SDL3 GPU talvez conseguisse um ganho de desempenho de 3 a 4 vezes
O livro do Frank Luna não cobre os recursos mais recentes, então é preciso garimpar o site Learn, exemplos no GitHub e a documentação de referência
O Vulkan também é complexo do mesmo jeito e, mesmo que um 2.0 saia, fica a dúvida de como isso poderia ser usado de fato em plataformas importantes como o Android
Tirando a Intel Arc, a maioria das GPUs funciona mesmo sem reBAR, mas parece que a Microsoft ou a Intel teriam de obrigar isso na UEFI para usar recursos como bindless texture com estabilidade
Só que, nesse caso, surgiria um piso mínimo de hardware compatível, e em placas-mãe anteriores a 2020 o suporte é bastante inconsistente
Está faltando a motivação central do texto
Pelo índice do blog, a ideia é que “nos últimos 10 anos a complexidade das APIs gráficas e das linguagens de shader aumentou drasticamente, e agora é preciso simplificar a camada de abstração para elevar a eficiência de desenvolvimento e o desempenho, além de preparar o terreno para futuras cargas de trabalho de GPU”
No começo, os SSDs reaproveitaram interfaces IDE/SATA, mas só conseguiram entregar o desempenho real quando abandonaram as premissas dos discos giratórios e adotaram um novo método de transferência
A comparação parece ser que as APIs gráficas também chegaram ao ponto de abandonar essas restrições legadas
Eu acompanho o trabalho do Sebastian Aaltonen há muito tempo, então talvez eu seja tendencioso, mas este texto está realmente excelente
Acho que a direção futura é um retorno ao rendering por software
A diferença é que, desta vez, os algoritmos e estruturas de dados recebem aceleração por hardware
Esse movimento já acontece na indústria de VFX, e um exemplo foi a portabilidade do OctaneRender para CUDA feita pela OTOY há cerca de 5 anos
Os tipos de shader servem para preencher os espaços entre essas etapas do pipeline, então uma softwareização completa não é realista
Por exemplo, o Nanite do Unreal Engine usa um rasterizador por software executado com compute shader da GPU para lidar com triângulos pequenos
Os detalhes do texto foram impressionantes
Entendi só uma parte, mas parece que ele vai virar uma futura referência de projeto de APIs gráficas
Para a maioria dos jogadores, Vulkan/DX12 não trouxe grandes vantagens, e vários jogos sofreram por causa de problemas com PSO
O Vulkan está melhorando, mas o WebGPU herdou intactas as limitações do projeto inicial do Vulkan
Com o hardware evoluindo tão rápido, talvez tenha sido um erro ir tão fundo em APIs de baixo nível
Talvez uma abordagem centrada em computação geral, como a do CUDA, seja um caminho melhor
Fiquei com saudade do Mantle
Tinha defeitos, mas passava a sensação de lidar diretamente com o hardware, e a época de desenvolvimento para o Xbox 360 foi a mais divertida para mim
Foi projetada pela Nvidia e pela Nintendo, e acho que é a API mais intuitiva entre os consoles
Depois de ler este texto, fiquei com a sensação de ter presenciado um momento histórico
Isso me fez lembrar do Google Toucan, que parece ser um projeto relacionado
Este texto trouxe muitas lembranças antigas
Entre os fatores adicionais que os projetistas de API precisam considerar estão
Fico curioso sobre por que a Microsoft não lança uma nova versão do DirectX
DirectX Ultimate e 12.2 são, na prática, o mesmo DX12
Será que, por causa do impacto de middlewares como o Unreal Engine, a importância de uma API própria diminuiu, ou será que a EPIC é que deveria propor uma nova API?
Desenvolvedores de jogos de verdade criam uma RHI (Rendering Hardware Interface) e focam no desenvolvimento do jogo
Ray tracing e mesh shaders foram as maiores inovações, mas ainda têm pouca adoção, então parece que nada mais avançou
Com a centralização em engines como Unreal e Unity, o interesse por inovação em APIs diminuiu, e os avanços continuaram mais do lado da GPU
A API de CPU ainda está no nível simples de mapeamento de buffers
Como aconteceu quando surgiram os tessellation shaders, talvez seja preciso uma nova mudança de hardware para haver progresso
Fico pensando se a Valve poderia criar sua própria API gráfica para o SteamOS
Ouvi dizer que a Valve foi um dos principais atores na fase inicial de desenvolvimento do Vulkan