Skip to main content
O XDXR é a implementação do XBOX da API DirectX Raytracing (DXR) no XBOX Series X|S. Com exceção (em novembro de 2019) dos sombreadores chamáveis, o XDXR representa um superconjunto da funcionalidade fornecida pela API DXR em PCs Windows a partir da Atualização de novembro de 2019 do Windows 10. Neste tópico, presumimos que você esteja familiarizado com o DXR. É altamente recomendável que você leia a documentação do DXR e a especificação do DXR para Windows.

Diferenças em relação ao DXR no Windows

Ao criar uma assinatura raiz global, um sinalizador extra deve ser definido na descrição da assinatura raiz: D3D12XBOX_ROOT_SIGNATURE_FLAG_RAYTRACING. Atualmente, esse sinalizador não pode ser definido em uma assinatura raiz especificada em HLSL (linguagem de sombreador de alto nível) e deve ser definido no código antes que a assinatura raiz seja serializada. O XDXR não oferece suporte total à funcionalidade RayQuery.TraceRayInline() do DXR 1.1; no entanto, fornecemos um arquivo de cabeçalho (XDXRStandaloneTraverse) que imita a API RayQuery e deve permitir uma experiência de portabilidade muito simples para a maior parte do código de RayQuery. As diferenças específicas são indicadas em XDXR Standalone Traverse. Atualmente, o XDXR não oferece suporte a RAY_FLAG_SKIP_TRIANGLES, RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES nem ao sistema D3D12_RAYTRACING_PIPELINE_FLAGS. Isso poderá ser revisado no futuro. Atualmente, builds de TLAS em lote podem ser extremamente rápidos no XBOX e, nesse caso, construir TLASes separadas proporcionará melhor desempenho de travessia do que pular os nós. O XDXR oferece suporte a várias extensões para consultar o estado diretamente da BVH ou da travessia, sem a necessidade de usar dados de payload para armazenamento. Para usar essas extensões, declare antecipadamente uma ou mais das seguintes funções no início do seu sombreador de raytracing.

Design do XDXR

Em alto nível, a implementação do XDXR pode ser considerada dividida em duas partes: um núcleo de travessia e o “agendador”.

Núcleos de travessia

Um núcleo de travessia é a implementação de travessia da hierarquia de volumes delimitadores (BVH) do XDXR. Sua responsabilidade é tratar a travessia e decisões de alto nível, como quais sombreadores (por exemplo, closest-hit e any-hit) chamar. Ele não lida com a mecânica real de chamar o sombreador. Essa é a responsabilidade do agendador. O XDXR usa uma representação BVH4 para armazenar suas estruturas de aceleração. Embora outros formatos de BVH pudessem ter sido escolhidos, esse formato corresponde àquele para o qual o XBOX Series X|S tem hardware personalizado para realizar testes de interseção entre raio e caixa delimitadora alinhada aos eixos (AABB). Para obter mais detalhes, confira Design de hardware de raytracing.

Travessia

Atualmente, o XDXR não implementa nenhuma forma de reempacotamento, classificação ou reordenação de raios. A partir do momento em que um sombreador de geração de raios é invocado, qualquer thread que não esteja rastreando ativamente um raio é uma “lane inativa” na wave e está desperdiçando oportunidades de fazer trabalho útil. Conceitualmente, um raio é gerado em uma determinada thread. Quaisquer invocações subsequentes de sombreadores ou raios recursivos residem nessa mesma thread. Se um sombreador de geração de raios gerar dois raios na lane 0 e nenhum raio em todas as outras lanes de uma wave, a thread 0 precisará concluir sequencialmente seus dois raios enquanto todas as outras threads permanecem inativas. Atualmente, o XDXR expõe dois algoritmos para travessia de BVH. O algoritmo padrão é chamado de travessia “Divergent” e é a solução mais genérica, boa para cargas de trabalho divergentes, como reflexos brilhantes. Para TraceRayInline(), o cabeçalho equivalente é XDXRStandaloneTraverseShortStack.hlsli. Para cargas de trabalho altamente coerentes, como raios de sombra ou reflexos não brilhantes, o GDK de junho de 2022 fornece um novo algoritmo de travessia “Hybrid”. Esse algoritmo realiza a travessia da TLAS usando ramificação escalar, divergindo apenas ao entrar em uma BLAS. A travessia “Hybrid” pode proporcionar um desempenho significativamente melhor em alguns conteúdos e cargas de trabalho de raytracing. Para habilitar a travessia “Hybrid”, adicione XBOX_RAY_FLAG_COHERENT_RAYS_HINT aos sinalizadores de raio de TraceRay() do DXR 1.0. Os sinalizadores de raio e o ponteiro da TLAS devem ser uniformes para habilitar esse tipo de travessia. Para TraceRayInline(), o cabeçalho equivalente é XDXRStandaloneTraverseHT.hlsli.

