1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
package shader
// DXBC (SM5.0) binary format constants.
// Subset needed for Luma shader compilation.
// Container magic
DXBC_MAGIC :: 0x43425844 // "DXBC" little-endian
// Chunk type identifiers
DXBC_CHUNK_RDEF :: 0x46454452 // "RDEF"
DXBC_CHUNK_ISGN :: 0x4E475349 // "ISGN"
DXBC_CHUNK_OSGN :: 0x4E47534F // "OSGN"
DXBC_CHUNK_SHEX :: 0x58454853 // "SHEX"
DXBC_CHUNK_STAT :: 0x54415453 // "STAT"
// Shader types for version token
DXBC_PROG_PIXEL :: 0
DXBC_PROG_VERTEX :: 1
DXBC_PROG_GEOMETRY :: 2
DXBC_PROG_HULL :: 3
DXBC_PROG_DOMAIN :: 4
DXBC_PROG_COMPUTE :: 5
// Build version token: (type << 16) | (major << 4) | minor
dxbc_version_token :: proc(prog_type: u32, major: u32 = 5, minor: u32 = 0) -> u32 {
return (prog_type << 16) | (major << 4) | minor
}
// ---- Opcodes ----
DXBC_OP_ADD :: 0
DXBC_OP_AND :: 1
DXBC_OP_BREAK :: 2
DXBC_OP_BREAKC :: 3
DXBC_OP_CALL :: 4
DXBC_OP_CALLC :: 5
DXBC_OP_CASE :: 6
DXBC_OP_CONTINUE :: 7
DXBC_OP_CONTINUEC :: 8
DXBC_OP_CUT :: 9
DXBC_OP_DEFAULT :: 10
DXBC_OP_DERIV_RTX :: 11
DXBC_OP_DERIV_RTY :: 12
DXBC_OP_DISCARD :: 13
DXBC_OP_DIV :: 14
DXBC_OP_DP2 :: 15
DXBC_OP_DP3 :: 16
DXBC_OP_DP4 :: 17
DXBC_OP_ELSE :: 18
DXBC_OP_EMIT :: 19
DXBC_OP_EMITTHENCUT :: 20
DXBC_OP_ENDIF :: 21
DXBC_OP_ENDLOOP :: 22
DXBC_OP_ENDSWITCH :: 23
DXBC_OP_EQ :: 24
DXBC_OP_EXP :: 25
DXBC_OP_FRC :: 26
DXBC_OP_FTOI :: 27
DXBC_OP_FTOU :: 28
DXBC_OP_GE :: 29
DXBC_OP_IADD :: 30
DXBC_OP_IF :: 31
DXBC_OP_IEQ :: 32
DXBC_OP_IGE :: 33
DXBC_OP_ILT :: 34
DXBC_OP_IMAD :: 35
DXBC_OP_IMAX :: 36
DXBC_OP_IMIN :: 37
DXBC_OP_IMUL :: 38
DXBC_OP_INE :: 39
DXBC_OP_INEG :: 40
DXBC_OP_ISHL :: 41
DXBC_OP_ISHR :: 42
DXBC_OP_ITOF :: 43
DXBC_OP_LABEL :: 44
DXBC_OP_LD :: 45
DXBC_OP_LD_MS :: 46
DXBC_OP_LOG :: 47
DXBC_OP_LOOP :: 48
DXBC_OP_LT :: 49
DXBC_OP_MAD :: 50
DXBC_OP_MIN :: 51
DXBC_OP_MAX :: 52
DXBC_OP_CUSTOMDATA :: 53
DXBC_OP_MOV :: 54
DXBC_OP_MOVC :: 55
DXBC_OP_MUL :: 56
DXBC_OP_NE :: 57
DXBC_OP_NOP :: 58
DXBC_OP_NOT :: 59
DXBC_OP_OR :: 60
DXBC_OP_RESINFO :: 61
DXBC_OP_RET :: 62
DXBC_OP_RETC :: 63
DXBC_OP_ROUND_NE :: 64
DXBC_OP_ROUND_NI :: 65
DXBC_OP_ROUND_PI :: 66
DXBC_OP_ROUND_Z :: 67
DXBC_OP_RSQ :: 68
DXBC_OP_SAMPLE :: 69
DXBC_OP_SAMPLE_C :: 70
DXBC_OP_SAMPLE_C_LZ :: 71
DXBC_OP_SAMPLE_L :: 72
DXBC_OP_SAMPLE_D :: 73
DXBC_OP_SAMPLE_B :: 74
DXBC_OP_SQRT :: 75
DXBC_OP_SWITCH :: 76
DXBC_OP_SINCOS :: 77
DXBC_OP_UDIV :: 78
DXBC_OP_ULT :: 79
DXBC_OP_UGE :: 80
DXBC_OP_UMUL :: 81
DXBC_OP_UMAD :: 82
DXBC_OP_UMAX :: 83
DXBC_OP_UMIN :: 84
DXBC_OP_USHR :: 85
DXBC_OP_UTOF :: 86
DXBC_OP_XOR :: 87
DXBC_OP_DCL_RESOURCE :: 88
DXBC_OP_DCL_CONSTANT_BUFFER :: 89
DXBC_OP_DCL_SAMPLER :: 90
DXBC_OP_DCL_INDEX_RANGE :: 91
DXBC_OP_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY :: 92
DXBC_OP_DCL_GS_INPUT_PRIMITIVE :: 93
DXBC_OP_DCL_MAX_OUTPUT_VERTEX_COUNT :: 94
DXBC_OP_DCL_INPUT :: 95
DXBC_OP_DCL_INPUT_SGV :: 96
DXBC_OP_DCL_INPUT_SIV :: 97
DXBC_OP_DCL_INPUT_PS :: 98
DXBC_OP_DCL_INPUT_PS_SGV :: 99
DXBC_OP_DCL_INPUT_PS_SIV :: 100
DXBC_OP_DCL_OUTPUT :: 101
DXBC_OP_DCL_OUTPUT_SGV :: 102
DXBC_OP_DCL_OUTPUT_SIV :: 103
DXBC_OP_DCL_TEMPS :: 104
DXBC_OP_DCL_INDEXABLE_TEMP :: 105
DXBC_OP_DCL_GLOBAL_FLAGS :: 106
// SM5.0 additions
DXBC_OP_DCL_THREAD_GROUP :: 155
DXBC_OP_DCL_UNORDERED_ACCESS_VIEW_TYPED :: 138
DXBC_OP_DCL_TGSM_RAW :: 159
DXBC_OP_DCL_TGSM_STRUCTURED :: 160
DXBC_OP_LD_STRUCTURED :: 161
DXBC_OP_STORE_STRUCTURED :: 173
DXBC_OP_SYNC :: 168
// ---- Operand types (bits 12-19 of operand token) ----
DXBC_OPERAND_TEMP :: 0
DXBC_OPERAND_INPUT :: 1
DXBC_OPERAND_OUTPUT :: 2
DXBC_OPERAND_INDEXABLE_TEMP :: 3
DXBC_OPERAND_IMMEDIATE32 :: 4
DXBC_OPERAND_IMMEDIATE64 :: 5
DXBC_OPERAND_SAMPLER :: 6
DXBC_OPERAND_RESOURCE :: 7
DXBC_OPERAND_CONSTANT_BUFFER :: 8
DXBC_OPERAND_IMMEDIATE_CONSTANT_BUFFER :: 9
DXBC_OPERAND_LABEL :: 10
DXBC_OPERAND_INPUT_PRIMITIVEID :: 11
DXBC_OPERAND_OUTPUT_DEPTH :: 12
DXBC_OPERAND_NULL :: 13
DXBC_OPERAND_OUTPUT_COVERAGE_MASK :: 14
DXBC_OPERAND_STREAM :: 15
DXBC_OPERAND_FUNCTION_BODY :: 16
DXBC_OPERAND_FUNCTION_TABLE :: 17
DXBC_OPERAND_INTERFACE :: 18
DXBC_OPERAND_FUNCTION_INPUT :: 19
DXBC_OPERAND_FUNCTION_OUTPUT :: 20
DXBC_OPERAND_OUTPUT_CONTROL_POINT_ID :: 21
DXBC_OPERAND_INPUT_FORK_INSTANCE_ID :: 22
DXBC_OPERAND_INPUT_JOIN_INSTANCE_ID :: 23
DXBC_OPERAND_INPUT_CONTROL_POINT :: 24
DXBC_OPERAND_OUTPUT_CONTROL_POINT :: 25
DXBC_OPERAND_INPUT_PATCH_CONSTANT :: 26
DXBC_OPERAND_INPUT_DOMAIN_POINT :: 27
DXBC_OPERAND_THIS_POINTER :: 28
DXBC_OPERAND_UNORDERED_ACCESS_VIEW :: 29
DXBC_OPERAND_THREAD_GROUP_SHARED_MEMORY :: 30
DXBC_OPERAND_INPUT_THREAD_ID :: 31
DXBC_OPERAND_INPUT_THREAD_GROUP_ID :: 32
DXBC_OPERAND_INPUT_THREAD_ID_IN_GROUP :: 33
DXBC_OPERAND_INPUT_COVERAGE_MASK :: 34
DXBC_OPERAND_INPUT_THREAD_ID_IN_GROUP_FLATTENED :: 35
// ---- Component selection modes (bits 2-3 of operand token) ----
DXBC_COMP_MASK :: 0 // destination: write mask in bits 4-7
DXBC_COMP_SWIZZLE :: 1 // source: component swizzle in bits 4-11
DXBC_COMP_SELECT_1 :: 2 // source: single component select in bits 4-5
// Component count (bits 0-1 of operand token)
DXBC_COMP_0 :: 0 // 0 components (e.g. label)
DXBC_COMP_1 :: 1 // 1 component (scalar)
DXBC_COMP_4 :: 2 // 4 components (vec4)
DXBC_COMP_N :: 3 // N components (rare)
// Swizzle component indices
DXBC_SWIZZLE_X :: 0
DXBC_SWIZZLE_Y :: 1
DXBC_SWIZZLE_Z :: 2
DXBC_SWIZZLE_W :: 3
// Component mask bits (for DXBC_COMP_MASK mode, bits 4-7)
DXBC_WRITEMASK_X :: 0x1
DXBC_WRITEMASK_Y :: 0x2
DXBC_WRITEMASK_Z :: 0x4
DXBC_WRITEMASK_W :: 0x8
DXBC_WRITEMASK_ALL :: 0xF
// Index dimensions (bits 20-21 of operand token)
DXBC_INDEX_0D :: 0 // no index (immediate)
DXBC_INDEX_1D :: 1 // one index (e.g. rN)
DXBC_INDEX_2D :: 2 // two indices (e.g. cbN[M])
DXBC_INDEX_3D :: 3 // three indices
// Index representation (bits 22-24 for dim0, bits 25-27 for dim1)
DXBC_INDEX_IMM32 :: 0
DXBC_INDEX_IMM64 :: 1
DXBC_INDEX_RELATIVE :: 2
DXBC_INDEX_IMM32_PLUS_RELATIVE :: 3
// ---- System values for ISGN/OSGN ----
DXBC_SV_UNDEFINED :: 0
DXBC_SV_POSITION :: 1
DXBC_SV_CLIP_DISTANCE :: 2
DXBC_SV_CULL_DISTANCE :: 3
DXBC_SV_RENDER_TARGET_ARRAY_INDEX :: 4
DXBC_SV_VIEWPORT_ARRAY_INDEX :: 5
DXBC_SV_VERTEX_ID :: 6
DXBC_SV_PRIMITIVE_ID :: 7
DXBC_SV_INSTANCE_ID :: 8
DXBC_SV_IS_FRONT_FACE :: 9
DXBC_SV_SAMPLE_INDEX :: 10
DXBC_SV_TARGET :: 0 // SV_Target uses system value 0 (undefined)
DXBC_SV_DEPTH :: 12
DXBC_SV_COVERAGE :: 13
// ---- Interpolation modes (for DCL_INPUT_PS) ----
DXBC_INTERPOLATION_UNDEFINED :: 0
DXBC_INTERPOLATION_CONSTANT :: 1
DXBC_INTERPOLATION_LINEAR :: 2
DXBC_INTERPOLATION_LINEAR_CENTROID :: 3
DXBC_INTERPOLATION_LINEAR_NOPERSPECTIVE :: 4
DXBC_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID :: 5
DXBC_INTERPOLATION_LINEAR_SAMPLE :: 6
DXBC_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE :: 7
// ---- Resource dimensions (for DCL_RESOURCE) ----
DXBC_RESOURCE_DIM_BUFFER :: 1
DXBC_RESOURCE_DIM_TEXTURE1D :: 2
DXBC_RESOURCE_DIM_TEXTURE2D :: 3
DXBC_RESOURCE_DIM_TEXTURE2DMS :: 4
DXBC_RESOURCE_DIM_TEXTURE3D :: 5
DXBC_RESOURCE_DIM_TEXTURECUBE :: 6
DXBC_RESOURCE_DIM_TEXTURE1DARRAY :: 7
DXBC_RESOURCE_DIM_TEXTURE2DARRAY :: 8
// Resource return type (for DCL_RESOURCE return type token)
DXBC_RETURN_TYPE_UNORM :: 1
DXBC_RETURN_TYPE_SNORM :: 2
DXBC_RETURN_TYPE_SINT :: 3
DXBC_RETURN_TYPE_UINT :: 4
DXBC_RETURN_TYPE_FLOAT :: 5
DXBC_RETURN_TYPE_MIXED :: 6
// ---- Sampler mode (for DCL_SAMPLER) ----
DXBC_SAMPLER_DEFAULT :: 0
DXBC_SAMPLER_COMPARISON :: 1
DXBC_SAMPLER_MONO :: 2
// ---- Constant buffer access pattern (for DCL_CONSTANT_BUFFER) ----
DXBC_CB_ACCESS_IMMEDIATE :: 0
DXBC_CB_ACCESS_DYNAMIC :: 1
// ---- Sync flags (for SYNC instruction) ----
DXBC_SYNC_THREADS_IN_GROUP :: 0x800
DXBC_SYNC_THREAD_GROUP_SHARED :: 0x400
DXBC_SYNC_UNORDERED_ACCESS_VIEW :: 0x200
// ---- Shader type flags for RDEF ----
DXBC_RDEF_SHADER_VS :: 0xFFFE
DXBC_RDEF_SHADER_PS :: 0xFFFF
DXBC_RDEF_SHADER_CS :: 0x4353 // "CS"
// ---- RDEF variable types ----
DXBC_SVT_VOID :: 0
DXBC_SVT_BOOL :: 1
DXBC_SVT_INT :: 2
DXBC_SVT_FLOAT :: 3
DXBC_SVT_UINT :: 19
DXBC_SVC_SCALAR :: 0
DXBC_SVC_VECTOR :: 1
DXBC_SVC_MATRIX_ROWS :: 2
DXBC_SVC_MATRIX_COLUMNS :: 3
// ---- Helpers for building operand tokens ----
dxbc_operand_token :: proc(comp_count: u32, sel_mode: u32, op_type: u32, index_dim: u32) -> u32 {
return comp_count | (sel_mode << 2) | (op_type << 12) | (index_dim << 20)
}
dxbc_mask_operand :: proc(op_type: u32, index_dim: u32, mask: u32) -> u32 {
return DXBC_COMP_4 | (DXBC_COMP_MASK << 2) | (u32(mask) << 4) | (op_type << 12) | (index_dim << 20)
}
dxbc_swizzle_operand :: proc(op_type: u32, index_dim: u32, swizzle: u32) -> u32 {
return DXBC_COMP_4 | (DXBC_COMP_SWIZZLE << 2) | (swizzle << 4) | (op_type << 12) | (index_dim << 20)
}
dxbc_select1_operand :: proc(op_type: u32, index_dim: u32, component: u32) -> u32 {
return DXBC_COMP_4 | (DXBC_COMP_SELECT_1 << 2) | (component << 4) | (op_type << 12) | (index_dim << 20)
}
dxbc_scalar_operand :: proc(op_type: u32, index_dim: u32) -> u32 {
return DXBC_COMP_1 | (op_type << 12) | (index_dim << 20)
}
// Build a swizzle value from 4 component indices (each 0-3)
dxbc_swizzle :: proc(x: u32 = 0, y: u32 = 1, z: u32 = 2, w: u32 = 3) -> u32 {
return x | (y << 2) | (z << 4) | (w << 6)
}
// Identity swizzle (.xyzw)
DXBC_SWIZZLE_IDENTITY :: u32(0) | (1 << 2) | (2 << 4) | (3 << 6) // x,y,z,w
// Replicate swizzle (e.g. .xxxx)
dxbc_swizzle_replicate :: proc(c: u32) -> u32 {
return c | (c << 2) | (c << 4) | (c << 6)
}
// Write mask from component count
dxbc_mask_from_count :: proc(count: int) -> u32 {
switch count {
case 1: return DXBC_WRITEMASK_X
case 2: return DXBC_WRITEMASK_X | DXBC_WRITEMASK_Y
case 3: return DXBC_WRITEMASK_X | DXBC_WRITEMASK_Y | DXBC_WRITEMASK_Z
case: return DXBC_WRITEMASK_ALL
}
}
// Index representation encoding in operand token
// dim0 rep goes in bits 22-24, dim1 rep in bits 25-27
dxbc_index_rep :: proc(dim0: u32, dim1: u32 = 0) -> u32 {
return (dim0 << 22) | (dim1 << 25)
}
// Opcode token: bits 0-10 = opcode, bits 24-30 = length
dxbc_opcode_token :: proc(opcode: u32, length: u32) -> u32 {
return (opcode & 0x7FF) | ((length & 0x7F) << 24)
}
// Opcode token with additional control bits in 12-23
dxbc_opcode_token_ex :: proc(opcode: u32, length: u32, control: u32) -> u32 {
return (opcode & 0x7FF) | ((control & 0xFFF) << 11) | ((length & 0x7F) << 24)
}