> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XDXRStandaloneTraverse

> XDXRStandaloneTraverse

Atualmente, o XDXR não oferece suporte ao objeto `RayQuery` descrito no DXR 1.1. No entanto, fornecemos uma implementação de travessia em um único cabeçalho (com diversas variantes) que compartilha a maior parte da nossa lógica de travessia do DXR 1.0 e a encapsula em uma API amplamente equivalente à API do objeto `RayQuery`. Esse cabeçalho pode ser usado em qualquer estágio de sombreador que permita a alocação de LDS pelo usuário, incluindo sombreadores de computação e de pixel.

Esse sistema deve permitir uma conversão simples (quase 1:1) de código de renderização de PC que dependa do `RayQuery` do DXR 1.1. Além disso, em situações com poucos sombreadores de raytracing (AnyHit/ClosestHit/etc.), esse sistema costuma ser significativamente mais rápido do que o raytracing no estilo DXR 1.0 no XBOX, devido à menor sobrecarga. É altamente recomendável que recursos de renderização como sombras ou oclusão de ambiente usem esse sistema de cabeçalho embutido.

Observe que, atualmente, o XDXR não realiza o inlining de pequenas tabelas de associação de sombreadores para o DXR 1.0. Alguns IHVs de PC podem ter recomendações diferentes por causa disso. Recomendamos criar perfis das compensações de raytracing do XBOX independentemente dos drivers de PC.

## Uso

### Cabeçalhos

No lugar do objeto `RayQuery` do DXR 1.1, fornecemos várias versões de um arquivo de cabeçalho XDXRStandaloneTraverse\*\*\*.hlsli dentro do diretório de instalação do GDK: `GDK_Install_Path\GDK_Version\GXDK\gameKit\Include\Scarlett`.

Esses cabeçalhos são fornecidos como código-fonte; no entanto, cabe ao desenvolvedor garantir que a versão do arquivo de cabeçalho seja compatível com o GDK com o qual suas BVHs são construídas. Versões anteriores do cabeçalho não terão suporte em GDKs mais recentes, e modificações no cabeçalho devem ser mescladas com quaisquer alterações de um GDK mais recente.

Atualmente, as versões são as seguintes:

* XDXRStandaloneTraverseShortStack.hlsli
  * Esta versão de travessia espelha o algoritmo de travessia padrão atual usado para o suporte ao DXR 1.0 no XDXR. Recomendada para todo raytracing que provavelmente será divergente, como AO ou reflexos brilhantes.
* XDXRStandaloneTraverseHT.hlsli
  * Esta versão de travessia implementa um algoritmo de travessia "coerente" que pode ser mais rápido do que outros algoritmos para conteúdo altamente coerente, como raios de sombra ou reflexos espelhados. Isso equivale a especificar `XBOX_RAY_FLAG_COHERENT_RAYS_HINT` nos sinalizadores de raio de `TraceRay()` do DXR 1.0.
* XDXRStandaloneTraverseShortStackNoMultibox.hlsli
  * Esta versão de travessia não oferece suporte a BVHs construídas offline, mas pode ser um pouco mais rápida se apenas builds de BVH em tempo de execução forem realizados.
* XDXRStandaloneTraverseLongStack.hlsli
  * Esta versão de travessia tem um tamanho máximo de pilha de 32 nós; isso pode ser mais rápido em alguns conteúdos, mas pode resultar em acertos de raio ausentes.

### Integração

Os cabeçalhos XDXRStandaloneTraverse fornecem um objeto `XboxRayQuery` que espelha o objeto `RayQuery` do DXR 1.1. Exceto pela nomenclatura, a API deve ser a mesma do DXR 1.1, com as seguintes diferenças:

