Constantes de sombreador (HLSL)

En el modelo de sombreador 4, las constantes de sombreador se almacenan en uno o varios recursos de búfer en la memoria. Se pueden organizar en dos tipos de búferes: búferes de constantes (cbuffers) y búferes de texturas (tbuffers). Los búferes de constantes están optimizados para el uso de variables constantes, que se caracteriza por el acceso de menor latencia y la actualización más frecuente desde la CPU. Por este motivo, se aplican restricciones de tamaño, diseño y acceso adicionales a estos recursos. Se accede a los búferes de texturas como texturas y funcionan mejor para los datos indexados arbitrariamente. Independientemente del tipo de recurso que use, no hay ningún límite para el número de búferes de constantes o búferes de texturas que puede crear una aplicación.

La declaración de un búfer de constantes o un búfer de texturas es muy similar a una declaración de estructura en C, con la adición de las palabras clave register y packoffset para asignar manualmente registros o datos de empaquetado.

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

Parámetros

BufferType

[in] Tipo de búfer.

BufferType Descripción
cbuffer búfer de constantes
tbuffer búfer de texturas

Nombre

[in] Cadena ASCII que contiene un nombre de búfer único.

register(b#)

[in] Palabra clave opcional, que se usa para empaquetar manualmente los datos de constantes. Las constantes solo se pueden empaquetar en un registro en un búfer de constantes, donde el registro inicial viene dado por el número de registro (#).

VariableDeclaration

[in] Declaración de variable, similar a una declaración de miembro de estructura. Puede ser cualquier tipo HLSL u objeto de efecto (excepto una textura o un objeto sampler).

packoffset(c#.xyzw)

[in] Palabra clave opcional, que se usa para empaquetar manualmente los datos de constantes. Las constantes se pueden empaquetar en cualquier búfer de constantes, donde el número de registro viene dado por (#). El empaquetado de subcomponente (mediante xyzw swizzling) está disponible para constantes cuyo tamaño cabe dentro de un único registro (no cruzan un límite de registro). Por ejemplo, un float4 no podría empaquetarse en un único registro empezando por el componente y porque no cabría en un registro de cuatro componentes.

Comentarios

Los búferes de constantes reducen el ancho de banda necesario para actualizar las constantes del sombreador al permitir que las constantes del sombreador se agrupen y confirmen al mismo tiempo en lugar de realizar llamadas individuales para confirmar cada constante por separado.

Un búfer de constantes es un recurso de búfer especializado al que se accede como un búfer. Cada búfer de constantes puede contener hasta 4096 vectores; cada vector contiene hasta cuatro valores de 32 bits. Puede enlazar hasta 14 búferes de constantes por fase de canalización (2 ranuras adicionales están reservadas para uso interno).

Un búfer de textura es un recurso de búfer especializado al que se accede como una textura. El acceso a texturas (en comparación con el acceso al búfer) puede tener un mejor rendimiento para los datos indexados arbitrariamente. Puede enlazar hasta 128 búferes de textura por fase de canalización.

Un recurso de búfer está diseñado para minimizar la sobrecarga de establecer constantes del sombreador. El marco de efecto (vea ID3D10Effect Interface) administrará la actualización de búferes de constantes y texturas, o puede usar la API de Direct3D para actualizar los búferes (consulte Copia y acceso a datos de recursos [Direct3D 10]) para obtener información. Una aplicación también puede copiar datos de otro búfer (como un destino de representación o un destino de salida de flujo) en un búfer de constantes.

Para obtener más información sobre el uso de búferes de constantes en una aplicación D3D10, consulte Tipos de recursos (Direct3D 10) y Creación de recursos de búfer (Direct3D 10).

Para obtener más información sobre el uso de búferes de constantes en una aplicación D3D11, consulte Introducción a los búferes en Direct3D 11 y Creación de un búfer de constantes.

Un búfer de constantes no requiere que una vista esté enlazada a la canalización. Sin embargo, un búfer de texturas requiere una vista y debe enlazarse a una ranura de textura (o debe enlazarse con SetTextureBuffer al usar un efecto).

Hay dos maneras de empaquetar datos de constantes: usar las palabras clave register (DirectX HLSL) y packoffset (DirectX HLSL).

Diferencias entre Direct3D 9 y Direct3D 10 y 11:

  • A diferencia de la asignación automática de constantes en Direct3D 9, que no realizó el empaquetado y, en su lugar, asignó cada variable a un conjunto de registros float4, las variables constantes HLSL siguen las reglas de empaquetado en Direct3D 10 y 11.

Organización de búferes de constantes

Los búferes de constantes reducen el ancho de banda necesario para actualizar las constantes del sombreador al permitir que las constantes del sombreador se agrupen y confirmen al mismo tiempo en lugar de realizar llamadas individuales para confirmar cada constante por separado.

La mejor manera de usar de forma eficaz los búferes de constantes es organizar las variables del sombreador en búferes de constantes en función de su frecuencia de actualización. Esto permite que una aplicación minimice el ancho de banda necesario para actualizar las constantes del sombreador. Por ejemplo, un sombreador podría declarar dos búferes de constantes y organizar los datos en cada uno en función de su frecuencia de actualización: los datos que deben actualizarse por objeto (como una matriz mundial) se agrupan en un búfer de constantes que se podría actualizar para cada objeto. Esto es independiente de los datos que caracterizan una escena y, por tanto, es probable que se actualicen mucho menos a menudo (cuando cambia la escena).

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

Búferes de constantes predeterminados

Hay dos búferes de constantes predeterminados disponibles, $Global y $Param. Las variables que se colocan en el ámbito global se agregan implícitamente al cbuffer $Global, mediante el mismo método de empaquetado que se usa para cbuffers. Los parámetros uniformes de la lista de parámetros de una función aparecen en el búfer de constantes $Param cuando se compila un sombreador fuera del marco de efectos. Cuando se compila dentro del marco de efectos, todos los uniformes deben resolverse en variables definidas en el ámbito global.

Ejemplos

Este es un ejemplo de Skinning10 Sample, que es un búfer de texturas formado por una matriz de matrices.

tbuffer tbAnimMatrices
{
    matrix g_mTexBoneWorld[MAX_BONE_MATRICES];
};
      

Esta declaración de ejemplo asigna manualmente un búfer de constantes para iniciarse en un registro determinado y también empaqueta elementos concretos por subcomponentes.

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

Modelo de sombreador 4