Agendador

O agendador tem a responsabilidade de conduzir o “loop principal” do DXR. O design do DXR é tal que o suporte a chamadas de função por ponteiro (também conhecidas como chamadas indiretas) é necessário, um conceito normalmente não associado a arquiteturas de GPU. No futuro, a capacidade de fazer chamadas de função fora do DXR/XDXR será exposta para uso mais geral. Ao considerar a melhor forma de usar o XDXR, é importante considerar o impacto no desempenho de depender demais de chamadas de função repetidas. Chamadas para TraceRay e outros sombreadores DXR exigem salvar e recarregar o estado dos registradores de cada thread antes de saltar para um novo trecho de código. Salvar o estado de cada thread/raio na memória e recarregá-lo posteriormente consome uma quantidade considerável de largura de banda cada vez que isso ocorre. Em resoluções mais altas, se cada raio precisar gravar e ler o estado de seus registradores mesmo uma única vez, isso poderá acabar consumindo centenas de megabytes de memória se não for tratado adequadamente. Os requisitos de largura de banda para salvar/restaurar o estado dos raios superam muito rapidamente o custo de realmente ler a BVH e as informações de material associadas, como texturas. O acesso total à memória de raytracing deve incluir a leitura da BVH, de texturas, índices e vértices, a gravação de alguma saída baseada em UAV (exibição de acesso não ordenado) e a leitura/gravação do estado dos raios para viabilizar chamadas de função. É por esses motivos que recomendamos evitar recursão e sombreadores any-hit tanto quanto possível.

Compilação de sombreadores

A compilação de sombreadores para código de máquina acontece por coleção. Todas as funções que podem ser totalmente resolvidas são compiladas para código de máquina e usadas por ponteiro dentro do agendador. Os núcleos de travessia (funções de travessia) só são compilados sob demanda, com base no tamanho máximo dos atributos e na presença de sombreadores de interseção. Isso ajuda a manter o tamanho da memória baixo, acelerar a compilação e melhorar a utilização do cache de instruções. A pré-compilação de sombreadores é possível, mas os sombreadores de raytracing pré-compilados só funcionarão com a versão correspondente do agendador e dos núcleos de travessia. Isso se deve a uma convenção específica de chamada de funções que o XDXR está usando, que está sujeita a alterações a qualquer momento. Nossa recomendação para o XBOX quanto a isso ainda está em análise.

DispatchRays

Considerando a quantidade de memória necessária para executar o agendador do XDXR (em alguns casos, um kilobyte por raio!) e supondo, por enquanto, que o tamanho da memória temporária por raio fosse o único fator limitante de ocupação, para manter uma ocupação de 1 precisamos executar aproximadamente 3.584 lanes no XBOX Series X. A qualquer momento, precisamos ter vários megabytes de memória temporária em uso para cada lote de raios. Uma escolha óbvia para usar essa memória é a memória temporária do sistema. No entanto, sua utilidade é limitada no XBOX One: ela precisa de uma liberação completa para reprogramar o tamanho da memória temporária. Portanto, ela não tem suporte nos pipes de computação assíncrona. O SPI (Shader Processor Interpolator) não oferece suporte a mais de uma exibição da memória temporária, então isso não vai funcionar. Como resultado, DispatchRays usa vários dispatches para processar todo o conjunto de raios. O driver usa um buffer temporário personalizado que percorre ciclicamente os pequenos dispatches de DispatchRays. O tamanho disponível de memória temporária determinará o número de dispatches simultâneos e, portanto, o desempenho de raytracing. Fences regulares são usadas para impedir que os dispatches substituam a memória temporária personalizada que está sendo usada por outras waves já em andamento. DispatchRaysX permite especificar um buffer temporário personalizado. Isso é necessário ao executar cargas de trabalho de raytracing em computação assíncrona. Observe que a travessia autônoma do XDXR embutida não requer memória temporária e, portanto, pode ser executada em computação assíncrona como um sombreador de computação normal, sem tratamento especial.

Confira também

Visão geral de raytracing (e DXR)
Last modified on October 6, 2026