* Sinalizadores de modelo como `XboxRayQuery<RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES>` só têm suporte ao compilar com HLSL 2021, no GDK de março de 2024 ou posterior.
* Antes do HLSL 2021 e do GDK de março de 2024, no lugar de `RayQuery<RAY_FLAG_XXX | RAY_FLAG_YYY>`, os usuários devem fazer uma das seguintes ações:
  * Colocar todos os sinalizadores dentro do parâmetro rayFlags de TraceRayInline(). Prefira usar literais de tempo de compilação para os sinalizadores em vez de valores de buffer constante, para permitir uma melhor geração de código. Considere ramificar entre diferentes chamadas de TraceRayInline() se quiser alternar sinalizadores.
  * No lugar de `RayQuery<RAY_FLAG_FORCE_OPAQUE>`, use `XboxRayQuery.TraceRayInlineNoAHS()`; da mesma forma, use `XboxRayQuery.TraceRayInlineNoIS()` ou `XboxRayQuery.TraceRayInlineNoAHSNoIS()` para desabilitar o tratamento de sombreadores de interseção.
    * De forma equivalente, há os membros booleanos `disableAHS` e `disableIS` no objeto `XboxRayQuery`, que podem ser definidos como literais após a chamada para `TraceRayInline`, mas antes da primeira chamada para `Proceed()`.
* O `XboxRayQuery` mantém estado global; todo o uso de um objeto `XboxRayQuery` deve ser concluído antes da criação ou do uso de um segundo objeto. Isso inclui consultar o status ou as informações do acerto final.
* O XDXR (e o `XboxRayQuery`) atualmente não oferece suporte a `RAY_FLAG_SKIP_TRIANGLES` ou `RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES`. Se a separação for necessária, considere construir várias TLASes em paralelo com a API do construtor em lote.
  * Uma exceção é que `XboxRayQuery<RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES>` tem suporte no HLSL2021 e equivale a `XboxRayQuery.TraceRayInlineNoIS()`. Esse sinalizador só tem suporte como parâmetro de modelo.
* Devido à estrutura do algoritmo coerente, o `XDXRStandaloneTraverseHT.hlsli` exige que todo o código do manipulador de `Proceed()` verifique se um acerto válido foi realmente relatado, adicionando um `if (query.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE || query.CandidateType() == CANDIDATE_PROCEDURAL_PRIMITIVE)` antes da lógica de AnyHit ou do sombreador de interseção. Embora isso seja permitido no DXR 1.1 normal, costuma ser omitido quando se sabe que a BVH contém apenas um tipo de primitiva. Isso causará artefatos na implementação de `XDXRStandaloneTraverseHT.hlsli`.
* A implementação de travessia `XDXRStandaloneTraverseHT.hlsli` exige que os sinalizadores de raio e o ponteiro da TLAS sejam uniformes.
* A travessia autônoma do XDXR inclui várias extensões não presentes no DXR 1.1, discutidas na próxima seção.

### CurrentNumIterations() e SetMaxNumIterations()

A travessia autônoma do XDXR adiciona duas extensões simples relacionadas à consulta e à limitação das contagens de iterações de travessia. Observe que cada uma dessas extensões pode causar pressão adicional de VGPR ou de ALU. Os usuários não devem usar/habilitar esses recursos, a menos que pretendam definir um limite de iterações baixo o suficiente para compensar o custo adicional.

