Constantes de sombreador (HLSL)

No Shader Model 4, as constantes de sombreador são armazenadas em um ou mais recursos de buffer na memória. Elas podem ser organizadas em dois tipos de buffers: buffers de constantes (cbuffers) e buffers de texturas (tbuffers). Os buffers de constantes são otimizados para uso de variáveis constantes, que é caracterizado pelo acesso de menor latência e pela atualização mais frequente da CPU. Por esse motivo, restrições adicionais de tamanho, layout e acesso se aplicam a esses recursos. Os buffers de texturas são acessados como texturas e têm um melhor desempenho para dados indexados arbitrariamente. Seja qual for o tipo de recurso usado, não há limite para o número de buffers de constantes ou buffers de texturas que um aplicativo pode criar.

Declarar um buffer de constantes ou um buffer de texturas se parece muito com uma declaração de estrutura em C, com a adição das palavras-chave register e packoffset para atribuir manualmente registros ou dados de empacotamento.

BufferType Name [: register(b#)] { VariableDeclaration [: packoffset(c#.xyzw)]; ... };

Parâmetros

BufferType

[in] O tipo de buffer.

BufferType Descrição
cbuffer buffer de constantes
tbuffer buffer de texturas

Nome

[in] Cadeia de caracteres ASCII que contém um nome de buffer exclusivo.

register(b#)

[in] Palavra-chave opcional, usada para empacotar manualmente dados de constantes. As constantes podem ser empacotadas em um registro somente e em um buffer de constantes, em que o registro inicial é dado pelo número de registro (#).

VariableDeclaration

[in] Declaração de variável, semelhante a uma declaração de membro da estrutura. Pode ser qualquer tipo HLSL ou objeto de efeito (exceto uma textura ou um objeto de amostra).

packoffset(c#.xyzw)

[in] Palavra-chave opcional, usada para empacotar manualmente dados de constantes. As constantes podem ser empacotadas em qualquer buffer de constantes, em que o número de registro é dado por (#). O empacotamento de subcomponentes (por meio do swizzling xyzw) está disponível para as constantes cujo tamanho cabe em um só registro (não cruzam um limite de registro). Por exemplo, um float4 não poderia ser empacotado em um só registro começando com o componente y, porque não caberia em um registro de quatro componentes.

Comentários

Os buffers de constantes reduzem a largura de banda necessária para atualizar as constantes de sombreador, permitindo que as constantes de sombreador sejam agrupadas e confirmadas ao mesmo tempo, em vez de fazer chamadas individuais para confirmar cada constante separadamente.

Um buffer de constantes é um recurso de buffer especializado que é acessado como um buffer. Cada buffer de constantes pode conter até 4.096 vetores, cada vetor contém até quatro valores de 32 bits. Você pode vincular até 14 buffers de constantes por fase de pipeline (dois slots adicionais são reservados para uso interno).

Um buffer de texturas é um recurso de buffer especializado que é acessado como uma textura. O acesso à textura (em comparação com o acesso ao buffer) pode ter um melhor desempenho para dados indexados arbitrariamente. Você pode vincular até 128 buffers de texturas por fase de pipeline.

Um recurso de buffer é projetado para minimizar a sobrecarga de definição de constantes de sombreador. A estrutura de efeitos (confira Interface ID3D10Effect) gerenciará a atualização dos buffers de constantes e texturas. Outra opção é usar a API do Direct3D para atualizar os buffers. Confira Como copiar e acessar dados de recursos (Direct3D 10) para obter informações. Um aplicativo também pode copiar dados de outro buffer (como um destino de renderização ou um destino de saída de fluxo) em um buffer de constantes.

Para obter mais informações sobre como usar buffers de constantes em um aplicativo D3D10, confira Tipos de recursos (Direct3D 10) e Como criar recursos de buffer (Direct3D 10).

Para obter mais informações sobre como usar buffers de constantes em um aplicativo D3D11, confira Introdução aos buffers no Direct3D 11 e Como criar um buffer de constantes.

Um buffer de constantes não exige que uma exibição seja vinculada ao pipeline. Um buffer de texturas, no entanto, exige uma exibição e precisa ser vinculado a um slot de textura (ou vinculado a SetTextureBuffer quando um efeito é usado).

Há duas maneiras de empacotar dados de constantes: usando as palavras-chave register (DirectX HLSL) e packoffset (DirectX HLSL).

Diferenças entre o Direct3D 9 e o Direct3D 10 e 11:

  • Ao contrário da alocação automática de constantes no Direct3D 9, que não fazia o empacotamento e, em vez disso, atribuía cada variável a um conjunto de registros float4, as variáveis de constantes HLSL seguem as regras de empacotamento do Direct3D 10 e 11.

Como organizar buffers de constantes

Os buffers de constantes reduzem a largura de banda necessária para atualizar as constantes de sombreador, permitindo que as constantes de sombreador sejam agrupadas e confirmadas ao mesmo tempo, em vez de fazer chamadas individuais para confirmar cada constante separadamente.

A melhor maneira de usar eficientemente os buffers de constantes é organizar as variáveis de sombreador em buffers de constantes com base na frequência de atualização deles. Isso permite que um aplicativo minimize a largura de banda necessária para atualizar as constantes de sombreador. Por exemplo, um sombreador pode declarar dois buffers de constantes e organizar os dados em cada um com base na frequência de atualização deles: os dados que precisam ser atualizados por objeto (como uma matriz mundial) são agrupados em um buffer de constantes que pode ser atualizado para cada objeto. Isso é separado dos dados que caracterizam uma cena e, portanto, é provável que seja atualizado com muito menos frequência (quando a cena muda).

cbuffer myObject
{       
    float4x4 matWorld;
    float3   vObjectPosition;
    int      arrayIndex;
}
 
cbuffer myScene
{
    float3   vSunPosition;
    float4x4 matView;
}
        

Buffers de constantes padrão

Há dois buffers de constantes padrão disponíveis, $Global e $Param. As variáveis que são colocadas no escopo global são adicionadas implicitamente ao cbuffer $Global, por meio do mesmo método de empacotamento usado para os cbuffers. Os parâmetros uniformes na lista de parâmetros de uma função aparecem no buffer de constantes $Param quando um sombreador é compilado fora da estrutura de efeitos. Quando ele é compilado dentro da estrutura de efeitos, todos os parâmetros uniformes precisam ser resolvidos para variáveis definidas no escopo global.

Exemplos

Este é um exemplo da Amostra de Skinning10 que é um buffer de texturas composto de uma matriz de matrizes.

tbuffer tbAnimMatrices
{
    matrix g_mTexBoneWorld[MAX_BONE_MATRICES];
};
      

Esse exemplo de declaração atribui manualmente um buffer de constantes para início em um registro específico e empacota os elementos específicos por subcomponentes.

cbuffer MyBuffer : register(b3)
{
    float4 Element1 : packoffset(c0);
    float1 Element2 : packoffset(c1);
    float1 Element3 : packoffset(c1.y);
}
      

Modelo de Sombreador 4