Packregeln für konstante Variablen
Füllregeln geben vor, wie streng Daten angeordnet werden können, wenn sie gespeichert werden. HLSL implementiert Packregeln für VS-Ausgabedaten, GS-Eingabe- und -Ausgabedaten sowie PS-Eingabe- und -Ausgabedaten. (Daten werden für VS-Eingaben nicht gepackt, da die IA-Phase keine Daten entpacken kann.)
HLSL-Füllregeln ähneln dem Ausführen eines # Pragmapakets 4 mit Visual Studio, das Daten in 4-Byte-Grenzen packt. Darüber hinaus packt HLSL Daten so, dass sie keine 16-Byte-Grenze überschreiten. Variablen werden in einen angegebenen Vektor mit vier Komponenten gepackt, bis die Variable eine 4-Vektor-Grenze umranden wird. Die nächsten Variablen werden auf den nächsten Vektor mit vier Komponenten springen.
Jede Struktur erzwingt, dass die nächste Variable mit dem nächsten Vektor mit vier Komponenten beginnt. Dies generiert manchmal Auf padding für Arrays von -Strukturen. Die resultierende Größe einer Struktur ist immer gleichmäßig durch sizeof*(Vektor mit vier Komponenten) teilbar.*
Arrays werden standardmäßig nicht in HLSL gepackt. Um zu vermeiden, dass der Shader den ALU-Mehraufwand für Offsetberechnungen übernehmen muss, wird jedes Element in einem Array in einem Vektor mit vier Komponenten gespeichert. Beachten Sie, dass Sie das Packen für Arrays (und die Adressierungsberechnungen) mithilfe der Umwandlung erreichen können.
Im Folgenden finden Sie Beispiele für Strukturen und deren entsprechende gepackte Größen (angegeben: float1 belegt 4 Bytes):
// 2 x 16byte elements
cbuffer IE
{
float4 Val1;
float2 Val2; // starts a new vector
float2 Val3;
};
// 3 x 16byte elements
cbuffer IE
{
float2 Val1;
float4 Val2; // starts a new vector
float2 Val3; // starts a new vector
};
// 1 x 16byte elements
cbuffer IE
{
float1 Val1;
float1 Val2;
float2 Val3;
};
// 1 x 16byte elements
cbuffer IE
{
float1 Val1;
float2 Val2;
float1 Val3;
};
// 2 x 16byte elements
cbuffer IE
{
float1 Val1;
float1 Val1;
float1 Val1;
float2 Val2; // starts a new vector
};
// 1 x 16byte elements
cbuffer IE
{
float3 Val1;
float1 Val2;
};
// 1 x 16byte elements
cbuffer IE
{
float1 Val1;
float3 Val2;
};
// 2 x 16byte elements
cbuffer IE
{
float1 Val1;
float1 Val1;
float3 Val2; // starts a new vector
};
// 3 x 16byte elements
cbuffer IE
{
float1 Val1;
struct {
float4 SVal1; // starts a new vector
float1 SVal2; // starts a new vector
} Val2;
};
// 3 x 16byte elements
cbuffer IE
{
float1 Val1;
struct {
float1 SVal1; // starts a new vector
float4 SVal2; // starts a new vector
} Val2;
};
// 3 x 16byte elements
cbuffer IE
{
struct {
float4 SVal1;
float1 SVal2; // starts a new vector
} Val1;
float1 Val2;
};
Aggressiveres Packen
Sie können ein Array aggressiver packen. Beispiel: Bei einem Array von float-Variablen:
float4 array[16];
Sie können sie wie die folgenden ohne Leerzeichen im Array packen:
static float2 aggressivePackArray[32] = (float2[32])array;
Das strengere Packen ist ein Vor- und Abkniff im Vergleich zur Notwendigkeit zusätzlicher Shaderanweisungen für die Adressberechnung.