* `XboxRayQuery.CurrentNumIterations()` retorna o número de iterações da lógica de travessia que ocorreram até o momento. Isso pode ser chamado após a travessia, para desenhar um mapa de calor, ou dentro da lógica de AHS ou semelhante para tomar decisões. Qualquer referência a essa função no seu sombreador adicionará um pequeno custo à travessia, inclusive quando estiver por trás de um sinalizador de tempo de execução. Recomendamos colocar quaisquer modos de "mapa de calor" por trás de um sinalizador `#ifdef` para garantir que os modos de versão de lançamento não sejam afetados.
* `XboxRayQuery.SetMaxNumIterations(uint maxNumIterations)` permite definir uma contagem máxima de iterações, após a qual a travessia será encerrada antecipadamente, e os resultados incluirão o acerto confirmado mais recente (ou nada, se nenhum tiver sido encontrado ainda).
  * Para usar esse recurso, `#define XDXR_ENABLE_ITERATION_LIMIT 1` deve ser definido antes de incluir o cabeçalho de travessia.
  * Coloque a chamada para `XboxRayQuery.SetMaxNumIterations(YOUR_ITERATION_LIMIT)` após a chamada para `XboxRayQuery.TraceRayInline()` e antes da chamada para `XboxRayQuery.Proceed()`.
  * Para testar se a travessia foi encerrada antecipadamente, verifique se `XboxRayQuery.CurrentNumIterations() >= YOUR_ITERATION_LIMIT`. Observe que a contagem de iterações pode ser maior que o limite, especialmente no caso de `XDXRStandaloneTraverseHT.hlsli`, pois alguns estágios da travessia não podem ser encerrados antecipadamente sem incorrer em um custo alto.

### InlineAHS e InlineIS

A travessia autônoma do XDXR fornece duas extensões para melhorar a velocidade da travessia quando é necessária uma lógica simples de AnyHit ou de sombreador de interseção.

Por padrão, a travessia de RayQuery do DXR 1.1 precisa sair do loop de travessia da BVH para dar controle ao usuário para tratar a lógica de AnyHit ou do sombreador de interseção em um loop `while(query.Proceed())`. Isso pode levar a um fluxo de controle complexo e a um desempenho abaixo do ideal.

A travessia autônoma do XDXR fornece os mecanismos InlineAHS e InlineIS para melhorar o desempenho, permitindo que a lógica de AHS ou IS seja embutida dentro do loop de travessia.

A partir do GDK de março de 2024, as definições `XDXR_USE_INLINE_AHS_FUNCTION` e `XDXR_USE_INLINE_IS_FUNCTION` foram preteridas. Os recursos InlineAHS e InlineIS agora estão disponíveis por meio de uma API baseada em modelos do HLSL 2021, com várias vantagens. As instruções para a versão do HLSL 2021 vêm a seguir, com uma seção sobre a versão anterior mais abaixo.

#### InlineAHS e InlineIS no HLSL 2021

* Crie uma struct HLSL que estenda `InlineAHSBaseLambda`, `InlineISBaseLambda` ou `InlineAHSAndISBaseLambda`, dependendo de se você precisa de lógica de AnyHit (AHS), lógica de interseção procedural (IS) ou ambas.
* Crie uma função com a assinatura e o nome `void InlineAHS(inout XboxRayQueryProxy rqp)` e/ou `void InlineIS(inout XboxRayQueryProxy rqp)` dentro da sua struct.
* Recorte/cole toda a lógica de AHS e IS do seu loop `while(query.Proceed()) {ISLogic(); AHSLogic()}` nas funções `InlineAHS` ou `InlineIS`.
* O objeto `XboxRayQueryProxy` oferece suporte a todas as mesmas funcionalidades do `XboxRayQuery` normal, exceto o getter `XboxRayQuery.CandidateType()`. Trate a lógica de `CANDIDATE_NON_OPAQUE_TRIANGLE` em `InlineAHS()` e a lógica de `CANDIDATE_PROCEDURAL_PRIMITIVE`, incluindo o teste alfa, em `InlineIS()`.
* O `XboxRayQueryProxy` pode ser usado para consultar informações de travessia exatamente da mesma forma que um objeto `RayQuery` normal, e para tratar acertos por meio das funções `rayQueryProxy.CommitNonOpaqueTriangleHit()` ou `rayQueryProxy.Abort()`.
  * `rayQueryProxy.CandidateProceduralPrimitiveNonOpaque()` pode ser consultado dentro de `InlineIS()` para determinar se a lógica de AHS deve ser executada para a primitiva procedural. Isso é o mesmo que no raytracing embutido padrão do DXR 1.1.
