Freigeben über


Bytecodeänderungen in SM5.1

SM5.1 ändert, wie Ressourcenregister deklariert und in Anweisungen referenziert werden.

SM5.1 bewegt sich zum Deklarieren einer Registervariablen, ähnlich wie dies für Gruppenfreigabespeicherregister geschieht, veranschaulicht durch das folgende Beispiel:

Texture2D<float4> tex0          : register(t5,  space0);
Texture2D<float4> tex1[][5][3]  : register(t10, space0);
Texture2D<float4> tex2[8]       : register(t0,  space1);
SamplerState samp0              : register(s5, space0);

float4 main(float4 coord : COORD) : SV_TARGET
{
    float4 r = coord;
    r += tex0.Sample(samp0, r.xy);
    r += tex2[r.x].Sample(samp0, r.xy);
    r += tex1[r.x][r.y][r.z].Sample(samp0, r.xy);
    return r;
}

Die Disassemblierung dieses Beispiels folgt:

// Resource Bindings:
//
// Name                                 Type  Format         Dim Space Slot  Elements
// ------------------------------ ---------- ------- ----------- ----- ---- ---------
// samp0                             sampler      NA          NA     0    5         1
// tex0                              texture  float4          2d     0    5         1
// tex1[0][5][3]                     texture  float4          2d     0   10 unbounded
// tex2[8]                           texture  float4          2d     1    0         8
//
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// COORD                    0   xyzw        0     NONE   float   xyzw
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
//
ps_5_1
dcl_globalFlags refactoringAllowed
dcl_sampler s0[5:5], mode_default, space=0
dcl_resource_texture2d (float,float,float,float) t0[5:5], space=0
dcl_resource_texture2d (float,float,float,float) t1[10:*], space=0
dcl_resource_texture2d (float,float,float,float) t2[0:7], space=1
dcl_input_ps linear v0.xyzw
dcl_output o0.xyzw
dcl_temps 2
sample r0.xyzw, v0.xyxx, t0[0].xyzw, s0[5]
add r0.xyzw, r0.xyzw, v0.xyzw
ftou r1.x, r0.x
sample r1.xyzw, r0.xyxx, t2[r1.x + 0].xyzw, s0[5]
add r0.xyzw, r0.xyzw, r1.xyzw
ftou r1.xyz, r0.zyxz
imul null, r1.yz, r1.zzyz, l(0, 15, 3, 0)
iadd r1.y, r1.z, r1.y
iadd r1.x, r1.x, r1.y
sample r1.xyzw, r0.xyxx, t1[r1.x + 10].xyzw, s0[5]
add o0.xyzw, r0.xyzw, r1.xyzw
ret
// Approximately 12 instruction slots used

Jeder Shaderressourcenbereich verfügt jetzt über eine ID (einen Namen) im Shader-Bytecode. Beispielsweise wird das Texturarray "tex1" im Shaderbytecode zu "t1". Die Angabe eindeutiger IDs für jeden Ressourcenbereich ermöglicht zwei Dinge:

  • Identifizieren Sie eindeutig, welcher Ressourcenbereich (siehe dcl_resource_texture2d) in einer Anweisung indiziert wird (siehe Beispielanweisung).
  • Fügen Sie der Deklaration eine Reihe von Attributen an, z. B. Elementtyp, Schrittgröße, Rasterbetriebsmodus usw..

Beachten Sie, dass die ID des Bereichs nicht mit der HLSL-Untergrenzendeklaration verknüpft ist.

Die Reihenfolge der Reflektionsressourcenbindungen und Shaderdeklarationsanweisungen ist identisch, um die Übereinstimmung zwischen HLSL-Variablen und Bytecode-IDs zu identifizieren.

Jede Deklarationsanweisung in SM5.1 verwendet einen 3D-Operanden, um zu definieren: Bereichs-ID, Unter- und Obergrenze. Ein zusätzliches Token wird ausgegeben, um den Registrierungsraum anzugeben. Es können auch andere Token ausgegeben werden, um zusätzliche Eigenschaften des Bereichs zu übermitteln, z. B. die Anweisung cbuffer oder strukturierte Pufferdeklaration gibt die Größe des cbuffer oder der Struktur aus. Die genauen Details der Codierung finden Sie in d3d12TokenizedProgramFormat.h und D3D10ShaderBinary::CShaderCodeParser.

SM5.1-Anweisungen geben keine zusätzlichen Ressourcenoperndeninformationen als Teil der Anweisung aus (wie in SM5.0). Diese Informationen werden nun in die Deklarationsanweisungen verschoben. In SM5.0 mussten ressourcenindizierte Ressourcenattribute in erweiterten Opcodetoken beschrieben werden, da die Indizierung die Zuordnung zur Deklaration verschleierte. In SM5.1 ist jede ID (z. B. "t1") eindeutig einer einzelnen Deklaration zugeordnet, die die erforderlichen Ressourceninformationen beschreibt. Daher werden die erweiterten Opcodetoken, die in Anweisungen zum Beschreiben von Ressourceninformationen verwendet werden, nicht mehr ausgegeben.

In Anweisungen ohne Deklaration ist ein Ressourcenopernd für Sampler, SRVs und UAVs ein 2D-Operand. Der erste Index ist eine Literalkonstante, die die Bereichs-ID angibt. Der zweite Index stellt den linearisierten Wert des Indexes dar. Der Wert wird relativ zum Anfang des entsprechenden Registerbereichs (nicht relativ zum Anfang des logischen Bereichs) berechnet, um besser mit der Stammsignatur zu korrelieren und den Aufwand des Treibercompilers beim Anpassen des Indexes zu verringern.

Ein Ressourcenopernd für CBVs ist ein 3D-Operand: Literal-ID des Bereichs, Index des cbuffer, Offset in die jeweilige instance von cbuffer.

HLSL Shader Model 5.1 Features für Direct3D 12

Shadermodell 5.1