Modifiche di Bytecode in SM5.1
SM5.1 modifica il modo in cui i registri delle risorse vengono dichiarati e a cui si fa riferimento nelle istruzioni.
SM5.1 si sposta verso la dichiarazione di un registro "variabile", simile alla modalità di esecuzione per i registri di memoria condivisa del gruppo, illustrata nell'esempio seguente:
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;
}
Il disassembly di questo esempio segue:
// 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
Ogni intervallo di risorse shader ha ora un ID (un nome) nel bytecode shader. Ad esempio, la matrice trama tex1 diventa 't1' nel codice di byte shader. L'aggiunta di ID univoci a ogni intervallo di risorse consente due elementi:
- Identificare in modo ambiguo l'intervallo di risorse (vedere dcl_resource_texture2d) indicizzato in un'istruzione (vedere l'istruzione di esempio).
- Collegare set di attributi alla dichiarazione, ad esempio tipo di elemento, dimensioni stride, modalità di operazione raster e così via.
Si noti che l'ID dell'intervallo non è correlato alla dichiarazione con associazione inferiore HLSL.
L'ordine delle associazioni di risorse di reflection e le istruzioni di dichiarazione shader è lo stesso per facilitare l'identificazione della corrispondenza tra le variabili HLSL e gli ID bytecode.
Ogni istruzione di dichiarazione in SM5.1 usa un operando 3D per definire: ID intervallo, limiti inferiori e superiori. Viene generato un token aggiuntivo per specificare lo spazio di registrazione. Altri token possono essere generati anche per trasmettere proprietà aggiuntive dell'intervallo, ad esempio cbuffer o istruzioni di dichiarazione buffer strutturata generano le dimensioni della cbuffer o della struttura. I dettagli esatti della codifica sono disponibili in d3d12TokenizedProgramFormat.h e D3D10ShaderBinary::CShaderCodeParser.
Le istruzioni SM5.1 non generano informazioni aggiuntive sull'operando delle risorse come parte dell'istruzione (come in SM5.0). Queste informazioni vengono ora spostate nelle istruzioni di dichiarazione. In SM5.0 le istruzioni per l'indicizzazione delle risorse necessarie devono essere descritte nei token opcode estesi, poiché l'indicizzazione ha offuscato l'associazione alla dichiarazione. In SM5.1 ogni ID (ad esempio 't1') è associato senza ambiguità a una singola dichiarazione che descrive le informazioni necessarie sulla risorsa. Pertanto, i token opcode estesi usati sulle istruzioni per descrivere le informazioni sulle risorse non vengono più generati.
Nelle istruzioni non dichiaranti, un operando di risorsa per esempi, SRV e UAV è un operando 2D. Il primo indice è una costante letterale che specifica l'ID intervallo. Il secondo indice rappresenta il valore linearizzato dell'indice. Il valore viene calcolato rispetto all'inizio dello spazio di registrazione corrispondente (non relativo all'inizio dell'intervallo logico) per correlare meglio con la firma radice e ridurre il carico del compilatore del driver di regolare l'indice.
Un operando di risorsa per CBV è un operando 3D: ID letterale dell'intervallo, indice della cbuffer, offset nell'istanza specifica di cbuffer.
Argomenti correlati