* Quando `InlineAHS` ou `InlineIS` (ou ambos) são usados, não há necessidade de colocar a chamada `rayQuery.Proceed()` dentro de um loop while, pois o controle não retornará ao usuário até que a travessia seja concluída. Toda a lógica de AHS ou IS será embutida usando as funções fornecidas.

```cpp theme={null}
#ifdef COMPILE_FLAG_INLINE_TRAVERSAL_HYBRID 
    #include "XDXRStandaloneTraverseHT.hlsli"
#else
    #include "XDXRStandaloneTraverseShortStack.hlsli"
#endif

// Extend one of: InlineAHSBaseLambda, InlineISBaseLambda, InlineAHSAndISBaseLambda.
// Implement one or both of: void InlineAHS(inout XboxRayQueryProxy rqp), void InlineIS(inout XboxRayQueryProxy rqp).
struct MyAHSLambda : InlineAHSBaseLambda
{
    // Optional: lambda structs can contain whatever state is required for your use-case.
    bool statefulVariable;

    void InlineAHS(inout XboxRayQueryProxy rqp)
    {
        if (MyAnyHitShaderImpl(...))
        {
            // rqp is inout, use the Commit functions as you would in DXR 1.1.
            rqp.CommitNonOpaqueTriangleHit();
        }

        if (statefulVariable)
        {
            ...
        }
    
        // Default is to ignore hits, to exit traversal completely use rqp.Abort().
    }
};

// Requires HLSL 2021.
[RootSignature(GlobalRootSignature)]
[numthreads(8, 4, 1)]
void MyRaygenShaderWith2021Lambda(uint3 DTid : SV_DispatchThreadID)
{
    RayDesc myRay = { ... };

    // RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES is used here to avoid costs associated with procedural primitive handling.
    // MyAHSLambda's InlineAHS will be inlined into the traversal loop.
    XboxRayQuery<RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES, MyAHSLambda> xrq;

    xrq.TraceRayInline(
        Scene,
        RAY_FLAG_NONE,
        0xff,
        myRay);

    MyAHSLambda myStatefulLambda;
    myStatefulLambda.statefulVariable = bool(DTid.x < 10);

    // Looping over this call is not required if the InlineAHS mechanism is used.
    // If your lambda struct has state members, it must be instantiated and provided as an argument to Proceed().
    // If your lambda struct does not have state members, this parameter can be omitted.
    xrq.Proceed(/*optional*/ myStatefulLambda);

    if (xrq.CommittedStatus() == COMMITTED_TRIANGLE_HIT)
    {
        ...
    }
}

// Requires HLSL 2021.
[RootSignature(GlobalRootSignature)]
[numthreads(8, 4, 1)]
void MyRaygenShaderWith2021Flags(uint3 DTid : SV_DispatchThreadID)
{
    RayDesc myRay = { ... };

    // RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES is used here to avoid costs associated with procedural primitive handling.
    XboxRayQuery<RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES> xrq;

    xrq.TraceRayInline(
        Scene,
        RAY_FLAG_NONE,
        0xff,
        myRay);

    // We have to loop over hit-candidates here. Normal DXR 1.1 Inline Raytracing style.
    while (xrq.Proceed())
    {
        // This if-statement is required for XDXRStandaloneTraverseHT even if the BVH is known to only contain triangles. Otherwise lanes without hits may remain active in this loop.
        if (xrq.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE)
        {
            if (MyAnyHitShaderImpl(alphaTexture, shaderRecord.alphaIsMask, xrq.CandidateTriangleBarycentrics(), u1, u2, u3))
            {
                xrq.CommitNonOpaqueTriangleHit();
            }               
        }
    }

    if (xrq.CommittedStatus() == COMMITTED_TRIANGLE_HIT)
    {
        ...
    }
}

// Works in HLSL 2018.
[RootSignature(GlobalRootSignature)]
[numthreads(8, 4, 1)]
void MyRaygenShaderWith2018Flags(uint3 DTid : SV_DispatchThreadID)
{
    RayDesc myRay = { ... };

    // No template flags in HLSL 2018.
    XboxRayQuery xrq;

    // TraceRayInlineNoIS is used here to avoid costs associated with procedural primitive handling.
    // Equivalent to XboxRayQuery<RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES> in HLSL 2021 versions.
    xrq.TraceRayInlineNoIS(
        Scene,
        RAY_FLAG_NONE,
        0xff,
        myRay);

    while (xrq.Proceed())
    {
        // This if-statement is required for XDXRStandaloneTraverseHT even if the BVH is known to only contain triangles. Otherwise lanes without hits may remain active in this loop.
        if (xrq.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE)
        {
            if (MyAnyHitShaderImpl(alphaTexture, shaderRecord.alphaIsMask, xrq.CandidateTriangleBarycentrics(), u1, u2, u3))
            {
                xrq.CommitNonOpaqueTriangleHit();
            }               
        }
    }

    if (xrq.CommittedStatus() == COMMITTED_TRIANGLE_HIT)
    {
        ...
    }
}
```

#### InlineAHS e InlineIS no HLSL 2018 (preterido)

* Especifique `#define XDXR_USE_INLINE_AHS_FUNCTION 1` e/ou `#define XDXR_USE_INLINE_IS_FUNCTION 1` antes de `#include "XDXRStandaloneTraverse****.hlsli"`. Observe que, se houver lógica de AHS e de IS, ambas devem usar o sistema embutido e não podem ser misturadas com os manipuladores normais do DXR 1.1.
* Crie uma função global com a assinatura e o nome `void InlineAHS(inout XboxRayQueryProxy rqp)` e/ou `void InlineIS(inout XboxRayQueryProxy rqp)`
* Siga as instruções da versão do HLSL 2021 acima, substituindo as funções InlineAHS e InlineIS membros da struct pelas funções InlineAHS e InlineIS definidas globalmente.

## Memória

O driver do XDXR aloca memória de suporte para a travessia no estilo `TraceRay()` do DXR 1.0. Se o seu título usar apenas raytracing embutido, talvez você queira recuperar essa memória. Em junho de 2022, isso corresponde a 12 MB no XBOX Series S e 32 MB no XBOX Series X. Para desabilitar essa memória, o título deve especificar `D3D12_GPU_VIRTUAL_ADDRESS_UNKNOWN` para `pDXRStackBuffer`, além de especificar um tamanho de `0` para `DXRStackBufferOverrideSizeBytes` em [D3D12XBOX\_CREATE\_DEVICE\_PARAMETERS](/pt-BR/reference/graphics/d3d12_xs/structs/d3d12xbox_create_device_parameters_xs).

## Integração com o PIX

Consulte a seção "Draw Rays" na documentação do [visualizador de BVH do PIX](/pt-BR/tools/tools-console/pix/gpu/pix-bvh-viewer) para obter instruções sobre como habilitar a exibição de caminhos de raios e de mapas de calor no PIX ao usar a travessia autônoma.

## Confira também

[Visualizador de BVH do PIX](/pt-BR/tools/tools-console/pix/gpu/pix-bvh-viewer) [Visão geral de raytracing (e DXR)](/pt-BR/build/core-features/graphics/newfeatures/raytracing/rt-overview)


## Related topics

- [Diretório de tópicos NDA: links ativos do Microsoft Learn](/pt-BR/nda/nda-topic-directory.md)
- [Ray tracing no XBOX Series X|S com XDXR](/pt-BR/build/core-features/graphics/newfeatures/raytracing/index.md)
- [Notas de versão do PlayFab 2016](/pt-BR/services/playfab/release-notes/2016.md)
- [Visão geral dos SDKs autônomos](/pt-BR/services/playfab/sdks/sdk-overview.md)
- [Introdução ao Android](/pt-BR/services/playfab/multiplayer/networking/android-specific-requirements.md)
