authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-14 17:02:51-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-05-14 17:02:51-04:00
log2dcec42b74cc0ae2bac5e5ef8a65955a55dca587
tree5e1c15838a561584e1013e4751bf7986388acea6
parent612ad779bb2df8e7e15ab20dd3df3a2900ff82f0
parent00428ac11b4d5b71ded1f9e572652ff52814f7b7
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8757 from Snektron/spirv-stuff

SPIR-V: Features + some other stuff

8 files changed, 2805 insertions(+), 236 deletions(-)

lib/std/target.zig+13-1
...@@ -431,6 +431,7 @@ pub const Target = struct {...@@ -431,6 +431,7 @@ pub const Target = struct {
431 pub const powerpc = @import("target/powerpc.zig");431 pub const powerpc = @import("target/powerpc.zig");
432 pub const riscv = @import("target/riscv.zig");432 pub const riscv = @import("target/riscv.zig");
433 pub const sparc = @import("target/sparc.zig");433 pub const sparc = @import("target/sparc.zig");
434 pub const spirv = @import("target/spirv.zig");
434 pub const systemz = @import("target/systemz.zig");435 pub const systemz = @import("target/systemz.zig");
435 pub const ve = @import("target/ve.zig");436 pub const ve = @import("target/ve.zig");
436 pub const wasm = @import("target/wasm.zig");437 pub const wasm = @import("target/wasm.zig");
...@@ -594,7 +595,7 @@ pub const Target = struct {...@@ -594,7 +595,7 @@ pub const Target = struct {
594 pub const Set = struct {595 pub const Set = struct {
595 ints: [usize_count]usize,596 ints: [usize_count]usize,
596597
597 pub const needed_bit_count = 172;598 pub const needed_bit_count = 288;
598 pub const byte_count = (needed_bit_count + 7) / 8;599 pub const byte_count = (needed_bit_count + 7) / 8;
599 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);600 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
600 pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));601 pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));
...@@ -822,6 +823,13 @@ pub const Target = struct {...@@ -822,6 +823,13 @@ pub const Target = struct {
822 };823 };
823 }824 }
824825
826 pub fn isSPIRV(arch: Arch) bool {
827 return switch (arch) {
828 .spirv32, .spirv64 => true,
829 else => false,
830 };
831 }
832
825 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {833 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
826 for (arch.allCpuModels()) |cpu| {834 for (arch.allCpuModels()) |cpu| {
827 if (mem.eql(u8, cpu_name, cpu.name)) {835 if (mem.eql(u8, cpu_name, cpu.name)) {
...@@ -1116,6 +1124,7 @@ pub const Target = struct {...@@ -1116,6 +1124,7 @@ pub const Target = struct {
1116 .amdgcn => &amdgpu.all_features,1124 .amdgcn => &amdgpu.all_features,
1117 .riscv32, .riscv64 => &riscv.all_features,1125 .riscv32, .riscv64 => &riscv.all_features,
1118 .sparc, .sparcv9, .sparcel => &sparc.all_features,1126 .sparc, .sparcv9, .sparcel => &sparc.all_features,
1127 .spirv32, .spirv64 => &spirv.all_features,
1119 .s390x => &systemz.all_features,1128 .s390x => &systemz.all_features,
1120 .i386, .x86_64 => &x86.all_features,1129 .i386, .x86_64 => &x86.all_features,
1121 .nvptx, .nvptx64 => &nvptx.all_features,1130 .nvptx, .nvptx64 => &nvptx.all_features,
...@@ -1324,6 +1333,9 @@ pub const Target = struct {...@@ -1324,6 +1333,9 @@ pub const Target = struct {
1324 if (cpu_arch.isWasm()) {1333 if (cpu_arch.isWasm()) {
1325 return .wasm;1334 return .wasm;
1326 }1335 }
1336 if (cpu_arch.isSPIRV()) {
1337 return .spirv;
1338 }
1327 return .elf;1339 return .elf;
1328 }1340 }
13291341
lib/std/target/spirv.zig created+2135
...@@ -0,0 +1,2135 @@
1//! This file is auto-generated by tools/update_spirv_features.zig.
2//! TODO: Dependencies of capabilities on extensions.
3//! TODO: Dependencies of extensions on extensions.
4//! TODO: Dependencies of extensions on versions.
5
6const std = @import("../std.zig");
7const CpuFeature = std.Target.Cpu.Feature;
8const CpuModel = std.Target.Cpu.Model;
9
10pub const Feature = enum {
11 v1_1,
12 v1_2,
13 v1_3,
14 v1_4,
15 v1_5,
16 SPV_AMD_shader_fragment_mask,
17 SPV_AMD_gpu_shader_int16,
18 SPV_AMD_gpu_shader_half_float,
19 SPV_AMD_texture_gather_bias_lod,
20 SPV_AMD_shader_ballot,
21 SPV_AMD_gcn_shader,
22 SPV_AMD_shader_image_load_store_lod,
23 SPV_AMD_shader_explicit_vertex_parameter,
24 SPV_AMD_shader_trinary_minmax,
25 SPV_AMD_gpu_shader_half_float_fetch,
26 SPV_GOOGLE_hlsl_functionality1,
27 SPV_GOOGLE_user_type,
28 SPV_GOOGLE_decorate_string,
29 SPV_EXT_demote_to_helper_invocation,
30 SPV_EXT_descriptor_indexing,
31 SPV_EXT_fragment_fully_covered,
32 SPV_EXT_shader_stencil_export,
33 SPV_EXT_physical_storage_buffer,
34 SPV_EXT_shader_atomic_float_add,
35 SPV_EXT_shader_atomic_float_min_max,
36 SPV_EXT_shader_image_int64,
37 SPV_EXT_fragment_shader_interlock,
38 SPV_EXT_fragment_invocation_density,
39 SPV_EXT_shader_viewport_index_layer,
40 SPV_INTEL_loop_fuse,
41 SPV_INTEL_fpga_dsp_control,
42 SPV_INTEL_fpga_reg,
43 SPV_INTEL_fpga_memory_accesses,
44 SPV_INTEL_fpga_loop_controls,
45 SPV_INTEL_io_pipes,
46 SPV_INTEL_unstructured_loop_controls,
47 SPV_INTEL_blocking_pipes,
48 SPV_INTEL_device_side_avc_motion_estimation,
49 SPV_INTEL_fpga_memory_attributes,
50 SPV_INTEL_fp_fast_math_mode,
51 SPV_INTEL_media_block_io,
52 SPV_INTEL_shader_integer_functions2,
53 SPV_INTEL_subgroups,
54 SPV_INTEL_fpga_cluster_attributes,
55 SPV_INTEL_kernel_attributes,
56 SPV_INTEL_arbitrary_precision_integers,
57 SPV_KHR_8bit_storage,
58 SPV_KHR_shader_clock,
59 SPV_KHR_device_group,
60 SPV_KHR_16bit_storage,
61 SPV_KHR_variable_pointers,
62 SPV_KHR_no_integer_wrap_decoration,
63 SPV_KHR_subgroup_vote,
64 SPV_KHR_multiview,
65 SPV_KHR_shader_ballot,
66 SPV_KHR_vulkan_memory_model,
67 SPV_KHR_physical_storage_buffer,
68 SPV_KHR_workgroup_memory_explicit_layout,
69 SPV_KHR_fragment_shading_rate,
70 SPV_KHR_shader_atomic_counter_ops,
71 SPV_KHR_shader_draw_parameters,
72 SPV_KHR_storage_buffer_storage_class,
73 SPV_KHR_linkonce_odr,
74 SPV_KHR_terminate_invocation,
75 SPV_KHR_non_semantic_info,
76 SPV_KHR_post_depth_coverage,
77 SPV_KHR_expect_assume,
78 SPV_KHR_ray_tracing,
79 SPV_KHR_ray_query,
80 SPV_KHR_float_controls,
81 SPV_NV_viewport_array2,
82 SPV_NV_shader_subgroup_partitioned,
83 SPV_NVX_multiview_per_view_attributes,
84 SPV_NV_ray_tracing,
85 SPV_NV_shader_image_footprint,
86 SPV_NV_shading_rate,
87 SPV_NV_stereo_view_rendering,
88 SPV_NV_compute_shader_derivatives,
89 SPV_NV_shader_sm_builtins,
90 SPV_NV_mesh_shader,
91 SPV_NV_geometry_shader_passthrough,
92 SPV_NV_fragment_shader_barycentric,
93 SPV_NV_cooperative_matrix,
94 SPV_NV_sample_mask_override_coverage,
95 Matrix,
96 Shader,
97 Geometry,
98 Tessellation,
99 Addresses,
100 Linkage,
101 Kernel,
102 Vector16,
103 Float16Buffer,
104 Float16,
105 Float64,
106 Int64,
107 Int64Atomics,
108 ImageBasic,
109 ImageReadWrite,
110 ImageMipmap,
111 Pipes,
112 Groups,
113 DeviceEnqueue,
114 LiteralSampler,
115 AtomicStorage,
116 Int16,
117 TessellationPointSize,
118 GeometryPointSize,
119 ImageGatherExtended,
120 StorageImageMultisample,
121 UniformBufferArrayDynamicIndexing,
122 SampledImageArrayDynamicIndexing,
123 StorageBufferArrayDynamicIndexing,
124 StorageImageArrayDynamicIndexing,
125 ClipDistance,
126 CullDistance,
127 ImageCubeArray,
128 SampleRateShading,
129 ImageRect,
130 SampledRect,
131 GenericPointer,
132 Int8,
133 InputAttachment,
134 SparseResidency,
135 MinLod,
136 Sampled1D,
137 Image1D,
138 SampledCubeArray,
139 SampledBuffer,
140 ImageBuffer,
141 ImageMSArray,
142 StorageImageExtendedFormats,
143 ImageQuery,
144 DerivativeControl,
145 InterpolationFunction,
146 TransformFeedback,
147 GeometryStreams,
148 StorageImageReadWithoutFormat,
149 StorageImageWriteWithoutFormat,
150 MultiViewport,
151 SubgroupDispatch,
152 NamedBarrier,
153 PipeStorage,
154 GroupNonUniform,
155 GroupNonUniformVote,
156 GroupNonUniformArithmetic,
157 GroupNonUniformBallot,
158 GroupNonUniformShuffle,
159 GroupNonUniformShuffleRelative,
160 GroupNonUniformClustered,
161 GroupNonUniformQuad,
162 ShaderLayer,
163 ShaderViewportIndex,
164 FragmentShadingRateKHR,
165 SubgroupBallotKHR,
166 DrawParameters,
167 WorkgroupMemoryExplicitLayoutKHR,
168 WorkgroupMemoryExplicitLayout8BitAccessKHR,
169 WorkgroupMemoryExplicitLayout16BitAccessKHR,
170 SubgroupVoteKHR,
171 StorageBuffer16BitAccess,
172 StorageUniformBufferBlock16,
173 UniformAndStorageBuffer16BitAccess,
174 StorageUniform16,
175 StoragePushConstant16,
176 StorageInputOutput16,
177 DeviceGroup,
178 MultiView,
179 VariablePointersStorageBuffer,
180 VariablePointers,
181 AtomicStorageOps,
182 SampleMaskPostDepthCoverage,
183 StorageBuffer8BitAccess,
184 UniformAndStorageBuffer8BitAccess,
185 StoragePushConstant8,
186 DenormPreserve,
187 DenormFlushToZero,
188 SignedZeroInfNanPreserve,
189 RoundingModeRTE,
190 RoundingModeRTZ,
191 RayQueryProvisionalKHR,
192 RayQueryKHR,
193 RayTraversalPrimitiveCullingKHR,
194 RayTracingKHR,
195 Float16ImageAMD,
196 ImageGatherBiasLodAMD,
197 FragmentMaskAMD,
198 StencilExportEXT,
199 ImageReadWriteLodAMD,
200 Int64ImageEXT,
201 ShaderClockKHR,
202 SampleMaskOverrideCoverageNV,
203 GeometryShaderPassthroughNV,
204 ShaderViewportIndexLayerEXT,
205 ShaderViewportIndexLayerNV,
206 ShaderViewportMaskNV,
207 ShaderStereoViewNV,
208 PerViewAttributesNV,
209 FragmentFullyCoveredEXT,
210 MeshShadingNV,
211 ImageFootprintNV,
212 FragmentBarycentricNV,
213 ComputeDerivativeGroupQuadsNV,
214 FragmentDensityEXT,
215 ShadingRateNV,
216 GroupNonUniformPartitionedNV,
217 ShaderNonUniform,
218 ShaderNonUniformEXT,
219 RuntimeDescriptorArray,
220 RuntimeDescriptorArrayEXT,
221 InputAttachmentArrayDynamicIndexing,
222 InputAttachmentArrayDynamicIndexingEXT,
223 UniformTexelBufferArrayDynamicIndexing,
224 UniformTexelBufferArrayDynamicIndexingEXT,
225 StorageTexelBufferArrayDynamicIndexing,
226 StorageTexelBufferArrayDynamicIndexingEXT,
227 UniformBufferArrayNonUniformIndexing,
228 UniformBufferArrayNonUniformIndexingEXT,
229 SampledImageArrayNonUniformIndexing,
230 SampledImageArrayNonUniformIndexingEXT,
231 StorageBufferArrayNonUniformIndexing,
232 StorageBufferArrayNonUniformIndexingEXT,
233 StorageImageArrayNonUniformIndexing,
234 StorageImageArrayNonUniformIndexingEXT,
235 InputAttachmentArrayNonUniformIndexing,
236 InputAttachmentArrayNonUniformIndexingEXT,
237 UniformTexelBufferArrayNonUniformIndexing,
238 UniformTexelBufferArrayNonUniformIndexingEXT,
239 StorageTexelBufferArrayNonUniformIndexing,
240 StorageTexelBufferArrayNonUniformIndexingEXT,
241 RayTracingNV,
242 VulkanMemoryModel,
243 VulkanMemoryModelKHR,
244 VulkanMemoryModelDeviceScope,
245 VulkanMemoryModelDeviceScopeKHR,
246 PhysicalStorageBufferAddresses,
247 PhysicalStorageBufferAddressesEXT,
248 ComputeDerivativeGroupLinearNV,
249 RayTracingProvisionalKHR,
250 CooperativeMatrixNV,
251 FragmentShaderSampleInterlockEXT,
252 FragmentShaderShadingRateInterlockEXT,
253 ShaderSMBuiltinsNV,
254 FragmentShaderPixelInterlockEXT,
255 DemoteToHelperInvocationEXT,
256 SubgroupShuffleINTEL,
257 SubgroupBufferBlockIOINTEL,
258 SubgroupImageBlockIOINTEL,
259 SubgroupImageMediaBlockIOINTEL,
260 RoundToInfinityINTEL,
261 FloatingPointModeINTEL,
262 IntegerFunctions2INTEL,
263 FunctionPointersINTEL,
264 IndirectReferencesINTEL,
265 AsmINTEL,
266 AtomicFloat32MinMaxEXT,
267 AtomicFloat64MinMaxEXT,
268 AtomicFloat16MinMaxEXT,
269 VectorComputeINTEL,
270 VectorAnyINTEL,
271 ExpectAssumeKHR,
272 SubgroupAvcMotionEstimationINTEL,
273 SubgroupAvcMotionEstimationIntraINTEL,
274 SubgroupAvcMotionEstimationChromaINTEL,
275 VariableLengthArrayINTEL,
276 FunctionFloatControlINTEL,
277 FPGAMemoryAttributesINTEL,
278 FPFastMathModeINTEL,
279 ArbitraryPrecisionIntegersINTEL,
280 UnstructuredLoopControlsINTEL,
281 FPGALoopControlsINTEL,
282 KernelAttributesINTEL,
283 FPGAKernelAttributesINTEL,
284 FPGAMemoryAccessesINTEL,
285 FPGAClusterAttributesINTEL,
286 LoopFuseINTEL,
287 FPGABufferLocationINTEL,
288 USMStorageClassesINTEL,
289 IOPipesINTEL,
290 BlockingPipesINTEL,
291 FPGARegINTEL,
292 AtomicFloat32AddEXT,
293 AtomicFloat64AddEXT,
294 LongConstantCompositeINTEL,
295};
296
297pub usingnamespace CpuFeature.feature_set_fns(Feature);
298
299pub const all_features = blk: {
300 @setEvalBranchQuota(2000);
301 const len = @typeInfo(Feature).Enum.fields.len;
302 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
303 var result: [len]CpuFeature = undefined;
304 result[@enumToInt(Feature.v1_1)] = .{
305 .llvm_name = null,
306 .description = "SPIR-V version 1.1",
307 .dependencies = featureSet(&[_]Feature{}),
308 };
309 result[@enumToInt(Feature.v1_2)] = .{
310 .llvm_name = null,
311 .description = "SPIR-V version 1.2",
312 .dependencies = featureSet(&[_]Feature{
313 .v1_1,
314 }),
315 };
316 result[@enumToInt(Feature.v1_3)] = .{
317 .llvm_name = null,
318 .description = "SPIR-V version 1.3",
319 .dependencies = featureSet(&[_]Feature{
320 .v1_2,
321 }),
322 };
323 result[@enumToInt(Feature.v1_4)] = .{
324 .llvm_name = null,
325 .description = "SPIR-V version 1.4",
326 .dependencies = featureSet(&[_]Feature{
327 .v1_3,
328 }),
329 };
330 result[@enumToInt(Feature.v1_5)] = .{
331 .llvm_name = null,
332 .description = "SPIR-V version 1.5",
333 .dependencies = featureSet(&[_]Feature{
334 .v1_4,
335 }),
336 };
337 result[@enumToInt(Feature.SPV_AMD_shader_fragment_mask)] = .{
338 .llvm_name = null,
339 .description = "SPIR-V extension SPV_AMD_shader_fragment_mask",
340 .dependencies = featureSet(&[_]Feature{}),
341 };
342 result[@enumToInt(Feature.SPV_AMD_gpu_shader_int16)] = .{
343 .llvm_name = null,
344 .description = "SPIR-V extension SPV_AMD_gpu_shader_int16",
345 .dependencies = featureSet(&[_]Feature{}),
346 };
347 result[@enumToInt(Feature.SPV_AMD_gpu_shader_half_float)] = .{
348 .llvm_name = null,
349 .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float",
350 .dependencies = featureSet(&[_]Feature{}),
351 };
352 result[@enumToInt(Feature.SPV_AMD_texture_gather_bias_lod)] = .{
353 .llvm_name = null,
354 .description = "SPIR-V extension SPV_AMD_texture_gather_bias_lod",
355 .dependencies = featureSet(&[_]Feature{}),
356 };
357 result[@enumToInt(Feature.SPV_AMD_shader_ballot)] = .{
358 .llvm_name = null,
359 .description = "SPIR-V extension SPV_AMD_shader_ballot",
360 .dependencies = featureSet(&[_]Feature{}),
361 };
362 result[@enumToInt(Feature.SPV_AMD_gcn_shader)] = .{
363 .llvm_name = null,
364 .description = "SPIR-V extension SPV_AMD_gcn_shader",
365 .dependencies = featureSet(&[_]Feature{}),
366 };
367 result[@enumToInt(Feature.SPV_AMD_shader_image_load_store_lod)] = .{
368 .llvm_name = null,
369 .description = "SPIR-V extension SPV_AMD_shader_image_load_store_lod",
370 .dependencies = featureSet(&[_]Feature{}),
371 };
372 result[@enumToInt(Feature.SPV_AMD_shader_explicit_vertex_parameter)] = .{
373 .llvm_name = null,
374 .description = "SPIR-V extension SPV_AMD_shader_explicit_vertex_parameter",
375 .dependencies = featureSet(&[_]Feature{}),
376 };
377 result[@enumToInt(Feature.SPV_AMD_shader_trinary_minmax)] = .{
378 .llvm_name = null,
379 .description = "SPIR-V extension SPV_AMD_shader_trinary_minmax",
380 .dependencies = featureSet(&[_]Feature{}),
381 };
382 result[@enumToInt(Feature.SPV_AMD_gpu_shader_half_float_fetch)] = .{
383 .llvm_name = null,
384 .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float_fetch",
385 .dependencies = featureSet(&[_]Feature{}),
386 };
387 result[@enumToInt(Feature.SPV_GOOGLE_hlsl_functionality1)] = .{
388 .llvm_name = null,
389 .description = "SPIR-V extension SPV_GOOGLE_hlsl_functionality1",
390 .dependencies = featureSet(&[_]Feature{}),
391 };
392 result[@enumToInt(Feature.SPV_GOOGLE_user_type)] = .{
393 .llvm_name = null,
394 .description = "SPIR-V extension SPV_GOOGLE_user_type",
395 .dependencies = featureSet(&[_]Feature{}),
396 };
397 result[@enumToInt(Feature.SPV_GOOGLE_decorate_string)] = .{
398 .llvm_name = null,
399 .description = "SPIR-V extension SPV_GOOGLE_decorate_string",
400 .dependencies = featureSet(&[_]Feature{}),
401 };
402 result[@enumToInt(Feature.SPV_EXT_demote_to_helper_invocation)] = .{
403 .llvm_name = null,
404 .description = "SPIR-V extension SPV_EXT_demote_to_helper_invocation",
405 .dependencies = featureSet(&[_]Feature{}),
406 };
407 result[@enumToInt(Feature.SPV_EXT_descriptor_indexing)] = .{
408 .llvm_name = null,
409 .description = "SPIR-V extension SPV_EXT_descriptor_indexing",
410 .dependencies = featureSet(&[_]Feature{}),
411 };
412 result[@enumToInt(Feature.SPV_EXT_fragment_fully_covered)] = .{
413 .llvm_name = null,
414 .description = "SPIR-V extension SPV_EXT_fragment_fully_covered",
415 .dependencies = featureSet(&[_]Feature{}),
416 };
417 result[@enumToInt(Feature.SPV_EXT_shader_stencil_export)] = .{
418 .llvm_name = null,
419 .description = "SPIR-V extension SPV_EXT_shader_stencil_export",
420 .dependencies = featureSet(&[_]Feature{}),
421 };
422 result[@enumToInt(Feature.SPV_EXT_physical_storage_buffer)] = .{
423 .llvm_name = null,
424 .description = "SPIR-V extension SPV_EXT_physical_storage_buffer",
425 .dependencies = featureSet(&[_]Feature{}),
426 };
427 result[@enumToInt(Feature.SPV_EXT_shader_atomic_float_add)] = .{
428 .llvm_name = null,
429 .description = "SPIR-V extension SPV_EXT_shader_atomic_float_add",
430 .dependencies = featureSet(&[_]Feature{}),
431 };
432 result[@enumToInt(Feature.SPV_EXT_shader_atomic_float_min_max)] = .{
433 .llvm_name = null,
434 .description = "SPIR-V extension SPV_EXT_shader_atomic_float_min_max",
435 .dependencies = featureSet(&[_]Feature{}),
436 };
437 result[@enumToInt(Feature.SPV_EXT_shader_image_int64)] = .{
438 .llvm_name = null,
439 .description = "SPIR-V extension SPV_EXT_shader_image_int64",
440 .dependencies = featureSet(&[_]Feature{}),
441 };
442 result[@enumToInt(Feature.SPV_EXT_fragment_shader_interlock)] = .{
443 .llvm_name = null,
444 .description = "SPIR-V extension SPV_EXT_fragment_shader_interlock",
445 .dependencies = featureSet(&[_]Feature{}),
446 };
447 result[@enumToInt(Feature.SPV_EXT_fragment_invocation_density)] = .{
448 .llvm_name = null,
449 .description = "SPIR-V extension SPV_EXT_fragment_invocation_density",
450 .dependencies = featureSet(&[_]Feature{}),
451 };
452 result[@enumToInt(Feature.SPV_EXT_shader_viewport_index_layer)] = .{
453 .llvm_name = null,
454 .description = "SPIR-V extension SPV_EXT_shader_viewport_index_layer",
455 .dependencies = featureSet(&[_]Feature{}),
456 };
457 result[@enumToInt(Feature.SPV_INTEL_loop_fuse)] = .{
458 .llvm_name = null,
459 .description = "SPIR-V extension SPV_INTEL_loop_fuse",
460 .dependencies = featureSet(&[_]Feature{}),
461 };
462 result[@enumToInt(Feature.SPV_INTEL_fpga_dsp_control)] = .{
463 .llvm_name = null,
464 .description = "SPIR-V extension SPV_INTEL_fpga_dsp_control",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@enumToInt(Feature.SPV_INTEL_fpga_reg)] = .{
468 .llvm_name = null,
469 .description = "SPIR-V extension SPV_INTEL_fpga_reg",
470 .dependencies = featureSet(&[_]Feature{}),
471 };
472 result[@enumToInt(Feature.SPV_INTEL_fpga_memory_accesses)] = .{
473 .llvm_name = null,
474 .description = "SPIR-V extension SPV_INTEL_fpga_memory_accesses",
475 .dependencies = featureSet(&[_]Feature{}),
476 };
477 result[@enumToInt(Feature.SPV_INTEL_fpga_loop_controls)] = .{
478 .llvm_name = null,
479 .description = "SPIR-V extension SPV_INTEL_fpga_loop_controls",
480 .dependencies = featureSet(&[_]Feature{}),
481 };
482 result[@enumToInt(Feature.SPV_INTEL_io_pipes)] = .{
483 .llvm_name = null,
484 .description = "SPIR-V extension SPV_INTEL_io_pipes",
485 .dependencies = featureSet(&[_]Feature{}),
486 };
487 result[@enumToInt(Feature.SPV_INTEL_unstructured_loop_controls)] = .{
488 .llvm_name = null,
489 .description = "SPIR-V extension SPV_INTEL_unstructured_loop_controls",
490 .dependencies = featureSet(&[_]Feature{}),
491 };
492 result[@enumToInt(Feature.SPV_INTEL_blocking_pipes)] = .{
493 .llvm_name = null,
494 .description = "SPIR-V extension SPV_INTEL_blocking_pipes",
495 .dependencies = featureSet(&[_]Feature{}),
496 };
497 result[@enumToInt(Feature.SPV_INTEL_device_side_avc_motion_estimation)] = .{
498 .llvm_name = null,
499 .description = "SPIR-V extension SPV_INTEL_device_side_avc_motion_estimation",
500 .dependencies = featureSet(&[_]Feature{}),
501 };
502 result[@enumToInt(Feature.SPV_INTEL_fpga_memory_attributes)] = .{
503 .llvm_name = null,
504 .description = "SPIR-V extension SPV_INTEL_fpga_memory_attributes",
505 .dependencies = featureSet(&[_]Feature{}),
506 };
507 result[@enumToInt(Feature.SPV_INTEL_fp_fast_math_mode)] = .{
508 .llvm_name = null,
509 .description = "SPIR-V extension SPV_INTEL_fp_fast_math_mode",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@enumToInt(Feature.SPV_INTEL_media_block_io)] = .{
513 .llvm_name = null,
514 .description = "SPIR-V extension SPV_INTEL_media_block_io",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@enumToInt(Feature.SPV_INTEL_shader_integer_functions2)] = .{
518 .llvm_name = null,
519 .description = "SPIR-V extension SPV_INTEL_shader_integer_functions2",
520 .dependencies = featureSet(&[_]Feature{}),
521 };
522 result[@enumToInt(Feature.SPV_INTEL_subgroups)] = .{
523 .llvm_name = null,
524 .description = "SPIR-V extension SPV_INTEL_subgroups",
525 .dependencies = featureSet(&[_]Feature{}),
526 };
527 result[@enumToInt(Feature.SPV_INTEL_fpga_cluster_attributes)] = .{
528 .llvm_name = null,
529 .description = "SPIR-V extension SPV_INTEL_fpga_cluster_attributes",
530 .dependencies = featureSet(&[_]Feature{}),
531 };
532 result[@enumToInt(Feature.SPV_INTEL_kernel_attributes)] = .{
533 .llvm_name = null,
534 .description = "SPIR-V extension SPV_INTEL_kernel_attributes",
535 .dependencies = featureSet(&[_]Feature{}),
536 };
537 result[@enumToInt(Feature.SPV_INTEL_arbitrary_precision_integers)] = .{
538 .llvm_name = null,
539 .description = "SPIR-V extension SPV_INTEL_arbitrary_precision_integers",
540 .dependencies = featureSet(&[_]Feature{}),
541 };
542 result[@enumToInt(Feature.SPV_KHR_8bit_storage)] = .{
543 .llvm_name = null,
544 .description = "SPIR-V extension SPV_KHR_8bit_storage",
545 .dependencies = featureSet(&[_]Feature{}),
546 };
547 result[@enumToInt(Feature.SPV_KHR_shader_clock)] = .{
548 .llvm_name = null,
549 .description = "SPIR-V extension SPV_KHR_shader_clock",
550 .dependencies = featureSet(&[_]Feature{}),
551 };
552 result[@enumToInt(Feature.SPV_KHR_device_group)] = .{
553 .llvm_name = null,
554 .description = "SPIR-V extension SPV_KHR_device_group",
555 .dependencies = featureSet(&[_]Feature{}),
556 };
557 result[@enumToInt(Feature.SPV_KHR_16bit_storage)] = .{
558 .llvm_name = null,
559 .description = "SPIR-V extension SPV_KHR_16bit_storage",
560 .dependencies = featureSet(&[_]Feature{}),
561 };
562 result[@enumToInt(Feature.SPV_KHR_variable_pointers)] = .{
563 .llvm_name = null,
564 .description = "SPIR-V extension SPV_KHR_variable_pointers",
565 .dependencies = featureSet(&[_]Feature{}),
566 };
567 result[@enumToInt(Feature.SPV_KHR_no_integer_wrap_decoration)] = .{
568 .llvm_name = null,
569 .description = "SPIR-V extension SPV_KHR_no_integer_wrap_decoration",
570 .dependencies = featureSet(&[_]Feature{}),
571 };
572 result[@enumToInt(Feature.SPV_KHR_subgroup_vote)] = .{
573 .llvm_name = null,
574 .description = "SPIR-V extension SPV_KHR_subgroup_vote",
575 .dependencies = featureSet(&[_]Feature{}),
576 };
577 result[@enumToInt(Feature.SPV_KHR_multiview)] = .{
578 .llvm_name = null,
579 .description = "SPIR-V extension SPV_KHR_multiview",
580 .dependencies = featureSet(&[_]Feature{}),
581 };
582 result[@enumToInt(Feature.SPV_KHR_shader_ballot)] = .{
583 .llvm_name = null,
584 .description = "SPIR-V extension SPV_KHR_shader_ballot",
585 .dependencies = featureSet(&[_]Feature{}),
586 };
587 result[@enumToInt(Feature.SPV_KHR_vulkan_memory_model)] = .{
588 .llvm_name = null,
589 .description = "SPIR-V extension SPV_KHR_vulkan_memory_model",
590 .dependencies = featureSet(&[_]Feature{}),
591 };
592 result[@enumToInt(Feature.SPV_KHR_physical_storage_buffer)] = .{
593 .llvm_name = null,
594 .description = "SPIR-V extension SPV_KHR_physical_storage_buffer",
595 .dependencies = featureSet(&[_]Feature{}),
596 };
597 result[@enumToInt(Feature.SPV_KHR_workgroup_memory_explicit_layout)] = .{
598 .llvm_name = null,
599 .description = "SPIR-V extension SPV_KHR_workgroup_memory_explicit_layout",
600 .dependencies = featureSet(&[_]Feature{}),
601 };
602 result[@enumToInt(Feature.SPV_KHR_fragment_shading_rate)] = .{
603 .llvm_name = null,
604 .description = "SPIR-V extension SPV_KHR_fragment_shading_rate",
605 .dependencies = featureSet(&[_]Feature{}),
606 };
607 result[@enumToInt(Feature.SPV_KHR_shader_atomic_counter_ops)] = .{
608 .llvm_name = null,
609 .description = "SPIR-V extension SPV_KHR_shader_atomic_counter_ops",
610 .dependencies = featureSet(&[_]Feature{}),
611 };
612 result[@enumToInt(Feature.SPV_KHR_shader_draw_parameters)] = .{
613 .llvm_name = null,
614 .description = "SPIR-V extension SPV_KHR_shader_draw_parameters",
615 .dependencies = featureSet(&[_]Feature{}),
616 };
617 result[@enumToInt(Feature.SPV_KHR_storage_buffer_storage_class)] = .{
618 .llvm_name = null,
619 .description = "SPIR-V extension SPV_KHR_storage_buffer_storage_class",
620 .dependencies = featureSet(&[_]Feature{}),
621 };
622 result[@enumToInt(Feature.SPV_KHR_linkonce_odr)] = .{
623 .llvm_name = null,
624 .description = "SPIR-V extension SPV_KHR_linkonce_odr",
625 .dependencies = featureSet(&[_]Feature{}),
626 };
627 result[@enumToInt(Feature.SPV_KHR_terminate_invocation)] = .{
628 .llvm_name = null,
629 .description = "SPIR-V extension SPV_KHR_terminate_invocation",
630 .dependencies = featureSet(&[_]Feature{}),
631 };
632 result[@enumToInt(Feature.SPV_KHR_non_semantic_info)] = .{
633 .llvm_name = null,
634 .description = "SPIR-V extension SPV_KHR_non_semantic_info",
635 .dependencies = featureSet(&[_]Feature{}),
636 };
637 result[@enumToInt(Feature.SPV_KHR_post_depth_coverage)] = .{
638 .llvm_name = null,
639 .description = "SPIR-V extension SPV_KHR_post_depth_coverage",
640 .dependencies = featureSet(&[_]Feature{}),
641 };
642 result[@enumToInt(Feature.SPV_KHR_expect_assume)] = .{
643 .llvm_name = null,
644 .description = "SPIR-V extension SPV_KHR_expect_assume",
645 .dependencies = featureSet(&[_]Feature{}),
646 };
647 result[@enumToInt(Feature.SPV_KHR_ray_tracing)] = .{
648 .llvm_name = null,
649 .description = "SPIR-V extension SPV_KHR_ray_tracing",
650 .dependencies = featureSet(&[_]Feature{}),
651 };
652 result[@enumToInt(Feature.SPV_KHR_ray_query)] = .{
653 .llvm_name = null,
654 .description = "SPIR-V extension SPV_KHR_ray_query",
655 .dependencies = featureSet(&[_]Feature{}),
656 };
657 result[@enumToInt(Feature.SPV_KHR_float_controls)] = .{
658 .llvm_name = null,
659 .description = "SPIR-V extension SPV_KHR_float_controls",
660 .dependencies = featureSet(&[_]Feature{}),
661 };
662 result[@enumToInt(Feature.SPV_NV_viewport_array2)] = .{
663 .llvm_name = null,
664 .description = "SPIR-V extension SPV_NV_viewport_array2",
665 .dependencies = featureSet(&[_]Feature{}),
666 };
667 result[@enumToInt(Feature.SPV_NV_shader_subgroup_partitioned)] = .{
668 .llvm_name = null,
669 .description = "SPIR-V extension SPV_NV_shader_subgroup_partitioned",
670 .dependencies = featureSet(&[_]Feature{}),
671 };
672 result[@enumToInt(Feature.SPV_NVX_multiview_per_view_attributes)] = .{
673 .llvm_name = null,
674 .description = "SPIR-V extension SPV_NVX_multiview_per_view_attributes",
675 .dependencies = featureSet(&[_]Feature{}),
676 };
677 result[@enumToInt(Feature.SPV_NV_ray_tracing)] = .{
678 .llvm_name = null,
679 .description = "SPIR-V extension SPV_NV_ray_tracing",
680 .dependencies = featureSet(&[_]Feature{}),
681 };
682 result[@enumToInt(Feature.SPV_NV_shader_image_footprint)] = .{
683 .llvm_name = null,
684 .description = "SPIR-V extension SPV_NV_shader_image_footprint",
685 .dependencies = featureSet(&[_]Feature{}),
686 };
687 result[@enumToInt(Feature.SPV_NV_shading_rate)] = .{
688 .llvm_name = null,
689 .description = "SPIR-V extension SPV_NV_shading_rate",
690 .dependencies = featureSet(&[_]Feature{}),
691 };
692 result[@enumToInt(Feature.SPV_NV_stereo_view_rendering)] = .{
693 .llvm_name = null,
694 .description = "SPIR-V extension SPV_NV_stereo_view_rendering",
695 .dependencies = featureSet(&[_]Feature{}),
696 };
697 result[@enumToInt(Feature.SPV_NV_compute_shader_derivatives)] = .{
698 .llvm_name = null,
699 .description = "SPIR-V extension SPV_NV_compute_shader_derivatives",
700 .dependencies = featureSet(&[_]Feature{}),
701 };
702 result[@enumToInt(Feature.SPV_NV_shader_sm_builtins)] = .{
703 .llvm_name = null,
704 .description = "SPIR-V extension SPV_NV_shader_sm_builtins",
705 .dependencies = featureSet(&[_]Feature{}),
706 };
707 result[@enumToInt(Feature.SPV_NV_mesh_shader)] = .{
708 .llvm_name = null,
709 .description = "SPIR-V extension SPV_NV_mesh_shader",
710 .dependencies = featureSet(&[_]Feature{}),
711 };
712 result[@enumToInt(Feature.SPV_NV_geometry_shader_passthrough)] = .{
713 .llvm_name = null,
714 .description = "SPIR-V extension SPV_NV_geometry_shader_passthrough",
715 .dependencies = featureSet(&[_]Feature{}),
716 };
717 result[@enumToInt(Feature.SPV_NV_fragment_shader_barycentric)] = .{
718 .llvm_name = null,
719 .description = "SPIR-V extension SPV_NV_fragment_shader_barycentric",
720 .dependencies = featureSet(&[_]Feature{}),
721 };
722 result[@enumToInt(Feature.SPV_NV_cooperative_matrix)] = .{
723 .llvm_name = null,
724 .description = "SPIR-V extension SPV_NV_cooperative_matrix",
725 .dependencies = featureSet(&[_]Feature{}),
726 };
727 result[@enumToInt(Feature.SPV_NV_sample_mask_override_coverage)] = .{
728 .llvm_name = null,
729 .description = "SPIR-V extension SPV_NV_sample_mask_override_coverage",
730 .dependencies = featureSet(&[_]Feature{}),
731 };
732 result[@enumToInt(Feature.Matrix)] = .{
733 .llvm_name = null,
734 .description = "Enable SPIR-V capability Matrix",
735 .dependencies = featureSet(&[_]Feature{
736 }),
737 };
738 result[@enumToInt(Feature.Shader)] = .{
739 .llvm_name = null,
740 .description = "Enable SPIR-V capability Shader",
741 .dependencies = featureSet(&[_]Feature{
742 .Matrix,
743 }),
744 };
745 result[@enumToInt(Feature.Geometry)] = .{
746 .llvm_name = null,
747 .description = "Enable SPIR-V capability Geometry",
748 .dependencies = featureSet(&[_]Feature{
749 .Shader,
750 }),
751 };
752 result[@enumToInt(Feature.Tessellation)] = .{
753 .llvm_name = null,
754 .description = "Enable SPIR-V capability Tessellation",
755 .dependencies = featureSet(&[_]Feature{
756 .Shader,
757 }),
758 };
759 result[@enumToInt(Feature.Addresses)] = .{
760 .llvm_name = null,
761 .description = "Enable SPIR-V capability Addresses",
762 .dependencies = featureSet(&[_]Feature{
763 }),
764 };
765 result[@enumToInt(Feature.Linkage)] = .{
766 .llvm_name = null,
767 .description = "Enable SPIR-V capability Linkage",
768 .dependencies = featureSet(&[_]Feature{
769 }),
770 };
771 result[@enumToInt(Feature.Kernel)] = .{
772 .llvm_name = null,
773 .description = "Enable SPIR-V capability Kernel",
774 .dependencies = featureSet(&[_]Feature{
775 }),
776 };
777 result[@enumToInt(Feature.Vector16)] = .{
778 .llvm_name = null,
779 .description = "Enable SPIR-V capability Vector16",
780 .dependencies = featureSet(&[_]Feature{
781 .Kernel,
782 }),
783 };
784 result[@enumToInt(Feature.Float16Buffer)] = .{
785 .llvm_name = null,
786 .description = "Enable SPIR-V capability Float16Buffer",
787 .dependencies = featureSet(&[_]Feature{
788 .Kernel,
789 }),
790 };
791 result[@enumToInt(Feature.Float16)] = .{
792 .llvm_name = null,
793 .description = "Enable SPIR-V capability Float16",
794 .dependencies = featureSet(&[_]Feature{
795 }),
796 };
797 result[@enumToInt(Feature.Float64)] = .{
798 .llvm_name = null,
799 .description = "Enable SPIR-V capability Float64",
800 .dependencies = featureSet(&[_]Feature{
801 }),
802 };
803 result[@enumToInt(Feature.Int64)] = .{
804 .llvm_name = null,
805 .description = "Enable SPIR-V capability Int64",
806 .dependencies = featureSet(&[_]Feature{
807 }),
808 };
809 result[@enumToInt(Feature.Int64Atomics)] = .{
810 .llvm_name = null,
811 .description = "Enable SPIR-V capability Int64Atomics",
812 .dependencies = featureSet(&[_]Feature{
813 .Int64,
814 }),
815 };
816 result[@enumToInt(Feature.ImageBasic)] = .{
817 .llvm_name = null,
818 .description = "Enable SPIR-V capability ImageBasic",
819 .dependencies = featureSet(&[_]Feature{
820 .Kernel,
821 }),
822 };
823 result[@enumToInt(Feature.ImageReadWrite)] = .{
824 .llvm_name = null,
825 .description = "Enable SPIR-V capability ImageReadWrite",
826 .dependencies = featureSet(&[_]Feature{
827 .ImageBasic,
828 }),
829 };
830 result[@enumToInt(Feature.ImageMipmap)] = .{
831 .llvm_name = null,
832 .description = "Enable SPIR-V capability ImageMipmap",
833 .dependencies = featureSet(&[_]Feature{
834 .ImageBasic,
835 }),
836 };
837 result[@enumToInt(Feature.Pipes)] = .{
838 .llvm_name = null,
839 .description = "Enable SPIR-V capability Pipes",
840 .dependencies = featureSet(&[_]Feature{
841 .Kernel,
842 }),
843 };
844 result[@enumToInt(Feature.Groups)] = .{
845 .llvm_name = null,
846 .description = "Enable SPIR-V capability Groups",
847 .dependencies = featureSet(&[_]Feature{
848 }),
849 };
850 result[@enumToInt(Feature.DeviceEnqueue)] = .{
851 .llvm_name = null,
852 .description = "Enable SPIR-V capability DeviceEnqueue",
853 .dependencies = featureSet(&[_]Feature{
854 .Kernel,
855 }),
856 };
857 result[@enumToInt(Feature.LiteralSampler)] = .{
858 .llvm_name = null,
859 .description = "Enable SPIR-V capability LiteralSampler",
860 .dependencies = featureSet(&[_]Feature{
861 .Kernel,
862 }),
863 };
864 result[@enumToInt(Feature.AtomicStorage)] = .{
865 .llvm_name = null,
866 .description = "Enable SPIR-V capability AtomicStorage",
867 .dependencies = featureSet(&[_]Feature{
868 .Shader,
869 }),
870 };
871 result[@enumToInt(Feature.Int16)] = .{
872 .llvm_name = null,
873 .description = "Enable SPIR-V capability Int16",
874 .dependencies = featureSet(&[_]Feature{
875 }),
876 };
877 result[@enumToInt(Feature.TessellationPointSize)] = .{
878 .llvm_name = null,
879 .description = "Enable SPIR-V capability TessellationPointSize",
880 .dependencies = featureSet(&[_]Feature{
881 .Tessellation,
882 }),
883 };
884 result[@enumToInt(Feature.GeometryPointSize)] = .{
885 .llvm_name = null,
886 .description = "Enable SPIR-V capability GeometryPointSize",
887 .dependencies = featureSet(&[_]Feature{
888 .Geometry,
889 }),
890 };
891 result[@enumToInt(Feature.ImageGatherExtended)] = .{
892 .llvm_name = null,
893 .description = "Enable SPIR-V capability ImageGatherExtended",
894 .dependencies = featureSet(&[_]Feature{
895 .Shader,
896 }),
897 };
898 result[@enumToInt(Feature.StorageImageMultisample)] = .{
899 .llvm_name = null,
900 .description = "Enable SPIR-V capability StorageImageMultisample",
901 .dependencies = featureSet(&[_]Feature{
902 .Shader,
903 }),
904 };
905 result[@enumToInt(Feature.UniformBufferArrayDynamicIndexing)] = .{
906 .llvm_name = null,
907 .description = "Enable SPIR-V capability UniformBufferArrayDynamicIndexing",
908 .dependencies = featureSet(&[_]Feature{
909 .Shader,
910 }),
911 };
912 result[@enumToInt(Feature.SampledImageArrayDynamicIndexing)] = .{
913 .llvm_name = null,
914 .description = "Enable SPIR-V capability SampledImageArrayDynamicIndexing",
915 .dependencies = featureSet(&[_]Feature{
916 .Shader,
917 }),
918 };
919 result[@enumToInt(Feature.StorageBufferArrayDynamicIndexing)] = .{
920 .llvm_name = null,
921 .description = "Enable SPIR-V capability StorageBufferArrayDynamicIndexing",
922 .dependencies = featureSet(&[_]Feature{
923 .Shader,
924 }),
925 };
926 result[@enumToInt(Feature.StorageImageArrayDynamicIndexing)] = .{
927 .llvm_name = null,
928 .description = "Enable SPIR-V capability StorageImageArrayDynamicIndexing",
929 .dependencies = featureSet(&[_]Feature{
930 .Shader,
931 }),
932 };
933 result[@enumToInt(Feature.ClipDistance)] = .{
934 .llvm_name = null,
935 .description = "Enable SPIR-V capability ClipDistance",
936 .dependencies = featureSet(&[_]Feature{
937 .Shader,
938 }),
939 };
940 result[@enumToInt(Feature.CullDistance)] = .{
941 .llvm_name = null,
942 .description = "Enable SPIR-V capability CullDistance",
943 .dependencies = featureSet(&[_]Feature{
944 .Shader,
945 }),
946 };
947 result[@enumToInt(Feature.ImageCubeArray)] = .{
948 .llvm_name = null,
949 .description = "Enable SPIR-V capability ImageCubeArray",
950 .dependencies = featureSet(&[_]Feature{
951 .SampledCubeArray,
952 }),
953 };
954 result[@enumToInt(Feature.SampleRateShading)] = .{
955 .llvm_name = null,
956 .description = "Enable SPIR-V capability SampleRateShading",
957 .dependencies = featureSet(&[_]Feature{
958 .Shader,
959 }),
960 };
961 result[@enumToInt(Feature.ImageRect)] = .{
962 .llvm_name = null,
963 .description = "Enable SPIR-V capability ImageRect",
964 .dependencies = featureSet(&[_]Feature{
965 .SampledRect,
966 }),
967 };
968 result[@enumToInt(Feature.SampledRect)] = .{
969 .llvm_name = null,
970 .description = "Enable SPIR-V capability SampledRect",
971 .dependencies = featureSet(&[_]Feature{
972 .Shader,
973 }),
974 };
975 result[@enumToInt(Feature.GenericPointer)] = .{
976 .llvm_name = null,
977 .description = "Enable SPIR-V capability GenericPointer",
978 .dependencies = featureSet(&[_]Feature{
979 .Addresses,
980 }),
981 };
982 result[@enumToInt(Feature.Int8)] = .{
983 .llvm_name = null,
984 .description = "Enable SPIR-V capability Int8",
985 .dependencies = featureSet(&[_]Feature{
986 }),
987 };
988 result[@enumToInt(Feature.InputAttachment)] = .{
989 .llvm_name = null,
990 .description = "Enable SPIR-V capability InputAttachment",
991 .dependencies = featureSet(&[_]Feature{
992 .Shader,
993 }),
994 };
995 result[@enumToInt(Feature.SparseResidency)] = .{
996 .llvm_name = null,
997 .description = "Enable SPIR-V capability SparseResidency",
998 .dependencies = featureSet(&[_]Feature{
999 .Shader,
1000 }),
1001 };
1002 result[@enumToInt(Feature.MinLod)] = .{
1003 .llvm_name = null,
1004 .description = "Enable SPIR-V capability MinLod",
1005 .dependencies = featureSet(&[_]Feature{
1006 .Shader,
1007 }),
1008 };
1009 result[@enumToInt(Feature.Sampled1D)] = .{
1010 .llvm_name = null,
1011 .description = "Enable SPIR-V capability Sampled1D",
1012 .dependencies = featureSet(&[_]Feature{
1013 }),
1014 };
1015 result[@enumToInt(Feature.Image1D)] = .{
1016 .llvm_name = null,
1017 .description = "Enable SPIR-V capability Image1D",
1018 .dependencies = featureSet(&[_]Feature{
1019 .Sampled1D,
1020 }),
1021 };
1022 result[@enumToInt(Feature.SampledCubeArray)] = .{
1023 .llvm_name = null,
1024 .description = "Enable SPIR-V capability SampledCubeArray",
1025 .dependencies = featureSet(&[_]Feature{
1026 .Shader,
1027 }),
1028 };
1029 result[@enumToInt(Feature.SampledBuffer)] = .{
1030 .llvm_name = null,
1031 .description = "Enable SPIR-V capability SampledBuffer",
1032 .dependencies = featureSet(&[_]Feature{
1033 }),
1034 };
1035 result[@enumToInt(Feature.ImageBuffer)] = .{
1036 .llvm_name = null,
1037 .description = "Enable SPIR-V capability ImageBuffer",
1038 .dependencies = featureSet(&[_]Feature{
1039 .SampledBuffer,
1040 }),
1041 };
1042 result[@enumToInt(Feature.ImageMSArray)] = .{
1043 .llvm_name = null,
1044 .description = "Enable SPIR-V capability ImageMSArray",
1045 .dependencies = featureSet(&[_]Feature{
1046 .Shader,
1047 }),
1048 };
1049 result[@enumToInt(Feature.StorageImageExtendedFormats)] = .{
1050 .llvm_name = null,
1051 .description = "Enable SPIR-V capability StorageImageExtendedFormats",
1052 .dependencies = featureSet(&[_]Feature{
1053 .Shader,
1054 }),
1055 };
1056 result[@enumToInt(Feature.ImageQuery)] = .{
1057 .llvm_name = null,
1058 .description = "Enable SPIR-V capability ImageQuery",
1059 .dependencies = featureSet(&[_]Feature{
1060 .Shader,
1061 }),
1062 };
1063 result[@enumToInt(Feature.DerivativeControl)] = .{
1064 .llvm_name = null,
1065 .description = "Enable SPIR-V capability DerivativeControl",
1066 .dependencies = featureSet(&[_]Feature{
1067 .Shader,
1068 }),
1069 };
1070 result[@enumToInt(Feature.InterpolationFunction)] = .{
1071 .llvm_name = null,
1072 .description = "Enable SPIR-V capability InterpolationFunction",
1073 .dependencies = featureSet(&[_]Feature{
1074 .Shader,
1075 }),
1076 };
1077 result[@enumToInt(Feature.TransformFeedback)] = .{
1078 .llvm_name = null,
1079 .description = "Enable SPIR-V capability TransformFeedback",
1080 .dependencies = featureSet(&[_]Feature{
1081 .Shader,
1082 }),
1083 };
1084 result[@enumToInt(Feature.GeometryStreams)] = .{
1085 .llvm_name = null,
1086 .description = "Enable SPIR-V capability GeometryStreams",
1087 .dependencies = featureSet(&[_]Feature{
1088 .Geometry,
1089 }),
1090 };
1091 result[@enumToInt(Feature.StorageImageReadWithoutFormat)] = .{
1092 .llvm_name = null,
1093 .description = "Enable SPIR-V capability StorageImageReadWithoutFormat",
1094 .dependencies = featureSet(&[_]Feature{
1095 .Shader,
1096 }),
1097 };
1098 result[@enumToInt(Feature.StorageImageWriteWithoutFormat)] = .{
1099 .llvm_name = null,
1100 .description = "Enable SPIR-V capability StorageImageWriteWithoutFormat",
1101 .dependencies = featureSet(&[_]Feature{
1102 .Shader,
1103 }),
1104 };
1105 result[@enumToInt(Feature.MultiViewport)] = .{
1106 .llvm_name = null,
1107 .description = "Enable SPIR-V capability MultiViewport",
1108 .dependencies = featureSet(&[_]Feature{
1109 .Geometry,
1110 }),
1111 };
1112 result[@enumToInt(Feature.SubgroupDispatch)] = .{
1113 .llvm_name = null,
1114 .description = "Enable SPIR-V capability SubgroupDispatch",
1115 .dependencies = featureSet(&[_]Feature{
1116 .v1_1,
1117 .DeviceEnqueue,
1118 }),
1119 };
1120 result[@enumToInt(Feature.NamedBarrier)] = .{
1121 .llvm_name = null,
1122 .description = "Enable SPIR-V capability NamedBarrier",
1123 .dependencies = featureSet(&[_]Feature{
1124 .v1_1,
1125 .Kernel,
1126 }),
1127 };
1128 result[@enumToInt(Feature.PipeStorage)] = .{
1129 .llvm_name = null,
1130 .description = "Enable SPIR-V capability PipeStorage",
1131 .dependencies = featureSet(&[_]Feature{
1132 .v1_1,
1133 .Pipes,
1134 }),
1135 };
1136 result[@enumToInt(Feature.GroupNonUniform)] = .{
1137 .llvm_name = null,
1138 .description = "Enable SPIR-V capability GroupNonUniform",
1139 .dependencies = featureSet(&[_]Feature{
1140 .v1_3,
1141 }),
1142 };
1143 result[@enumToInt(Feature.GroupNonUniformVote)] = .{
1144 .llvm_name = null,
1145 .description = "Enable SPIR-V capability GroupNonUniformVote",
1146 .dependencies = featureSet(&[_]Feature{
1147 .v1_3,
1148 .GroupNonUniform,
1149 }),
1150 };
1151 result[@enumToInt(Feature.GroupNonUniformArithmetic)] = .{
1152 .llvm_name = null,
1153 .description = "Enable SPIR-V capability GroupNonUniformArithmetic",
1154 .dependencies = featureSet(&[_]Feature{
1155 .v1_3,
1156 .GroupNonUniform,
1157 }),
1158 };
1159 result[@enumToInt(Feature.GroupNonUniformBallot)] = .{
1160 .llvm_name = null,
1161 .description = "Enable SPIR-V capability GroupNonUniformBallot",
1162 .dependencies = featureSet(&[_]Feature{
1163 .v1_3,
1164 .GroupNonUniform,
1165 }),
1166 };
1167 result[@enumToInt(Feature.GroupNonUniformShuffle)] = .{
1168 .llvm_name = null,
1169 .description = "Enable SPIR-V capability GroupNonUniformShuffle",
1170 .dependencies = featureSet(&[_]Feature{
1171 .v1_3,
1172 .GroupNonUniform,
1173 }),
1174 };
1175 result[@enumToInt(Feature.GroupNonUniformShuffleRelative)] = .{
1176 .llvm_name = null,
1177 .description = "Enable SPIR-V capability GroupNonUniformShuffleRelative",
1178 .dependencies = featureSet(&[_]Feature{
1179 .v1_3,
1180 .GroupNonUniform,
1181 }),
1182 };
1183 result[@enumToInt(Feature.GroupNonUniformClustered)] = .{
1184 .llvm_name = null,
1185 .description = "Enable SPIR-V capability GroupNonUniformClustered",
1186 .dependencies = featureSet(&[_]Feature{
1187 .v1_3,
1188 .GroupNonUniform,
1189 }),
1190 };
1191 result[@enumToInt(Feature.GroupNonUniformQuad)] = .{
1192 .llvm_name = null,
1193 .description = "Enable SPIR-V capability GroupNonUniformQuad",
1194 .dependencies = featureSet(&[_]Feature{
1195 .v1_3,
1196 .GroupNonUniform,
1197 }),
1198 };
1199 result[@enumToInt(Feature.ShaderLayer)] = .{
1200 .llvm_name = null,
1201 .description = "Enable SPIR-V capability ShaderLayer",
1202 .dependencies = featureSet(&[_]Feature{
1203 .v1_5,
1204 }),
1205 };
1206 result[@enumToInt(Feature.ShaderViewportIndex)] = .{
1207 .llvm_name = null,
1208 .description = "Enable SPIR-V capability ShaderViewportIndex",
1209 .dependencies = featureSet(&[_]Feature{
1210 .v1_5,
1211 }),
1212 };
1213 result[@enumToInt(Feature.FragmentShadingRateKHR)] = .{
1214 .llvm_name = null,
1215 .description = "Enable SPIR-V capability FragmentShadingRateKHR",
1216 .dependencies = featureSet(&[_]Feature{
1217 .Shader,
1218 }),
1219 };
1220 result[@enumToInt(Feature.SubgroupBallotKHR)] = .{
1221 .llvm_name = null,
1222 .description = "Enable SPIR-V capability SubgroupBallotKHR",
1223 .dependencies = featureSet(&[_]Feature{
1224 }),
1225 };
1226 result[@enumToInt(Feature.DrawParameters)] = .{
1227 .llvm_name = null,
1228 .description = "Enable SPIR-V capability DrawParameters",
1229 .dependencies = featureSet(&[_]Feature{
1230 .v1_3,
1231 .Shader,
1232 }),
1233 };
1234 result[@enumToInt(Feature.WorkgroupMemoryExplicitLayoutKHR)] = .{
1235 .llvm_name = null,
1236 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayoutKHR",
1237 .dependencies = featureSet(&[_]Feature{
1238 .Shader,
1239 }),
1240 };
1241 result[@enumToInt(Feature.WorkgroupMemoryExplicitLayout8BitAccessKHR)] = .{
1242 .llvm_name = null,
1243 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout8BitAccessKHR",
1244 .dependencies = featureSet(&[_]Feature{
1245 .WorkgroupMemoryExplicitLayoutKHR,
1246 }),
1247 };
1248 result[@enumToInt(Feature.WorkgroupMemoryExplicitLayout16BitAccessKHR)] = .{
1249 .llvm_name = null,
1250 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout16BitAccessKHR",
1251 .dependencies = featureSet(&[_]Feature{
1252 .Shader,
1253 }),
1254 };
1255 result[@enumToInt(Feature.SubgroupVoteKHR)] = .{
1256 .llvm_name = null,
1257 .description = "Enable SPIR-V capability SubgroupVoteKHR",
1258 .dependencies = featureSet(&[_]Feature{
1259 }),
1260 };
1261 result[@enumToInt(Feature.StorageBuffer16BitAccess)] = .{
1262 .llvm_name = null,
1263 .description = "Enable SPIR-V capability StorageBuffer16BitAccess",
1264 .dependencies = featureSet(&[_]Feature{
1265 .v1_3,
1266 }),
1267 };
1268 result[@enumToInt(Feature.StorageUniformBufferBlock16)] = .{
1269 .llvm_name = null,
1270 .description = "Enable SPIR-V capability StorageUniformBufferBlock16",
1271 .dependencies = featureSet(&[_]Feature{
1272 .v1_3,
1273 }),
1274 };
1275 result[@enumToInt(Feature.UniformAndStorageBuffer16BitAccess)] = .{
1276 .llvm_name = null,
1277 .description = "Enable SPIR-V capability UniformAndStorageBuffer16BitAccess",
1278 .dependencies = featureSet(&[_]Feature{
1279 .v1_3,
1280 .StorageBuffer16BitAccess,
1281 .StorageUniformBufferBlock16,
1282 }),
1283 };
1284 result[@enumToInt(Feature.StorageUniform16)] = .{
1285 .llvm_name = null,
1286 .description = "Enable SPIR-V capability StorageUniform16",
1287 .dependencies = featureSet(&[_]Feature{
1288 .v1_3,
1289 .StorageBuffer16BitAccess,
1290 .StorageUniformBufferBlock16,
1291 }),
1292 };
1293 result[@enumToInt(Feature.StoragePushConstant16)] = .{
1294 .llvm_name = null,
1295 .description = "Enable SPIR-V capability StoragePushConstant16",
1296 .dependencies = featureSet(&[_]Feature{
1297 .v1_3,
1298 }),
1299 };
1300 result[@enumToInt(Feature.StorageInputOutput16)] = .{
1301 .llvm_name = null,
1302 .description = "Enable SPIR-V capability StorageInputOutput16",
1303 .dependencies = featureSet(&[_]Feature{
1304 .v1_3,
1305 }),
1306 };
1307 result[@enumToInt(Feature.DeviceGroup)] = .{
1308 .llvm_name = null,
1309 .description = "Enable SPIR-V capability DeviceGroup",
1310 .dependencies = featureSet(&[_]Feature{
1311 .v1_3,
1312 }),
1313 };
1314 result[@enumToInt(Feature.MultiView)] = .{
1315 .llvm_name = null,
1316 .description = "Enable SPIR-V capability MultiView",
1317 .dependencies = featureSet(&[_]Feature{
1318 .v1_3,
1319 .Shader,
1320 }),
1321 };
1322 result[@enumToInt(Feature.VariablePointersStorageBuffer)] = .{
1323 .llvm_name = null,
1324 .description = "Enable SPIR-V capability VariablePointersStorageBuffer",
1325 .dependencies = featureSet(&[_]Feature{
1326 .v1_3,
1327 .Shader,
1328 }),
1329 };
1330 result[@enumToInt(Feature.VariablePointers)] = .{
1331 .llvm_name = null,
1332 .description = "Enable SPIR-V capability VariablePointers",
1333 .dependencies = featureSet(&[_]Feature{
1334 .v1_3,
1335 .VariablePointersStorageBuffer,
1336 }),
1337 };
1338 result[@enumToInt(Feature.AtomicStorageOps)] = .{
1339 .llvm_name = null,
1340 .description = "Enable SPIR-V capability AtomicStorageOps",
1341 .dependencies = featureSet(&[_]Feature{
1342 }),
1343 };
1344 result[@enumToInt(Feature.SampleMaskPostDepthCoverage)] = .{
1345 .llvm_name = null,
1346 .description = "Enable SPIR-V capability SampleMaskPostDepthCoverage",
1347 .dependencies = featureSet(&[_]Feature{
1348 }),
1349 };
1350 result[@enumToInt(Feature.StorageBuffer8BitAccess)] = .{
1351 .llvm_name = null,
1352 .description = "Enable SPIR-V capability StorageBuffer8BitAccess",
1353 .dependencies = featureSet(&[_]Feature{
1354 .v1_5,
1355 }),
1356 };
1357 result[@enumToInt(Feature.UniformAndStorageBuffer8BitAccess)] = .{
1358 .llvm_name = null,
1359 .description = "Enable SPIR-V capability UniformAndStorageBuffer8BitAccess",
1360 .dependencies = featureSet(&[_]Feature{
1361 .v1_5,
1362 .StorageBuffer8BitAccess,
1363 }),
1364 };
1365 result[@enumToInt(Feature.StoragePushConstant8)] = .{
1366 .llvm_name = null,
1367 .description = "Enable SPIR-V capability StoragePushConstant8",
1368 .dependencies = featureSet(&[_]Feature{
1369 .v1_5,
1370 }),
1371 };
1372 result[@enumToInt(Feature.DenormPreserve)] = .{
1373 .llvm_name = null,
1374 .description = "Enable SPIR-V capability DenormPreserve",
1375 .dependencies = featureSet(&[_]Feature{
1376 .v1_4,
1377 }),
1378 };
1379 result[@enumToInt(Feature.DenormFlushToZero)] = .{
1380 .llvm_name = null,
1381 .description = "Enable SPIR-V capability DenormFlushToZero",
1382 .dependencies = featureSet(&[_]Feature{
1383 .v1_4,
1384 }),
1385 };
1386 result[@enumToInt(Feature.SignedZeroInfNanPreserve)] = .{
1387 .llvm_name = null,
1388 .description = "Enable SPIR-V capability SignedZeroInfNanPreserve",
1389 .dependencies = featureSet(&[_]Feature{
1390 .v1_4,
1391 }),
1392 };
1393 result[@enumToInt(Feature.RoundingModeRTE)] = .{
1394 .llvm_name = null,
1395 .description = "Enable SPIR-V capability RoundingModeRTE",
1396 .dependencies = featureSet(&[_]Feature{
1397 .v1_4,
1398 }),
1399 };
1400 result[@enumToInt(Feature.RoundingModeRTZ)] = .{
1401 .llvm_name = null,
1402 .description = "Enable SPIR-V capability RoundingModeRTZ",
1403 .dependencies = featureSet(&[_]Feature{
1404 .v1_4,
1405 }),
1406 };
1407 result[@enumToInt(Feature.RayQueryProvisionalKHR)] = .{
1408 .llvm_name = null,
1409 .description = "Enable SPIR-V capability RayQueryProvisionalKHR",
1410 .dependencies = featureSet(&[_]Feature{
1411 .Shader,
1412 }),
1413 };
1414 result[@enumToInt(Feature.RayQueryKHR)] = .{
1415 .llvm_name = null,
1416 .description = "Enable SPIR-V capability RayQueryKHR",
1417 .dependencies = featureSet(&[_]Feature{
1418 .Shader,
1419 }),
1420 };
1421 result[@enumToInt(Feature.RayTraversalPrimitiveCullingKHR)] = .{
1422 .llvm_name = null,
1423 .description = "Enable SPIR-V capability RayTraversalPrimitiveCullingKHR",
1424 .dependencies = featureSet(&[_]Feature{
1425 .RayQueryKHR,
1426 .RayTracingKHR,
1427 }),
1428 };
1429 result[@enumToInt(Feature.RayTracingKHR)] = .{
1430 .llvm_name = null,
1431 .description = "Enable SPIR-V capability RayTracingKHR",
1432 .dependencies = featureSet(&[_]Feature{
1433 .Shader,
1434 }),
1435 };
1436 result[@enumToInt(Feature.Float16ImageAMD)] = .{
1437 .llvm_name = null,
1438 .description = "Enable SPIR-V capability Float16ImageAMD",
1439 .dependencies = featureSet(&[_]Feature{
1440 .Shader,
1441 }),
1442 };
1443 result[@enumToInt(Feature.ImageGatherBiasLodAMD)] = .{
1444 .llvm_name = null,
1445 .description = "Enable SPIR-V capability ImageGatherBiasLodAMD",
1446 .dependencies = featureSet(&[_]Feature{
1447 .Shader,
1448 }),
1449 };
1450 result[@enumToInt(Feature.FragmentMaskAMD)] = .{
1451 .llvm_name = null,
1452 .description = "Enable SPIR-V capability FragmentMaskAMD",
1453 .dependencies = featureSet(&[_]Feature{
1454 .Shader,
1455 }),
1456 };
1457 result[@enumToInt(Feature.StencilExportEXT)] = .{
1458 .llvm_name = null,
1459 .description = "Enable SPIR-V capability StencilExportEXT",
1460 .dependencies = featureSet(&[_]Feature{
1461 .Shader,
1462 }),
1463 };
1464 result[@enumToInt(Feature.ImageReadWriteLodAMD)] = .{
1465 .llvm_name = null,
1466 .description = "Enable SPIR-V capability ImageReadWriteLodAMD",
1467 .dependencies = featureSet(&[_]Feature{
1468 .Shader,
1469 }),
1470 };
1471 result[@enumToInt(Feature.Int64ImageEXT)] = .{
1472 .llvm_name = null,
1473 .description = "Enable SPIR-V capability Int64ImageEXT",
1474 .dependencies = featureSet(&[_]Feature{
1475 .Shader,
1476 }),
1477 };
1478 result[@enumToInt(Feature.ShaderClockKHR)] = .{
1479 .llvm_name = null,
1480 .description = "Enable SPIR-V capability ShaderClockKHR",
1481 .dependencies = featureSet(&[_]Feature{
1482 .Shader,
1483 }),
1484 };
1485 result[@enumToInt(Feature.SampleMaskOverrideCoverageNV)] = .{
1486 .llvm_name = null,
1487 .description = "Enable SPIR-V capability SampleMaskOverrideCoverageNV",
1488 .dependencies = featureSet(&[_]Feature{
1489 .SampleRateShading,
1490 }),
1491 };
1492 result[@enumToInt(Feature.GeometryShaderPassthroughNV)] = .{
1493 .llvm_name = null,
1494 .description = "Enable SPIR-V capability GeometryShaderPassthroughNV",
1495 .dependencies = featureSet(&[_]Feature{
1496 .Geometry,
1497 }),
1498 };
1499 result[@enumToInt(Feature.ShaderViewportIndexLayerEXT)] = .{
1500 .llvm_name = null,
1501 .description = "Enable SPIR-V capability ShaderViewportIndexLayerEXT",
1502 .dependencies = featureSet(&[_]Feature{
1503 .MultiViewport,
1504 }),
1505 };
1506 result[@enumToInt(Feature.ShaderViewportIndexLayerNV)] = .{
1507 .llvm_name = null,
1508 .description = "Enable SPIR-V capability ShaderViewportIndexLayerNV",
1509 .dependencies = featureSet(&[_]Feature{
1510 .MultiViewport,
1511 }),
1512 };
1513 result[@enumToInt(Feature.ShaderViewportMaskNV)] = .{
1514 .llvm_name = null,
1515 .description = "Enable SPIR-V capability ShaderViewportMaskNV",
1516 .dependencies = featureSet(&[_]Feature{
1517 .ShaderViewportIndexLayerNV,
1518 }),
1519 };
1520 result[@enumToInt(Feature.ShaderStereoViewNV)] = .{
1521 .llvm_name = null,
1522 .description = "Enable SPIR-V capability ShaderStereoViewNV",
1523 .dependencies = featureSet(&[_]Feature{
1524 .ShaderViewportMaskNV,
1525 }),
1526 };
1527 result[@enumToInt(Feature.PerViewAttributesNV)] = .{
1528 .llvm_name = null,
1529 .description = "Enable SPIR-V capability PerViewAttributesNV",
1530 .dependencies = featureSet(&[_]Feature{
1531 .MultiView,
1532 }),
1533 };
1534 result[@enumToInt(Feature.FragmentFullyCoveredEXT)] = .{
1535 .llvm_name = null,
1536 .description = "Enable SPIR-V capability FragmentFullyCoveredEXT",
1537 .dependencies = featureSet(&[_]Feature{
1538 .Shader,
1539 }),
1540 };
1541 result[@enumToInt(Feature.MeshShadingNV)] = .{
1542 .llvm_name = null,
1543 .description = "Enable SPIR-V capability MeshShadingNV",
1544 .dependencies = featureSet(&[_]Feature{
1545 .Shader,
1546 }),
1547 };
1548 result[@enumToInt(Feature.ImageFootprintNV)] = .{
1549 .llvm_name = null,
1550 .description = "Enable SPIR-V capability ImageFootprintNV",
1551 .dependencies = featureSet(&[_]Feature{
1552 }),
1553 };
1554 result[@enumToInt(Feature.FragmentBarycentricNV)] = .{
1555 .llvm_name = null,
1556 .description = "Enable SPIR-V capability FragmentBarycentricNV",
1557 .dependencies = featureSet(&[_]Feature{
1558 }),
1559 };
1560 result[@enumToInt(Feature.ComputeDerivativeGroupQuadsNV)] = .{
1561 .llvm_name = null,
1562 .description = "Enable SPIR-V capability ComputeDerivativeGroupQuadsNV",
1563 .dependencies = featureSet(&[_]Feature{
1564 }),
1565 };
1566 result[@enumToInt(Feature.FragmentDensityEXT)] = .{
1567 .llvm_name = null,
1568 .description = "Enable SPIR-V capability FragmentDensityEXT",
1569 .dependencies = featureSet(&[_]Feature{
1570 .Shader,
1571 }),
1572 };
1573 result[@enumToInt(Feature.ShadingRateNV)] = .{
1574 .llvm_name = null,
1575 .description = "Enable SPIR-V capability ShadingRateNV",
1576 .dependencies = featureSet(&[_]Feature{
1577 .Shader,
1578 }),
1579 };
1580 result[@enumToInt(Feature.GroupNonUniformPartitionedNV)] = .{
1581 .llvm_name = null,
1582 .description = "Enable SPIR-V capability GroupNonUniformPartitionedNV",
1583 .dependencies = featureSet(&[_]Feature{
1584 }),
1585 };
1586 result[@enumToInt(Feature.ShaderNonUniform)] = .{
1587 .llvm_name = null,
1588 .description = "Enable SPIR-V capability ShaderNonUniform",
1589 .dependencies = featureSet(&[_]Feature{
1590 .v1_5,
1591 .Shader,
1592 }),
1593 };
1594 result[@enumToInt(Feature.ShaderNonUniformEXT)] = .{
1595 .llvm_name = null,
1596 .description = "Enable SPIR-V capability ShaderNonUniformEXT",
1597 .dependencies = featureSet(&[_]Feature{
1598 .v1_5,
1599 .Shader,
1600 }),
1601 };
1602 result[@enumToInt(Feature.RuntimeDescriptorArray)] = .{
1603 .llvm_name = null,
1604 .description = "Enable SPIR-V capability RuntimeDescriptorArray",
1605 .dependencies = featureSet(&[_]Feature{
1606 .v1_5,
1607 .Shader,
1608 }),
1609 };
1610 result[@enumToInt(Feature.RuntimeDescriptorArrayEXT)] = .{
1611 .llvm_name = null,
1612 .description = "Enable SPIR-V capability RuntimeDescriptorArrayEXT",
1613 .dependencies = featureSet(&[_]Feature{
1614 .v1_5,
1615 .Shader,
1616 }),
1617 };
1618 result[@enumToInt(Feature.InputAttachmentArrayDynamicIndexing)] = .{
1619 .llvm_name = null,
1620 .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexing",
1621 .dependencies = featureSet(&[_]Feature{
1622 .v1_5,
1623 .InputAttachment,
1624 }),
1625 };
1626 result[@enumToInt(Feature.InputAttachmentArrayDynamicIndexingEXT)] = .{
1627 .llvm_name = null,
1628 .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexingEXT",
1629 .dependencies = featureSet(&[_]Feature{
1630 .v1_5,
1631 .InputAttachment,
1632 }),
1633 };
1634 result[@enumToInt(Feature.UniformTexelBufferArrayDynamicIndexing)] = .{
1635 .llvm_name = null,
1636 .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexing",
1637 .dependencies = featureSet(&[_]Feature{
1638 .v1_5,
1639 .SampledBuffer,
1640 }),
1641 };
1642 result[@enumToInt(Feature.UniformTexelBufferArrayDynamicIndexingEXT)] = .{
1643 .llvm_name = null,
1644 .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexingEXT",
1645 .dependencies = featureSet(&[_]Feature{
1646 .v1_5,
1647 .SampledBuffer,
1648 }),
1649 };
1650 result[@enumToInt(Feature.StorageTexelBufferArrayDynamicIndexing)] = .{
1651 .llvm_name = null,
1652 .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexing",
1653 .dependencies = featureSet(&[_]Feature{
1654 .v1_5,
1655 .ImageBuffer,
1656 }),
1657 };
1658 result[@enumToInt(Feature.StorageTexelBufferArrayDynamicIndexingEXT)] = .{
1659 .llvm_name = null,
1660 .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexingEXT",
1661 .dependencies = featureSet(&[_]Feature{
1662 .v1_5,
1663 .ImageBuffer,
1664 }),
1665 };
1666 result[@enumToInt(Feature.UniformBufferArrayNonUniformIndexing)] = .{
1667 .llvm_name = null,
1668 .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexing",
1669 .dependencies = featureSet(&[_]Feature{
1670 .v1_5,
1671 .ShaderNonUniform,
1672 }),
1673 };
1674 result[@enumToInt(Feature.UniformBufferArrayNonUniformIndexingEXT)] = .{
1675 .llvm_name = null,
1676 .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexingEXT",
1677 .dependencies = featureSet(&[_]Feature{
1678 .v1_5,
1679 .ShaderNonUniform,
1680 }),
1681 };
1682 result[@enumToInt(Feature.SampledImageArrayNonUniformIndexing)] = .{
1683 .llvm_name = null,
1684 .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexing",
1685 .dependencies = featureSet(&[_]Feature{
1686 .v1_5,
1687 .ShaderNonUniform,
1688 }),
1689 };
1690 result[@enumToInt(Feature.SampledImageArrayNonUniformIndexingEXT)] = .{
1691 .llvm_name = null,
1692 .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexingEXT",
1693 .dependencies = featureSet(&[_]Feature{
1694 .v1_5,
1695 .ShaderNonUniform,
1696 }),
1697 };
1698 result[@enumToInt(Feature.StorageBufferArrayNonUniformIndexing)] = .{
1699 .llvm_name = null,
1700 .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexing",
1701 .dependencies = featureSet(&[_]Feature{
1702 .v1_5,
1703 .ShaderNonUniform,
1704 }),
1705 };
1706 result[@enumToInt(Feature.StorageBufferArrayNonUniformIndexingEXT)] = .{
1707 .llvm_name = null,
1708 .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexingEXT",
1709 .dependencies = featureSet(&[_]Feature{
1710 .v1_5,
1711 .ShaderNonUniform,
1712 }),
1713 };
1714 result[@enumToInt(Feature.StorageImageArrayNonUniformIndexing)] = .{
1715 .llvm_name = null,
1716 .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexing",
1717 .dependencies = featureSet(&[_]Feature{
1718 .v1_5,
1719 .ShaderNonUniform,
1720 }),
1721 };
1722 result[@enumToInt(Feature.StorageImageArrayNonUniformIndexingEXT)] = .{
1723 .llvm_name = null,
1724 .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexingEXT",
1725 .dependencies = featureSet(&[_]Feature{
1726 .v1_5,
1727 .ShaderNonUniform,
1728 }),
1729 };
1730 result[@enumToInt(Feature.InputAttachmentArrayNonUniformIndexing)] = .{
1731 .llvm_name = null,
1732 .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexing",
1733 .dependencies = featureSet(&[_]Feature{
1734 .v1_5,
1735 .InputAttachment,
1736 .ShaderNonUniform,
1737 }),
1738 };
1739 result[@enumToInt(Feature.InputAttachmentArrayNonUniformIndexingEXT)] = .{
1740 .llvm_name = null,
1741 .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexingEXT",
1742 .dependencies = featureSet(&[_]Feature{
1743 .v1_5,
1744 .InputAttachment,
1745 .ShaderNonUniform,
1746 }),
1747 };
1748 result[@enumToInt(Feature.UniformTexelBufferArrayNonUniformIndexing)] = .{
1749 .llvm_name = null,
1750 .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexing",
1751 .dependencies = featureSet(&[_]Feature{
1752 .v1_5,
1753 .SampledBuffer,
1754 .ShaderNonUniform,
1755 }),
1756 };
1757 result[@enumToInt(Feature.UniformTexelBufferArrayNonUniformIndexingEXT)] = .{
1758 .llvm_name = null,
1759 .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexingEXT",
1760 .dependencies = featureSet(&[_]Feature{
1761 .v1_5,
1762 .SampledBuffer,
1763 .ShaderNonUniform,
1764 }),
1765 };
1766 result[@enumToInt(Feature.StorageTexelBufferArrayNonUniformIndexing)] = .{
1767 .llvm_name = null,
1768 .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexing",
1769 .dependencies = featureSet(&[_]Feature{
1770 .v1_5,
1771 .ImageBuffer,
1772 .ShaderNonUniform,
1773 }),
1774 };
1775 result[@enumToInt(Feature.StorageTexelBufferArrayNonUniformIndexingEXT)] = .{
1776 .llvm_name = null,
1777 .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexingEXT",
1778 .dependencies = featureSet(&[_]Feature{
1779 .v1_5,
1780 .ImageBuffer,
1781 .ShaderNonUniform,
1782 }),
1783 };
1784 result[@enumToInt(Feature.RayTracingNV)] = .{
1785 .llvm_name = null,
1786 .description = "Enable SPIR-V capability RayTracingNV",
1787 .dependencies = featureSet(&[_]Feature{
1788 .Shader,
1789 }),
1790 };
1791 result[@enumToInt(Feature.VulkanMemoryModel)] = .{
1792 .llvm_name = null,
1793 .description = "Enable SPIR-V capability VulkanMemoryModel",
1794 .dependencies = featureSet(&[_]Feature{
1795 .v1_5,
1796 }),
1797 };
1798 result[@enumToInt(Feature.VulkanMemoryModelKHR)] = .{
1799 .llvm_name = null,
1800 .description = "Enable SPIR-V capability VulkanMemoryModelKHR",
1801 .dependencies = featureSet(&[_]Feature{
1802 .v1_5,
1803 }),
1804 };
1805 result[@enumToInt(Feature.VulkanMemoryModelDeviceScope)] = .{
1806 .llvm_name = null,
1807 .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScope",
1808 .dependencies = featureSet(&[_]Feature{
1809 .v1_5,
1810 }),
1811 };
1812 result[@enumToInt(Feature.VulkanMemoryModelDeviceScopeKHR)] = .{
1813 .llvm_name = null,
1814 .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScopeKHR",
1815 .dependencies = featureSet(&[_]Feature{
1816 .v1_5,
1817 }),
1818 };
1819 result[@enumToInt(Feature.PhysicalStorageBufferAddresses)] = .{
1820 .llvm_name = null,
1821 .description = "Enable SPIR-V capability PhysicalStorageBufferAddresses",
1822 .dependencies = featureSet(&[_]Feature{
1823 .v1_5,
1824 .Shader,
1825 }),
1826 };
1827 result[@enumToInt(Feature.PhysicalStorageBufferAddressesEXT)] = .{
1828 .llvm_name = null,
1829 .description = "Enable SPIR-V capability PhysicalStorageBufferAddressesEXT",
1830 .dependencies = featureSet(&[_]Feature{
1831 .v1_5,
1832 .Shader,
1833 }),
1834 };
1835 result[@enumToInt(Feature.ComputeDerivativeGroupLinearNV)] = .{
1836 .llvm_name = null,
1837 .description = "Enable SPIR-V capability ComputeDerivativeGroupLinearNV",
1838 .dependencies = featureSet(&[_]Feature{
1839 }),
1840 };
1841 result[@enumToInt(Feature.RayTracingProvisionalKHR)] = .{
1842 .llvm_name = null,
1843 .description = "Enable SPIR-V capability RayTracingProvisionalKHR",
1844 .dependencies = featureSet(&[_]Feature{
1845 .Shader,
1846 }),
1847 };
1848 result[@enumToInt(Feature.CooperativeMatrixNV)] = .{
1849 .llvm_name = null,
1850 .description = "Enable SPIR-V capability CooperativeMatrixNV",
1851 .dependencies = featureSet(&[_]Feature{
1852 .Shader,
1853 }),
1854 };
1855 result[@enumToInt(Feature.FragmentShaderSampleInterlockEXT)] = .{
1856 .llvm_name = null,
1857 .description = "Enable SPIR-V capability FragmentShaderSampleInterlockEXT",
1858 .dependencies = featureSet(&[_]Feature{
1859 .Shader,
1860 }),
1861 };
1862 result[@enumToInt(Feature.FragmentShaderShadingRateInterlockEXT)] = .{
1863 .llvm_name = null,
1864 .description = "Enable SPIR-V capability FragmentShaderShadingRateInterlockEXT",
1865 .dependencies = featureSet(&[_]Feature{
1866 .Shader,
1867 }),
1868 };
1869 result[@enumToInt(Feature.ShaderSMBuiltinsNV)] = .{
1870 .llvm_name = null,
1871 .description = "Enable SPIR-V capability ShaderSMBuiltinsNV",
1872 .dependencies = featureSet(&[_]Feature{
1873 .Shader,
1874 }),
1875 };
1876 result[@enumToInt(Feature.FragmentShaderPixelInterlockEXT)] = .{
1877 .llvm_name = null,
1878 .description = "Enable SPIR-V capability FragmentShaderPixelInterlockEXT",
1879 .dependencies = featureSet(&[_]Feature{
1880 .Shader,
1881 }),
1882 };
1883 result[@enumToInt(Feature.DemoteToHelperInvocationEXT)] = .{
1884 .llvm_name = null,
1885 .description = "Enable SPIR-V capability DemoteToHelperInvocationEXT",
1886 .dependencies = featureSet(&[_]Feature{
1887 .Shader,
1888 }),
1889 };
1890 result[@enumToInt(Feature.SubgroupShuffleINTEL)] = .{
1891 .llvm_name = null,
1892 .description = "Enable SPIR-V capability SubgroupShuffleINTEL",
1893 .dependencies = featureSet(&[_]Feature{
1894 }),
1895 };
1896 result[@enumToInt(Feature.SubgroupBufferBlockIOINTEL)] = .{
1897 .llvm_name = null,
1898 .description = "Enable SPIR-V capability SubgroupBufferBlockIOINTEL",
1899 .dependencies = featureSet(&[_]Feature{
1900 }),
1901 };
1902 result[@enumToInt(Feature.SubgroupImageBlockIOINTEL)] = .{
1903 .llvm_name = null,
1904 .description = "Enable SPIR-V capability SubgroupImageBlockIOINTEL",
1905 .dependencies = featureSet(&[_]Feature{
1906 }),
1907 };
1908 result[@enumToInt(Feature.SubgroupImageMediaBlockIOINTEL)] = .{
1909 .llvm_name = null,
1910 .description = "Enable SPIR-V capability SubgroupImageMediaBlockIOINTEL",
1911 .dependencies = featureSet(&[_]Feature{
1912 }),
1913 };
1914 result[@enumToInt(Feature.RoundToInfinityINTEL)] = .{
1915 .llvm_name = null,
1916 .description = "Enable SPIR-V capability RoundToInfinityINTEL",
1917 .dependencies = featureSet(&[_]Feature{
1918 }),
1919 };
1920 result[@enumToInt(Feature.FloatingPointModeINTEL)] = .{
1921 .llvm_name = null,
1922 .description = "Enable SPIR-V capability FloatingPointModeINTEL",
1923 .dependencies = featureSet(&[_]Feature{
1924 }),
1925 };
1926 result[@enumToInt(Feature.IntegerFunctions2INTEL)] = .{
1927 .llvm_name = null,
1928 .description = "Enable SPIR-V capability IntegerFunctions2INTEL",
1929 .dependencies = featureSet(&[_]Feature{
1930 .Shader,
1931 }),
1932 };
1933 result[@enumToInt(Feature.FunctionPointersINTEL)] = .{
1934 .llvm_name = null,
1935 .description = "Enable SPIR-V capability FunctionPointersINTEL",
1936 .dependencies = featureSet(&[_]Feature{
1937 }),
1938 };
1939 result[@enumToInt(Feature.IndirectReferencesINTEL)] = .{
1940 .llvm_name = null,
1941 .description = "Enable SPIR-V capability IndirectReferencesINTEL",
1942 .dependencies = featureSet(&[_]Feature{
1943 }),
1944 };
1945 result[@enumToInt(Feature.AsmINTEL)] = .{
1946 .llvm_name = null,
1947 .description = "Enable SPIR-V capability AsmINTEL",
1948 .dependencies = featureSet(&[_]Feature{
1949 }),
1950 };
1951 result[@enumToInt(Feature.AtomicFloat32MinMaxEXT)] = .{
1952 .llvm_name = null,
1953 .description = "Enable SPIR-V capability AtomicFloat32MinMaxEXT",
1954 .dependencies = featureSet(&[_]Feature{
1955 }),
1956 };
1957 result[@enumToInt(Feature.AtomicFloat64MinMaxEXT)] = .{
1958 .llvm_name = null,
1959 .description = "Enable SPIR-V capability AtomicFloat64MinMaxEXT",
1960 .dependencies = featureSet(&[_]Feature{
1961 }),
1962 };
1963 result[@enumToInt(Feature.AtomicFloat16MinMaxEXT)] = .{
1964 .llvm_name = null,
1965 .description = "Enable SPIR-V capability AtomicFloat16MinMaxEXT",
1966 .dependencies = featureSet(&[_]Feature{
1967 }),
1968 };
1969 result[@enumToInt(Feature.VectorComputeINTEL)] = .{
1970 .llvm_name = null,
1971 .description = "Enable SPIR-V capability VectorComputeINTEL",
1972 .dependencies = featureSet(&[_]Feature{
1973 .VectorAnyINTEL,
1974 }),
1975 };
1976 result[@enumToInt(Feature.VectorAnyINTEL)] = .{
1977 .llvm_name = null,
1978 .description = "Enable SPIR-V capability VectorAnyINTEL",
1979 .dependencies = featureSet(&[_]Feature{
1980 }),
1981 };
1982 result[@enumToInt(Feature.ExpectAssumeKHR)] = .{
1983 .llvm_name = null,
1984 .description = "Enable SPIR-V capability ExpectAssumeKHR",
1985 .dependencies = featureSet(&[_]Feature{
1986 }),
1987 };
1988 result[@enumToInt(Feature.SubgroupAvcMotionEstimationINTEL)] = .{
1989 .llvm_name = null,
1990 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationINTEL",
1991 .dependencies = featureSet(&[_]Feature{
1992 }),
1993 };
1994 result[@enumToInt(Feature.SubgroupAvcMotionEstimationIntraINTEL)] = .{
1995 .llvm_name = null,
1996 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationIntraINTEL",
1997 .dependencies = featureSet(&[_]Feature{
1998 }),
1999 };
2000 result[@enumToInt(Feature.SubgroupAvcMotionEstimationChromaINTEL)] = .{
2001 .llvm_name = null,
2002 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationChromaINTEL",
2003 .dependencies = featureSet(&[_]Feature{
2004 }),
2005 };
2006 result[@enumToInt(Feature.VariableLengthArrayINTEL)] = .{
2007 .llvm_name = null,
2008 .description = "Enable SPIR-V capability VariableLengthArrayINTEL",
2009 .dependencies = featureSet(&[_]Feature{
2010 }),
2011 };
2012 result[@enumToInt(Feature.FunctionFloatControlINTEL)] = .{
2013 .llvm_name = null,
2014 .description = "Enable SPIR-V capability FunctionFloatControlINTEL",
2015 .dependencies = featureSet(&[_]Feature{
2016 }),
2017 };
2018 result[@enumToInt(Feature.FPGAMemoryAttributesINTEL)] = .{
2019 .llvm_name = null,
2020 .description = "Enable SPIR-V capability FPGAMemoryAttributesINTEL",
2021 .dependencies = featureSet(&[_]Feature{
2022 }),
2023 };
2024 result[@enumToInt(Feature.FPFastMathModeINTEL)] = .{
2025 .llvm_name = null,
2026 .description = "Enable SPIR-V capability FPFastMathModeINTEL",
2027 .dependencies = featureSet(&[_]Feature{
2028 .Kernel,
2029 }),
2030 };
2031 result[@enumToInt(Feature.ArbitraryPrecisionIntegersINTEL)] = .{
2032 .llvm_name = null,
2033 .description = "Enable SPIR-V capability ArbitraryPrecisionIntegersINTEL",
2034 .dependencies = featureSet(&[_]Feature{
2035 }),
2036 };
2037 result[@enumToInt(Feature.UnstructuredLoopControlsINTEL)] = .{
2038 .llvm_name = null,
2039 .description = "Enable SPIR-V capability UnstructuredLoopControlsINTEL",
2040 .dependencies = featureSet(&[_]Feature{
2041 }),
2042 };
2043 result[@enumToInt(Feature.FPGALoopControlsINTEL)] = .{
2044 .llvm_name = null,
2045 .description = "Enable SPIR-V capability FPGALoopControlsINTEL",
2046 .dependencies = featureSet(&[_]Feature{
2047 }),
2048 };
2049 result[@enumToInt(Feature.KernelAttributesINTEL)] = .{
2050 .llvm_name = null,
2051 .description = "Enable SPIR-V capability KernelAttributesINTEL",
2052 .dependencies = featureSet(&[_]Feature{
2053 }),
2054 };
2055 result[@enumToInt(Feature.FPGAKernelAttributesINTEL)] = .{
2056 .llvm_name = null,
2057 .description = "Enable SPIR-V capability FPGAKernelAttributesINTEL",
2058 .dependencies = featureSet(&[_]Feature{
2059 }),
2060 };
2061 result[@enumToInt(Feature.FPGAMemoryAccessesINTEL)] = .{
2062 .llvm_name = null,
2063 .description = "Enable SPIR-V capability FPGAMemoryAccessesINTEL",
2064 .dependencies = featureSet(&[_]Feature{
2065 }),
2066 };
2067 result[@enumToInt(Feature.FPGAClusterAttributesINTEL)] = .{
2068 .llvm_name = null,
2069 .description = "Enable SPIR-V capability FPGAClusterAttributesINTEL",
2070 .dependencies = featureSet(&[_]Feature{
2071 }),
2072 };
2073 result[@enumToInt(Feature.LoopFuseINTEL)] = .{
2074 .llvm_name = null,
2075 .description = "Enable SPIR-V capability LoopFuseINTEL",
2076 .dependencies = featureSet(&[_]Feature{
2077 }),
2078 };
2079 result[@enumToInt(Feature.FPGABufferLocationINTEL)] = .{
2080 .llvm_name = null,
2081 .description = "Enable SPIR-V capability FPGABufferLocationINTEL",
2082 .dependencies = featureSet(&[_]Feature{
2083 }),
2084 };
2085 result[@enumToInt(Feature.USMStorageClassesINTEL)] = .{
2086 .llvm_name = null,
2087 .description = "Enable SPIR-V capability USMStorageClassesINTEL",
2088 .dependencies = featureSet(&[_]Feature{
2089 }),
2090 };
2091 result[@enumToInt(Feature.IOPipesINTEL)] = .{
2092 .llvm_name = null,
2093 .description = "Enable SPIR-V capability IOPipesINTEL",
2094 .dependencies = featureSet(&[_]Feature{
2095 }),
2096 };
2097 result[@enumToInt(Feature.BlockingPipesINTEL)] = .{
2098 .llvm_name = null,
2099 .description = "Enable SPIR-V capability BlockingPipesINTEL",
2100 .dependencies = featureSet(&[_]Feature{
2101 }),
2102 };
2103 result[@enumToInt(Feature.FPGARegINTEL)] = .{
2104 .llvm_name = null,
2105 .description = "Enable SPIR-V capability FPGARegINTEL",
2106 .dependencies = featureSet(&[_]Feature{
2107 }),
2108 };
2109 result[@enumToInt(Feature.AtomicFloat32AddEXT)] = .{
2110 .llvm_name = null,
2111 .description = "Enable SPIR-V capability AtomicFloat32AddEXT",
2112 .dependencies = featureSet(&[_]Feature{
2113 .Shader,
2114 }),
2115 };
2116 result[@enumToInt(Feature.AtomicFloat64AddEXT)] = .{
2117 .llvm_name = null,
2118 .description = "Enable SPIR-V capability AtomicFloat64AddEXT",
2119 .dependencies = featureSet(&[_]Feature{
2120 .Shader,
2121 }),
2122 };
2123 result[@enumToInt(Feature.LongConstantCompositeINTEL)] = .{
2124 .llvm_name = null,
2125 .description = "Enable SPIR-V capability LongConstantCompositeINTEL",
2126 .dependencies = featureSet(&[_]Feature{
2127 }),
2128 };
2129 const ti = @typeInfo(Feature);
2130 for (result) |*elem, i| {
2131 elem.index = i;
2132 elem.name = ti.Enum.fields[i].name;
2133 }
2134 break :blk result;
2135};
src/codegen/spirv.zig+76-19
...@@ -1,9 +1,13 @@...@@ -1,9 +1,13 @@
1const std = @import("std");1const std = @import("std");
2const Allocator = std.mem.Allocator;2const Allocator = std.mem.Allocator;
3const log = std.log.scoped(.codegen);
34
4const spec = @import("spirv/spec.zig");5const spec = @import("spirv/spec.zig");
5const Module = @import("../Module.zig");6const Module = @import("../Module.zig");
6const Decl = Module.Decl;7const Decl = Module.Decl;
8const Type = @import("../type.zig").Type;
9
10pub const TypeMap = std.HashMap(Type, u32, Type.hash, Type.eql, std.hash_map.default_max_load_percentage);
711
8pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []const u32) !void {12pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []const u32) !void {
9 const word_count = @intCast(u32, args.len + 1);13 const word_count = @intCast(u32, args.len + 1);
...@@ -12,38 +16,91 @@ pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []c...@@ -12,38 +16,91 @@ pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []c
12}16}
1317
14pub const SPIRVModule = struct {18pub const SPIRVModule = struct {
15 next_id: u32 = 0,19 next_result_id: u32 = 0,
16 free_id_list: std.ArrayList(u32),20
21 target: std.Target,
22
23 types: TypeMap,
24
25 types_and_globals: std.ArrayList(u32),
26 fn_decls: std.ArrayList(u32),
1727
18 pub fn init(allocator: *Allocator) SPIRVModule {28 pub fn init(target: std.Target, allocator: *Allocator) SPIRVModule {
19 return .{29 return .{
20 .free_id_list = std.ArrayList(u32).init(allocator),30 .target = target,
31 .types = TypeMap.init(allocator),
32 .types_and_globals = std.ArrayList(u32).init(allocator),
33 .fn_decls = std.ArrayList(u32).init(allocator),
21 };34 };
22 }35 }
2336
24 pub fn deinit(self: *SPIRVModule) void {37 pub fn deinit(self: *SPIRVModule) void {
25 self.free_id_list.deinit();38 self.fn_decls.deinit();
39 self.types_and_globals.deinit();
40 self.types.deinit();
41 self.* = undefined;
26 }42 }
2743
28 pub fn allocId(self: *SPIRVModule) u32 {44 pub fn allocResultId(self: *SPIRVModule) u32 {
29 if (self.free_id_list.popOrNull()) |id| return id;45 defer self.next_result_id += 1;
46 return self.next_result_id;
47 }
3048
31 defer self.next_id += 1;49 pub fn resultIdBound(self: *SPIRVModule) u32 {
32 return self.next_id;50 return self.next_result_id;
33 }51 }
3452
35 pub fn freeId(self: *SPIRVModule, id: u32) void {53 pub fn getOrGenType(self: *SPIRVModule, t: Type) !u32 {
36 if (id + 1 == self.next_id) {54 // We can't use getOrPut here so we can recursively generate types.
37 self.next_id -= 1;55 if (self.types.get(t)) |already_generated| {
38 } else {56 return already_generated;
39 // If no more memory to append the id to the free list, just ignore it.
40 self.free_id_list.append(id) catch {};
41 }57 }
42 }
4358
44 pub fn idBound(self: *SPIRVModule) u32 {59 const result = self.allocResultId();
45 return self.next_id;60
61 switch (t.zigTypeTag()) {
62 .Void => try writeInstruction(&self.types_and_globals, .OpTypeVoid, &[_]u32{ result }),
63 .Bool => try writeInstruction(&self.types_and_globals, .OpTypeBool, &[_]u32{ result }),
64 .Int => {
65 const int_info = t.intInfo(self.target);
66 try writeInstruction(&self.types_and_globals, .OpTypeInt, &[_]u32{
67 result,
68 int_info.bits,
69 switch (int_info.signedness) {
70 .unsigned => 0,
71 .signed => 1,
72 },
73 });
74 },
75 // TODO: Verify that floatBits() will be correct.
76 .Float => try writeInstruction(&self.types_and_globals, .OpTypeFloat, &[_]u32{ result, t.floatBits(self.target) }),
77 .Null,
78 .Undefined,
79 .EnumLiteral,
80 .ComptimeFloat,
81 .ComptimeInt,
82 .Type,
83 => unreachable, // Must be const or comptime.
84
85 .BoundFn => unreachable, // this type will be deleted from the language.
86
87 else => return error.TODO,
88 }
89
90 try self.types.put(t, result);
91 return result;
46 }92 }
4793
48 pub fn genDecl(self: SPIRVModule, id: u32, code: *std.ArrayList(u32), decl: *Decl) !void {}94 pub fn gen(self: *SPIRVModule, decl: *Decl) !void {
95 const typed_value = decl.typed_value.most_recent.typed_value;
96
97 switch (typed_value.ty.zigTypeTag()) {
98 .Fn => {
99 log.debug("Generating code for function '{s}'", .{ std.mem.spanZ(decl.name) });
100
101 _ = try self.getOrGenType(typed_value.ty.fnReturnType());
102 },
103 else => return error.TODO,
104 }
105 }
49};106};
src/codegen/spirv/spec.zig+89-31
...@@ -1,26 +1,5 @@...@@ -1,26 +1,5 @@
1// Copyright (c) 2014-2020 The Khronos Group Inc.1//! This file is auto-generated by tools/gen_spirv_spec.zig.
2//2
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and/or associated documentation files (the "Materials"),
5// to deal in the Materials without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Materials, and to permit persons to whom the
8// Materials are furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Materials.
12//
13// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
14// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
15// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
16//
17// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
23// IN THE MATERIALS.
24const Version = @import("builtin").Version;3const Version = @import("builtin").Version;
25pub const version = Version{ .major = 1, .minor = 5, .patch = 4 };4pub const version = Version{ .major = 1, .minor = 5, .patch = 4 };
26pub const magic_number: u32 = 0x07230203;5pub const magic_number: u32 = 0x07230203;
...@@ -443,8 +422,15 @@ pub const Opcode = extern enum(u16) {...@@ -443,8 +422,15 @@ pub const Opcode = extern enum(u16) {
443 OpUSubSatINTEL = 5596,422 OpUSubSatINTEL = 5596,
444 OpIMul32x16INTEL = 5597,423 OpIMul32x16INTEL = 5597,
445 OpUMul32x16INTEL = 5598,424 OpUMul32x16INTEL = 5598,
446 OpFunctionPointerINTEL = 5600,425 OpConstFunctionPointerINTEL = 5600,
447 OpFunctionPointerCallINTEL = 5601,426 OpFunctionPointerCallINTEL = 5601,
427 OpAsmTargetINTEL = 5609,
428 OpAsmINTEL = 5610,
429 OpAsmCallINTEL = 5611,
430 OpAtomicFMinEXT = 5614,
431 OpAtomicFMaxEXT = 5615,
432 OpAssumeTrueKHR = 5630,
433 OpExpectKHR = 5631,
448 OpDecorateString = 5632,434 OpDecorateString = 5632,
449 OpDecorateStringGOOGLE = 5632,435 OpDecorateStringGOOGLE = 5632,
450 OpMemberDecorateString = 5633,436 OpMemberDecorateString = 5633,
...@@ -567,7 +553,12 @@ pub const Opcode = extern enum(u16) {...@@ -567,7 +553,12 @@ pub const Opcode = extern enum(u16) {
567 OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,553 OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
568 OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,554 OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
569 OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,555 OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
556 OpVariableLengthArrayINTEL = 5818,
557 OpSaveMemoryINTEL = 5819,
558 OpRestoreMemoryINTEL = 5820,
570 OpLoopControlINTEL = 5887,559 OpLoopControlINTEL = 5887,
560 OpPtrCastToCrossWorkgroupINTEL = 5934,
561 OpCrossWorkgroupCastToPtrINTEL = 5938,
571 OpReadPipeBlockingINTEL = 5946,562 OpReadPipeBlockingINTEL = 5946,
572 OpWritePipeBlockingINTEL = 5947,563 OpWritePipeBlockingINTEL = 5947,
573 OpFPGARegINTEL = 5949,564 OpFPGARegINTEL = 5949,
...@@ -589,6 +580,10 @@ pub const Opcode = extern enum(u16) {...@@ -589,6 +580,10 @@ pub const Opcode = extern enum(u16) {
589 OpRayQueryGetIntersectionObjectToWorldKHR = 6031,580 OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
590 OpRayQueryGetIntersectionWorldToObjectKHR = 6032,581 OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
591 OpAtomicFAddEXT = 6035,582 OpAtomicFAddEXT = 6035,
583 OpTypeBufferSurfaceINTEL = 6086,
584 OpTypeStructContinuedINTEL = 6090,
585 OpConstantCompositeContinuedINTEL = 6091,
586 OpSpecConstantCompositeContinuedINTEL = 6092,
592 _,587 _,
593};588};
594pub const ImageOperands = packed struct {589pub const ImageOperands = packed struct {
...@@ -642,8 +637,8 @@ pub const FPFastMathMode = packed struct {...@@ -642,8 +637,8 @@ pub const FPFastMathMode = packed struct {
642 _reserved_bit_13: bool = false,637 _reserved_bit_13: bool = false,
643 _reserved_bit_14: bool = false,638 _reserved_bit_14: bool = false,
644 _reserved_bit_15: bool = false,639 _reserved_bit_15: bool = false,
645 _reserved_bit_16: bool = false,640 AllowContractFastINTEL: bool = false,
646 _reserved_bit_17: bool = false,641 AllowReassocINTEL: bool = false,
647 _reserved_bit_18: bool = false,642 _reserved_bit_18: bool = false,
648 _reserved_bit_19: bool = false,643 _reserved_bit_19: bool = false,
649 _reserved_bit_20: bool = false,644 _reserved_bit_20: bool = false,
...@@ -717,7 +712,7 @@ pub const LoopControl = packed struct {...@@ -717,7 +712,7 @@ pub const LoopControl = packed struct {
717 LoopCoalesceINTEL: bool = false,712 LoopCoalesceINTEL: bool = false,
718 MaxInterleavingINTEL: bool = false,713 MaxInterleavingINTEL: bool = false,
719 SpeculatedIterationsINTEL: bool = false,714 SpeculatedIterationsINTEL: bool = false,
720 _reserved_bit_23: bool = false,715 NoFusionINTEL: bool = false,
721 _reserved_bit_24: bool = false,716 _reserved_bit_24: bool = false,
722 _reserved_bit_25: bool = false,717 _reserved_bit_25: bool = false,
723 _reserved_bit_26: bool = false,718 _reserved_bit_26: bool = false,
...@@ -1037,10 +1032,16 @@ pub const ExecutionMode = extern enum(u32) {...@@ -1037,10 +1032,16 @@ pub const ExecutionMode = extern enum(u32) {
1037 SampleInterlockUnorderedEXT = 5369,1032 SampleInterlockUnorderedEXT = 5369,
1038 ShadingRateInterlockOrderedEXT = 5370,1033 ShadingRateInterlockOrderedEXT = 5370,
1039 ShadingRateInterlockUnorderedEXT = 5371,1034 ShadingRateInterlockUnorderedEXT = 5371,
1035 SharedLocalMemorySizeINTEL = 5618,
1036 RoundingModeRTPINTEL = 5620,
1037 RoundingModeRTNINTEL = 5621,
1038 FloatingPointModeALTINTEL = 5622,
1039 FloatingPointModeIEEEINTEL = 5623,
1040 MaxWorkgroupSizeINTEL = 5893,1040 MaxWorkgroupSizeINTEL = 5893,
1041 MaxWorkDimINTEL = 5894,1041 MaxWorkDimINTEL = 5894,
1042 NoGlobalOffsetINTEL = 5895,1042 NoGlobalOffsetINTEL = 5895,
1043 NumSIMDWorkitemsINTEL = 5896,1043 NumSIMDWorkitemsINTEL = 5896,
1044 SchedulerTargetFmaxMhzINTEL = 5903,
1044 _,1045 _,
1045};1046};
1046pub const StorageClass = extern enum(u32) {1047pub const StorageClass = extern enum(u32) {
...@@ -1072,6 +1073,8 @@ pub const StorageClass = extern enum(u32) {...@@ -1072,6 +1073,8 @@ pub const StorageClass = extern enum(u32) {
1072 PhysicalStorageBuffer = 5349,1073 PhysicalStorageBuffer = 5349,
1073 PhysicalStorageBufferEXT = 5349,1074 PhysicalStorageBufferEXT = 5349,
1074 CodeSectionINTEL = 5605,1075 CodeSectionINTEL = 5605,
1076 DeviceOnlyINTEL = 5936,
1077 HostOnlyINTEL = 5937,
1075 _,1078 _,
1076};1079};
1077pub const Dim = extern enum(u32) {1080pub const Dim = extern enum(u32) {
...@@ -1192,9 +1195,20 @@ pub const FPRoundingMode = extern enum(u32) {...@@ -1192,9 +1195,20 @@ pub const FPRoundingMode = extern enum(u32) {
1192 RTN = 3,1195 RTN = 3,
1193 _,1196 _,
1194};1197};
1198pub const FPDenormMode = extern enum(u32) {
1199 Preserve = 0,
1200 FlushToZero = 1,
1201 _,
1202};
1203pub const FPOperationMode = extern enum(u32) {
1204 IEEE = 0,
1205 ALT = 1,
1206 _,
1207};
1195pub const LinkageType = extern enum(u32) {1208pub const LinkageType = extern enum(u32) {
1196 Export = 0,1209 Export = 0,
1197 Import = 1,1210 Import = 1,
1211 LinkOnceODR = 2,
1198 _,1212 _,
1199};1213};
1200pub const AccessQualifier = extern enum(u32) {1214pub const AccessQualifier = extern enum(u32) {
...@@ -1279,12 +1293,22 @@ pub const Decoration = extern enum(u32) {...@@ -1279,12 +1293,22 @@ pub const Decoration = extern enum(u32) {
1279 RestrictPointerEXT = 5355,1293 RestrictPointerEXT = 5355,
1280 AliasedPointer = 5356,1294 AliasedPointer = 5356,
1281 AliasedPointerEXT = 5356,1295 AliasedPointerEXT = 5356,
1296 SIMTCallINTEL = 5599,
1282 ReferencedIndirectlyINTEL = 5602,1297 ReferencedIndirectlyINTEL = 5602,
1298 ClobberINTEL = 5607,
1299 SideEffectsINTEL = 5608,
1300 VectorComputeVariableINTEL = 5624,
1301 FuncParamIOKindINTEL = 5625,
1302 VectorComputeFunctionINTEL = 5626,
1303 StackCallINTEL = 5627,
1304 GlobalVariableOffsetINTEL = 5628,
1283 CounterBuffer = 5634,1305 CounterBuffer = 5634,
1284 HlslCounterBufferGOOGLE = 5634,1306 HlslCounterBufferGOOGLE = 5634,
1285 UserSemantic = 5635,1307 UserSemantic = 5635,
1286 HlslSemanticGOOGLE = 5635,1308 HlslSemanticGOOGLE = 5635,
1287 UserTypeGOOGLE = 5636,1309 UserTypeGOOGLE = 5636,
1310 FunctionRoundingModeINTEL = 5822,
1311 FunctionDenormModeINTEL = 5823,
1288 RegisterINTEL = 5825,1312 RegisterINTEL = 5825,
1289 MemoryINTEL = 5826,1313 MemoryINTEL = 5826,
1290 NumbanksINTEL = 5827,1314 NumbanksINTEL = 5827,
...@@ -1297,6 +1321,17 @@ pub const Decoration = extern enum(u32) {...@@ -1297,6 +1321,17 @@ pub const Decoration = extern enum(u32) {
1297 MergeINTEL = 5834,1321 MergeINTEL = 5834,
1298 BankBitsINTEL = 5835,1322 BankBitsINTEL = 5835,
1299 ForcePow2DepthINTEL = 5836,1323 ForcePow2DepthINTEL = 5836,
1324 BurstCoalesceINTEL = 5899,
1325 CacheSizeINTEL = 5900,
1326 DontStaticallyCoalesceINTEL = 5901,
1327 PrefetchINTEL = 5902,
1328 StallEnableINTEL = 5905,
1329 FuseLoopsInFunctionINTEL = 5907,
1330 BufferLocationINTEL = 5921,
1331 IOPipeStorageINTEL = 5944,
1332 FunctionFloatingPointModeINTEL = 6080,
1333 SingleElementVectorINTEL = 6085,
1334 VectorComputeCallableFunctionINTEL = 6087,
1300 _,1335 _,
1301};1336};
1302pub const BuiltIn = extern enum(u32) {1337pub const BuiltIn = extern enum(u32) {
...@@ -1342,14 +1377,14 @@ pub const BuiltIn = extern enum(u32) {...@@ -1342,14 +1377,14 @@ pub const BuiltIn = extern enum(u32) {
1342 VertexIndex = 42,1377 VertexIndex = 42,
1343 InstanceIndex = 43,1378 InstanceIndex = 43,
1344 SubgroupEqMask = 4416,1379 SubgroupEqMask = 4416,
1345 SubgroupGeMask = 4417,
1346 SubgroupGtMask = 4418,
1347 SubgroupLeMask = 4419,
1348 SubgroupLtMask = 4420,
1349 SubgroupEqMaskKHR = 4416,1380 SubgroupEqMaskKHR = 4416,
1381 SubgroupGeMask = 4417,
1350 SubgroupGeMaskKHR = 4417,1382 SubgroupGeMaskKHR = 4417,
1383 SubgroupGtMask = 4418,
1351 SubgroupGtMaskKHR = 4418,1384 SubgroupGtMaskKHR = 4418,
1385 SubgroupLeMask = 4419,
1352 SubgroupLeMaskKHR = 4419,1386 SubgroupLeMaskKHR = 4419,
1387 SubgroupLtMask = 4420,
1353 SubgroupLtMaskKHR = 4420,1388 SubgroupLtMaskKHR = 4420,
1354 BaseVertex = 4424,1389 BaseVertex = 4424,
1355 BaseInstance = 4425,1390 BaseInstance = 4425,
...@@ -1520,6 +1555,9 @@ pub const Capability = extern enum(u32) {...@@ -1520,6 +1555,9 @@ pub const Capability = extern enum(u32) {
1520 FragmentShadingRateKHR = 4422,1555 FragmentShadingRateKHR = 4422,
1521 SubgroupBallotKHR = 4423,1556 SubgroupBallotKHR = 4423,
1522 DrawParameters = 4427,1557 DrawParameters = 4427,
1558 WorkgroupMemoryExplicitLayoutKHR = 4428,
1559 WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
1560 WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
1523 SubgroupVoteKHR = 4431,1561 SubgroupVoteKHR = 4431,
1524 StorageBuffer16BitAccess = 4433,1562 StorageBuffer16BitAccess = 4433,
1525 StorageUniformBufferBlock16 = 4433,1563 StorageUniformBufferBlock16 = 4433,
...@@ -1610,21 +1648,41 @@ pub const Capability = extern enum(u32) {...@@ -1610,21 +1648,41 @@ pub const Capability = extern enum(u32) {
1610 SubgroupBufferBlockIOINTEL = 5569,1648 SubgroupBufferBlockIOINTEL = 5569,
1611 SubgroupImageBlockIOINTEL = 5570,1649 SubgroupImageBlockIOINTEL = 5570,
1612 SubgroupImageMediaBlockIOINTEL = 5579,1650 SubgroupImageMediaBlockIOINTEL = 5579,
1651 RoundToInfinityINTEL = 5582,
1652 FloatingPointModeINTEL = 5583,
1613 IntegerFunctions2INTEL = 5584,1653 IntegerFunctions2INTEL = 5584,
1614 FunctionPointersINTEL = 5603,1654 FunctionPointersINTEL = 5603,
1615 IndirectReferencesINTEL = 5604,1655 IndirectReferencesINTEL = 5604,
1656 AsmINTEL = 5606,
1657 AtomicFloat32MinMaxEXT = 5612,
1658 AtomicFloat64MinMaxEXT = 5613,
1659 AtomicFloat16MinMaxEXT = 5616,
1660 VectorComputeINTEL = 5617,
1661 VectorAnyINTEL = 5619,
1662 ExpectAssumeKHR = 5629,
1616 SubgroupAvcMotionEstimationINTEL = 5696,1663 SubgroupAvcMotionEstimationINTEL = 5696,
1617 SubgroupAvcMotionEstimationIntraINTEL = 5697,1664 SubgroupAvcMotionEstimationIntraINTEL = 5697,
1618 SubgroupAvcMotionEstimationChromaINTEL = 5698,1665 SubgroupAvcMotionEstimationChromaINTEL = 5698,
1666 VariableLengthArrayINTEL = 5817,
1667 FunctionFloatControlINTEL = 5821,
1619 FPGAMemoryAttributesINTEL = 5824,1668 FPGAMemoryAttributesINTEL = 5824,
1669 FPFastMathModeINTEL = 5837,
1670 ArbitraryPrecisionIntegersINTEL = 5844,
1620 UnstructuredLoopControlsINTEL = 5886,1671 UnstructuredLoopControlsINTEL = 5886,
1621 FPGALoopControlsINTEL = 5888,1672 FPGALoopControlsINTEL = 5888,
1622 KernelAttributesINTEL = 5892,1673 KernelAttributesINTEL = 5892,
1623 FPGAKernelAttributesINTEL = 5897,1674 FPGAKernelAttributesINTEL = 5897,
1675 FPGAMemoryAccessesINTEL = 5898,
1676 FPGAClusterAttributesINTEL = 5904,
1677 LoopFuseINTEL = 5906,
1678 FPGABufferLocationINTEL = 5920,
1679 USMStorageClassesINTEL = 5935,
1680 IOPipesINTEL = 5943,
1624 BlockingPipesINTEL = 5945,1681 BlockingPipesINTEL = 5945,
1625 FPGARegINTEL = 5948,1682 FPGARegINTEL = 5948,
1626 AtomicFloat32AddEXT = 6033,1683 AtomicFloat32AddEXT = 6033,
1627 AtomicFloat64AddEXT = 6034,1684 AtomicFloat64AddEXT = 6034,
1685 LongConstantCompositeINTEL = 6089,
1628 _,1686 _,
1629};1687};
1630pub const RayQueryIntersection = extern enum(u32) {1688pub const RayQueryIntersection = extern enum(u32) {
src/link/SpirV.zig+56-63
...@@ -16,11 +16,16 @@...@@ -16,11 +16,16 @@
16//! All function declarations without a body (extern functions presumably).16//! All function declarations without a body (extern functions presumably).
17//! All regular functions.17//! All regular functions.
1818
19// Because SPIR-V requires re-compilation anyway, and so hot swapping will not work
20// anyway, we simply generate all the code in flushModule. This keeps
21// things considerably simpler.
22
19const SpirV = @This();23const SpirV = @This();
2024
21const std = @import("std");25const std = @import("std");
22const Allocator = std.mem.Allocator;26const Allocator = std.mem.Allocator;
23const assert = std.debug.assert;27const assert = std.debug.assert;
28const log = std.log.scoped(.link);
2429
25const Module = @import("../Module.zig");30const Module = @import("../Module.zig");
26const Compilation = @import("../Compilation.zig");31const Compilation = @import("../Compilation.zig");
...@@ -30,16 +35,15 @@ const trace = @import("../tracy.zig").trace;...@@ -30,16 +35,15 @@ const trace = @import("../tracy.zig").trace;
30const build_options = @import("build_options");35const build_options = @import("build_options");
31const spec = @import("../codegen/spirv/spec.zig");36const spec = @import("../codegen/spirv/spec.zig");
3237
38// TODO: Should this struct be used at all rather than just a hashmap of aux data for every decl?
33pub const FnData = struct {39pub const FnData = struct {
34 id: ?u32 = null,40 // We're going to fill these in flushModule, and we're going to fill them unconditionally,
35 code: std.ArrayListUnmanaged(u32) = .{},41 // so just set it to undefined.
42 id: u32 = undefined
36};43};
3744
38base: link.File,45base: link.File,
3946
40// TODO: Does this file need to support multiple independent modules?
41spirv_module: codegen.SPIRVModule,
42
43pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {47pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {
44 const spirv = try gpa.create(SpirV);48 const spirv = try gpa.create(SpirV);
45 spirv.* = .{49 spirv.* = .{
...@@ -49,7 +53,6 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {...@@ -49,7 +53,6 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {
49 .file = null,53 .file = null,
50 .allocator = gpa,54 .allocator = gpa,
51 },55 },
52 .spirv_module = codegen.SPIRVModule.init(gpa),
53 };56 };
5457
55 // TODO: Figure out where to put all of these58 // TODO: Figure out where to put all of these
...@@ -87,28 +90,9 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -87,28 +90,9 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
87 return spirv;90 return spirv;
88}91}
8992
90pub fn deinit(self: *SpirV) void {93pub fn deinit(self: *SpirV) void {}
91 self.spirv_module.deinit();
92}
93
94pub fn updateDecl(self: *SpirV, module: *Module, decl: *Module.Decl) !void {
95 const tracy = trace(@src());
96 defer tracy.end();
97
98 const fn_data = &decl.fn_link.spirv;
99 if (fn_data.id == null) {
100 fn_data.id = self.spirv_module.allocId();
101 }
102
103 var managed_code = fn_data.code.toManaged(self.base.allocator);
104 managed_code.items.len = 0;
105
106 try self.spirv_module.genDecl(fn_data.id.?, &managed_code, decl);
107 fn_data.code = managed_code.toUnmanaged();
10894
109 // Free excess allocated memory for this Decl.95pub fn updateDecl(self: *SpirV, module: *Module, decl: *Module.Decl) !void {}
110 fn_data.code.shrinkAndFree(self.base.allocator, fn_data.code.items.len);
111}
11296
113pub fn updateDeclExports(97pub fn updateDeclExports(
114 self: *SpirV,98 self: *SpirV,
...@@ -117,12 +101,7 @@ pub fn updateDeclExports(...@@ -117,12 +101,7 @@ pub fn updateDeclExports(
117 exports: []const *Module.Export,101 exports: []const *Module.Export,
118) !void {}102) !void {}
119103
120pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {104pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {}
121 var fn_data = decl.fn_link.spirv;
122 fn_data.code.deinit(self.base.allocator);
123 if (fn_data.id) |id| self.spirv_module.freeId(id);
124 decl.fn_link.spirv = undefined;
125}
126105
127pub fn flush(self: *SpirV, comp: *Compilation) !void {106pub fn flush(self: *SpirV, comp: *Compilation) !void {
128 if (build_options.have_llvm and self.base.options.use_lld) {107 if (build_options.have_llvm and self.base.options.use_lld) {
...@@ -139,55 +118,69 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {...@@ -139,55 +118,69 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
139 const module = self.base.options.module.?;118 const module = self.base.options.module.?;
140 const target = comp.getTarget();119 const target = comp.getTarget();
141120
121 var spirv_module = codegen.SPIRVModule.init(target, self.base.allocator);
122 defer spirv_module.deinit();
123
124 // Allocate an ID for every declaration before generating code,
125 // so that we can access them before processing them.
126 // TODO: We're allocating an ID unconditionally now, are there
127 // declarations which don't generate a result?
128 // TODO: fn_link is used here, but thats probably not the right field. It will work anyway though.
129 {
130 for (module.decl_table.items()) |entry| {
131 const decl = entry.value;
132 if (decl.typed_value != .most_recent)
133 continue;
134
135 decl.fn_link.spirv.id = spirv_module.allocResultId();
136 log.debug("Allocating id {} to '{s}'", .{ decl.fn_link.spirv.id, std.mem.spanZ(decl.name) });
137 }
138 }
139
140 // Now, actually generate the code for all declarations.
141 {
142 for (module.decl_table.items()) |entry| {
143 const decl = entry.value;
144 if (decl.typed_value != .most_recent)
145 continue;
146
147 try spirv_module.gen(decl);
148 }
149 }
150
142 var binary = std.ArrayList(u32).init(self.base.allocator);151 var binary = std.ArrayList(u32).init(self.base.allocator);
143 defer binary.deinit();152 defer binary.deinit();
144153
145 // Note: The order of adding sections to the final binary
146 // follows the SPIR-V logical module format!
147
148 try binary.appendSlice(&[_]u32{154 try binary.appendSlice(&[_]u32{
149 spec.magic_number,155 spec.magic_number,
150 (spec.version.major << 16) | (spec.version.minor << 8),156 (spec.version.major << 16) | (spec.version.minor << 8),
151 0, // TODO: Register Zig compiler magic number.157 0, // TODO: Register Zig compiler magic number.
152 self.spirv_module.idBound(),158 spirv_module.resultIdBound(), // ID bound.
153 0, // Schema (currently reserved for future use in the SPIR-V spec).159 0, // Schema (currently reserved for future use in the SPIR-V spec).
154 });160 });
155161
156 try writeCapabilities(&binary, target);162 try writeCapabilities(&binary, target);
157 try writeMemoryModel(&binary, target);163 try writeMemoryModel(&binary, target);
158164
159 // Collect list of buffers to write.165 // Note: The order of adding sections to the final binary
160 // SPIR-V files support both little and big endian words. The actual format is166 // follows the SPIR-V logical module format!
161 // disambiguated by the magic number, and so theoretically we don't need to worry167 var all_buffers = [_]std.os.iovec_const{
162 // about endian-ness when writing the final binary.168 wordsToIovConst(binary.items),
163 var all_buffers = std.ArrayList(std.os.iovec_const).init(self.base.allocator);169 wordsToIovConst(spirv_module.types_and_globals.items),
164 defer all_buffers.deinit();170 wordsToIovConst(spirv_module.fn_decls.items),
165171 };
166 // Pre-allocate enough for the binary info + all functions172
167 try all_buffers.ensureCapacity(module.decl_table.count() + 1);173 const file = self.base.file.?;
168174 const bytes = std.mem.sliceAsBytes(binary.items);
169 all_buffers.appendAssumeCapacity(wordsToIovConst(binary.items));
170
171 for (module.decl_table.items()) |entry| {
172 const decl = entry.value;
173 switch (decl.typed_value) {
174 .most_recent => |tvm| {
175 const fn_data = &decl.fn_link.spirv;
176 all_buffers.appendAssumeCapacity(wordsToIovConst(fn_data.code.items));
177 },
178 .never_succeeded => continue,
179 }
180 }
181175
182 var file_size: u64 = 0;176 var file_size: u64 = 0;
183 for (all_buffers.items) |iov| {177 for (all_buffers) |iov| {
184 file_size += iov.iov_len;178 file_size += iov.iov_len;
185 }179 }
186180
187 const file = self.base.file.?;
188 try file.seekTo(0);181 try file.seekTo(0);
189 try file.setEndPos(file_size);182 try file.setEndPos(file_size);
190 try file.pwritevAll(all_buffers.items, 0);183 try file.pwritevAll(&all_buffers, 0);
191}184}
192185
193fn writeCapabilities(binary: *std.ArrayList(u32), target: std.Target) !void {186fn writeCapabilities(binary: *std.ArrayList(u32), target: std.Target) !void {
...@@ -231,4 +224,4 @@ fn wordsToIovConst(words: []const u32) std.os.iovec_const {...@@ -231,4 +224,4 @@ fn wordsToIovConst(words: []const u32) std.os.iovec_const {
231 .iov_base = bytes.ptr,224 .iov_base = bytes.ptr,
232 .iov_len = bytes.len,225 .iov_len = bytes.len,
233 };226 };
234}227}
\ No newline at end of file
tools/gen_spirv_spec.zig+25-122
...@@ -1,96 +1,5 @@...@@ -1,96 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const Writer = std.ArrayList(u8).Writer;2const g = @import("spirv/grammar.zig");
3
4//! See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
5//! and the files in https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/unified1/
6//! Note: Non-canonical casing in these structs used to match SPIR-V spec json.
7const Registry = union(enum) {
8 core: CoreRegistry,
9 extension: ExtensionRegistry,
10};
11
12const CoreRegistry = struct {
13 copyright: [][]const u8,
14 /// Hexadecimal representation of the magic number
15 magic_number: []const u8,
16 major_version: u32,
17 minor_version: u32,
18 revision: u32,
19 instruction_printing_class: []InstructionPrintingClass,
20 instructions: []Instruction,
21 operand_kinds: []OperandKind,
22};
23
24const ExtensionRegistry = struct {
25 copyright: [][]const u8,
26 version: u32,
27 revision: u32,
28 instructions: []Instruction,
29 operand_kinds: []OperandKind = &[_]OperandKind{},
30};
31
32const InstructionPrintingClass = struct {
33 tag: []const u8,
34 heading: ?[]const u8 = null,
35};
36
37const Instruction = struct {
38 opname: []const u8,
39 class: ?[]const u8 = null, // Note: Only available in the core registry.
40 opcode: u32,
41 operands: []Operand = &[_]Operand{},
42 capabilities: [][]const u8 = &[_][]const u8{},
43 extensions: [][]const u8 = &[_][]const u8{},
44 version: ?[]const u8 = null,
45
46 lastVersion: ?[]const u8 = null,
47};
48
49const Operand = struct {
50 kind: []const u8,
51 /// If this field is 'null', the operand is only expected once.
52 quantifier: ?Quantifier = null,
53 name: []const u8 = "",
54};
55
56const Quantifier = enum {
57 /// zero or once
58 @"?",
59 /// zero or more
60 @"*",
61};
62
63const OperandCategory = enum {
64 BitEnum,
65 ValueEnum,
66 Id,
67 Literal,
68 Composite,
69};
70
71const OperandKind = struct {
72 category: OperandCategory,
73 /// The name
74 kind: []const u8,
75 doc: ?[]const u8 = null,
76 enumerants: ?[]Enumerant = null,
77 bases: ?[]const []const u8 = null,
78};
79
80const Enumerant = struct {
81 enumerant: []const u8,
82 value: union(enum) {
83 bitflag: []const u8, // Hexadecimal representation of the value
84 int: u31,
85 },
86 capabilities: [][]const u8 = &[_][]const u8{},
87 /// Valid for .ValueEnum and .BitEnum
88 extensions: [][]const u8 = &[_][]const u8{},
89 /// `quantifier` will always be `null`.
90 parameters: []Operand = &[_]Operand{},
91 version: ?[]const u8 = null,
92 lastVersion: ?[]const u8 = null,
93};
943
95pub fn main() !void {4pub fn main() !void {
96 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);5 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
...@@ -106,24 +15,25 @@ pub fn main() !void {...@@ -106,24 +15,25 @@ pub fn main() !void {
106 const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));15 const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));
10716
108 var tokens = std.json.TokenStream.init(spec);17 var tokens = std.json.TokenStream.init(spec);
109 var registry = try std.json.parse(Registry, &tokens, .{.allocator = allocator});18 var registry = try std.json.parse(g.Registry, &tokens, .{.allocator = allocator});
11019
111 var buf = std.ArrayList(u8).init(allocator);20 var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
112 defer buf.deinit();21 try render(bw.writer(), registry);
11322 try bw.flush();
114 try render(buf.writer(), registry);
115
116 const tree = try std.zig.parse(allocator, buf.items);
117 _ = try std.zig.render(allocator, std.io.getStdOut().writer(), tree);
118}23}
11924
120fn render(writer: Writer, registry: Registry) !void {25fn render(writer: anytype, registry: g.Registry) !void {
26 try writer.writeAll(
27 \\//! This file is auto-generated by tools/gen_spirv_spec.zig.
28 \\
29 \\const Version = @import("builtin").Version;
30 \\
31 );
32
121 switch (registry) {33 switch (registry) {
122 .core => |core_reg| {34 .core => |core_reg| {
123 try renderCopyRight(writer, core_reg.copyright);
124 try writer.print(35 try writer.print(
125 \\const Version = @import("builtin").Version;36 \\pub const version = Version{{ .major = {}, .minor = {}, .patch = {} }};
126 \\pub const version = Version{{.major = {}, .minor = {}, .patch = {}}};
127 \\pub const magic_number: u32 = {s};37 \\pub const magic_number: u32 = {s};
128 \\38 \\
129 , .{ core_reg.major_version, core_reg.minor_version, core_reg.revision, core_reg.magic_number },39 , .{ core_reg.major_version, core_reg.minor_version, core_reg.revision, core_reg.magic_number },
...@@ -132,10 +42,8 @@ fn render(writer: Writer, registry: Registry) !void {...@@ -132,10 +42,8 @@ fn render(writer: Writer, registry: Registry) !void {
132 try renderOperandKinds(writer, core_reg.operand_kinds);42 try renderOperandKinds(writer, core_reg.operand_kinds);
133 },43 },
134 .extension => |ext_reg| {44 .extension => |ext_reg| {
135 try renderCopyRight(writer, ext_reg.copyright);
136 try writer.print(45 try writer.print(
137 \\const Version = @import("builtin").Version;46 \\pub const version = Version{{ .major = {}, .minor = 0, .patch = {} }};
138 \\pub const version = Version{{.major = {}, .minor = 0, .patch = {}}};
139 \\47 \\
140 , .{ ext_reg.version, ext_reg.revision },48 , .{ ext_reg.version, ext_reg.revision },
141 );49 );
...@@ -145,21 +53,15 @@ fn render(writer: Writer, registry: Registry) !void {...@@ -145,21 +53,15 @@ fn render(writer: Writer, registry: Registry) !void {
145 }53 }
146}54}
14755
148fn renderCopyRight(writer: Writer, copyright: []const []const u8) !void {56fn renderOpcodes(writer: anytype, instructions: []const g.Instruction) !void {
149 for (copyright) |line| {
150 try writer.print("// {s}\n", .{ line });
151 }
152}
153
154fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {
155 try writer.writeAll("pub const Opcode = extern enum(u16) {\n");57 try writer.writeAll("pub const Opcode = extern enum(u16) {\n");
156 for (instructions) |instr| {58 for (instructions) |instr| {
157 try writer.print("{} = {},\n", .{ std.zig.fmtId(instr.opname), instr.opcode });59 try writer.print(" {} = {},\n", .{ std.zig.fmtId(instr.opname), instr.opcode });
158 }60 }
159 try writer.writeAll("_,\n};\n");61 try writer.writeAll(" _,\n};\n");
160}62}
16163
162fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {64fn renderOperandKinds(writer: anytype, kinds: []const g.OperandKind) !void {
163 for (kinds) |kind| {65 for (kinds) |kind| {
164 switch (kind.category) {66 switch (kind.category) {
165 .ValueEnum => try renderValueEnum(writer, kind),67 .ValueEnum => try renderValueEnum(writer, kind),
...@@ -169,20 +71,20 @@ fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {...@@ -169,20 +71,20 @@ fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {
169 }71 }
170}72}
17173
172fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {74fn renderValueEnum(writer: anytype, enumeration: g.OperandKind) !void {
173 try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });75 try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });
17476
175 const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;77 const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;
176 for (enumerants) |enumerant| {78 for (enumerants) |enumerant| {
177 if (enumerant.value != .int) return error.InvalidRegistry;79 if (enumerant.value != .int) return error.InvalidRegistry;
17880
179 try writer.print("{} = {},\n", .{ std.zig.fmtId(enumerant.enumerant), enumerant.value.int });81 try writer.print(" {} = {},\n", .{ std.zig.fmtId(enumerant.enumerant), enumerant.value.int });
180 }82 }
18183
182 try writer.writeAll("_,\n};\n");84 try writer.writeAll(" _,\n};\n");
183}85}
18486
185fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {87fn renderBitEnum(writer: anytype, enumeration: g.OperandKind) !void {
186 try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });88 try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });
18789
188 var flags_by_bitpos = [_]?[]const u8{null} ** 32;90 var flags_by_bitpos = [_]?[]const u8{null} ** 32;
...@@ -205,6 +107,7 @@ fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {...@@ -205,6 +107,7 @@ fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {
205 }107 }
206108
207 for (flags_by_bitpos) |maybe_flag_name, bitpos| {109 for (flags_by_bitpos) |maybe_flag_name, bitpos| {
110 try writer.writeAll(" ");
208 if (maybe_flag_name) |flag_name| {111 if (maybe_flag_name) |flag_name| {
209 try writer.writeAll(flag_name);112 try writer.writeAll(flag_name);
210 } else {113 } else {
...@@ -215,7 +118,7 @@ fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {...@@ -215,7 +118,7 @@ fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {
215 if (bitpos == 0) { // Force alignment to integer boundaries118 if (bitpos == 0) { // Force alignment to integer boundaries
216 try writer.writeAll("align(@alignOf(u32)) ");119 try writer.writeAll("align(@alignOf(u32)) ");
217 }120 }
218 try writer.writeAll("= false, ");121 try writer.writeAll("= false,\n");
219 }122 }
220123
221 try writer.writeAll("};\n");124 try writer.writeAll("};\n");
tools/spirv/grammar.zig created+90
...@@ -0,0 +1,90 @@
1//! See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
2//! and the files in https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/unified1/
3//! Note: Non-canonical casing in these structs used to match SPIR-V spec json.
4pub const Registry = union(enum) {
5 core: CoreRegistry,
6 extension: ExtensionRegistry,
7};
8
9pub const CoreRegistry = struct {
10 copyright: [][]const u8,
11 /// Hexadecimal representation of the magic number
12 magic_number: []const u8,
13 major_version: u32,
14 minor_version: u32,
15 revision: u32,
16 instruction_printing_class: []InstructionPrintingClass,
17 instructions: []Instruction,
18 operand_kinds: []OperandKind,
19};
20
21pub const ExtensionRegistry = struct {
22 copyright: [][]const u8,
23 version: u32,
24 revision: u32,
25 instructions: []Instruction,
26 operand_kinds: []OperandKind = &[_]OperandKind{},
27};
28
29pub const InstructionPrintingClass = struct {
30 tag: []const u8,
31 heading: ?[]const u8 = null,
32};
33
34pub const Instruction = struct {
35 opname: []const u8,
36 class: ?[]const u8 = null, // Note: Only available in the core registry.
37 opcode: u32,
38 operands: []Operand = &[_]Operand{},
39 capabilities: [][]const u8 = &[_][]const u8{},
40 extensions: [][]const u8 = &[_][]const u8{},
41 version: ?[]const u8 = null,
42
43 lastVersion: ?[]const u8 = null,
44};
45
46pub const Operand = struct {
47 kind: []const u8,
48 /// If this field is 'null', the operand is only expected once.
49 quantifier: ?Quantifier = null,
50 name: []const u8 = "",
51};
52
53pub const Quantifier = enum {
54 /// zero or once
55 @"?",
56 /// zero or more
57 @"*",
58};
59
60pub const OperandCategory = enum {
61 BitEnum,
62 ValueEnum,
63 Id,
64 Literal,
65 Composite,
66};
67
68pub const OperandKind = struct {
69 category: OperandCategory,
70 /// The name
71 kind: []const u8,
72 doc: ?[]const u8 = null,
73 enumerants: ?[]Enumerant = null,
74 bases: ?[]const []const u8 = null,
75};
76
77pub const Enumerant = struct {
78 enumerant: []const u8,
79 value: union(enum) {
80 bitflag: []const u8, // Hexadecimal representation of the value
81 int: u31,
82 },
83 capabilities: [][]const u8 = &[_][]const u8{},
84 /// Valid for .ValueEnum and .BitEnum
85 extensions: [][]const u8 = &[_][]const u8{},
86 /// `quantifier` will always be `null`.
87 parameters: []Operand = &[_]Operand{},
88 version: ?[]const u8 = null,
89 lastVersion: ?[]const u8 = null,
90};
tools/update_spirv_features.zig created+321
...@@ -0,0 +1,321 @@
1const std = @import("std");
2const fs = std.fs;
3const Allocator = std.mem.Allocator;
4const g = @import("spirv/grammar.zig");
5
6//! This tool generates SPIR-V features from the grammar files in the SPIRV-Headers
7//! (https://github.com/KhronosGroup/SPIRV-Headers/) and SPIRV-Registry (https://github.com/KhronosGroup/SPIRV-Registry/)
8//! repositories. Currently it only generates a basic feature set definition consisting of versions, extensions and capabilities.
9//! There is a lot left to be desired, as currently dependencies of extensions and dependencies on extensions aren't generated.
10//! This is because there are some peculiarities in the SPIR-V registries:
11//! - Capabilities may depend on multiple extensions, which cannot be modelled yet by std.Target.
12//! - Extension dependencies are not documented in a machine-readable manner.
13//! - Note that the grammar spec also contains definitions from extensions which aren't actually official. Most of these seem to be
14//! from an intel project (https://github.com/intel/llvm/, https://github.com/intel/llvm/tree/sycl/sycl/doc/extensions/SPIRV),
15//! and so ONLY extensions in the SPIRV-Registry should be included.
16
17const Version = struct {
18 major: u32,
19 minor: u32,
20
21 fn parse(str: []const u8) !Version {
22 var it = std.mem.split(str, ".");
23
24 const major = it.next() orelse return error.InvalidVersion;
25 const minor = it.next() orelse return error.InvalidVersion;
26
27 if (it.next() != null) return error.InvalidVersion;
28
29 return Version{
30 .major = std.fmt.parseInt(u32, major, 10) catch return error.InvalidVersion,
31 .minor = std.fmt.parseInt(u32, minor, 10) catch return error.InvalidVersion,
32 };
33 }
34
35 fn eql(a: Version, b: Version) bool {
36 return a.major == b.major and a.minor == b.minor;
37 }
38
39 fn lessThan(ctx: void, a: Version, b: Version) bool {
40 return if (a.major == b.major)
41 a.minor < b.minor
42 else
43 a.major < b.major;
44 }
45};
46
47pub fn main() !void {
48 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
49 defer arena.deinit();
50 const allocator = &arena.allocator;
51
52 const args = try std.process.argsAlloc(allocator);
53
54 if (args.len <= 1) {
55 usageAndExit(std.io.getStdErr(), args[0], 1);
56 }
57 if (std.mem.eql(u8, args[1], "--help")) {
58 usageAndExit(std.io.getStdErr(), args[0], 0);
59 }
60 if (args.len != 3) {
61 usageAndExit(std.io.getStdErr(), args[0], 1);
62 }
63
64 const spirv_headers_root = args[1];
65 const spirv_registry_root = args[2];
66
67 if (std.mem.startsWith(u8, spirv_headers_root, "-") or std.mem.startsWith(u8, spirv_registry_root, "-")) {
68 usageAndExit(std.io.getStdErr(), args[0], 1);
69 }
70
71 const registry_path = try fs.path.join(allocator, &.{ spirv_headers_root, "include", "spirv", "unified1", "spirv.core.grammar.json" });
72 const registry_json = try std.fs.cwd().readFileAlloc(allocator, registry_path, std.math.maxInt(usize));
73 var tokens = std.json.TokenStream.init(registry_json);
74 const registry = try std.json.parse(g.CoreRegistry, &tokens, .{ .allocator = allocator });
75
76 const capabilities = for (registry.operand_kinds) |opkind| {
77 if (std.mem.eql(u8, opkind.kind, "Capability"))
78 break opkind.enumerants orelse return error.InvalidRegistry;
79 } else return error.InvalidRegistry;
80
81 const extensions = try gather_extensions(allocator, spirv_registry_root);
82 const versions = try gatherVersions(allocator, registry);
83
84 var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
85 const w = bw.writer();
86
87 try w.writeAll(
88 \\//! This file is auto-generated by tools/update_spirv_features.zig.
89 \\//! TODO: Dependencies of capabilities on extensions.
90 \\//! TODO: Dependencies of extensions on extensions.
91 \\//! TODO: Dependencies of extensions on versions.
92 \\
93 \\const std = @import("../std.zig");
94 \\const CpuFeature = std.Target.Cpu.Feature;
95 \\const CpuModel = std.Target.Cpu.Model;
96 \\
97 \\pub const Feature = enum {
98 \\
99 );
100
101 for (versions) |ver| {
102 try w.print(" v{}_{},\n", .{ ver.major, ver.minor });
103 }
104
105 for (extensions) |ext| {
106 try w.print(" {},\n", .{ std.zig.fmtId(ext) });
107 }
108
109 for (capabilities) |cap| {
110 try w.print(" {},\n", .{ std.zig.fmtId(cap.enumerant) });
111 }
112
113 try w.writeAll(
114 \\};
115 \\
116 \\pub usingnamespace CpuFeature.feature_set_fns(Feature);
117 \\
118 \\pub const all_features = blk: {
119 \\ @setEvalBranchQuota(2000);
120 \\ const len = @typeInfo(Feature).Enum.fields.len;
121 \\ std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
122 \\ var result: [len]CpuFeature = undefined;
123 \\
124 );
125
126 for (versions) |ver, i| {
127 try w.print(
128 \\ result[@enumToInt(Feature.v{0}_{1})] = .{{
129 \\ .llvm_name = null,
130 \\ .description = "SPIR-V version {0}.{1}",
131 \\
132 , .{ ver.major, ver.minor }
133 );
134
135 if (i == 0) {
136 try w.writeAll(
137 \\ .dependencies = featureSet(&[_]Feature{}),
138 \\ };
139 \\
140 );
141 } else {
142 try w.print(
143 \\ .dependencies = featureSet(&[_]Feature{{
144 \\ .v{}_{},
145 \\ }}),
146 \\ }};
147 \\
148 , .{ versions[i - 1].major, versions[i - 1].minor }
149 );
150 }
151 }
152
153 // TODO: Extension dependencies.
154 for (extensions) |ext| {
155 try w.print(
156 \\ result[@enumToInt(Feature.{s})] = .{{
157 \\ .llvm_name = null,
158 \\ .description = "SPIR-V extension {s}",
159 \\ .dependencies = featureSet(&[_]Feature{{}}),
160 \\ }};
161 \\
162 , .{
163 std.zig.fmtId(ext),
164 ext,
165 }
166 );
167 }
168
169 // TODO: Capability extension dependencies.
170 for (capabilities) |cap| {
171 try w.print(
172 \\ result[@enumToInt(Feature.{s})] = .{{
173 \\ .llvm_name = null,
174 \\ .description = "Enable SPIR-V capability {s}",
175 \\ .dependencies = featureSet(&[_]Feature{{
176 \\
177 , .{
178 std.zig.fmtId(cap.enumerant),
179 cap.enumerant,
180 }
181 );
182
183 if (cap.version) |ver_str| {
184 if (!std.mem.eql(u8, ver_str, "None")) {
185 const ver = try Version.parse(ver_str);
186 try w.print(" .v{}_{},\n", .{ ver.major, ver.minor });
187 }
188 }
189
190 for (cap.capabilities) |cap_dep| {
191 try w.print(" .{},\n", .{ std.zig.fmtId(cap_dep) });
192 }
193
194 try w.writeAll(
195 \\ }),
196 \\ };
197 \\
198 );
199 }
200
201 try w.writeAll(
202 \\ const ti = @typeInfo(Feature);
203 \\ for (result) |*elem, i| {
204 \\ elem.index = i;
205 \\ elem.name = ti.Enum.fields[i].name;
206 \\ }
207 \\ break :blk result;
208 \\};
209 \\
210 );
211
212 try bw.flush();
213}
214
215/// SPIRV-Registry should hold all extensions currently registered for SPIR-V.
216/// The *.grammar.json in SPIRV-Headers should have most of these as well, but with this we're sure to get only the actually
217/// registered ones.
218/// TODO: Unfortunately, neither repository contains a machine-readable list of extension dependencies.
219fn gather_extensions(allocator: *Allocator, spirv_registry_root: []const u8) ![]const []const u8 {
220 const extensions_path = try fs.path.join(allocator, &.{spirv_registry_root, "extensions"});
221 var extensions_dir = try fs.cwd().openDir(extensions_path, .{ .iterate = true });
222 defer extensions_dir.close();
223
224 var extensions = std.ArrayList([]const u8).init(allocator);
225
226 var vendor_it = extensions_dir.iterate();
227 while (try vendor_it.next()) |vendor_entry| {
228 std.debug.assert(vendor_entry.kind == .Directory); // If this fails, the structure of SPIRV-Registry has changed.
229
230 const vendor_dir = try extensions_dir.openDir(vendor_entry.name, .{ .iterate = true });
231 var ext_it = vendor_dir.iterate();
232 while (try ext_it.next()) |ext_entry| {
233 // There is both a HTML and asciidoc version of every spec (as well as some other directories),
234 // we need just the name, but to avoid duplicates here we will just skip anything thats not asciidoc.
235 if (!std.mem.endsWith(u8, ext_entry.name, ".asciidoc"))
236 continue;
237
238 // Unfortunately, some extension filenames are incorrect, so we need to look for the string in tne 'Name Strings' section.
239 // This has the following format:
240 // ```
241 // Name Strings
242 // ------------
243 //
244 // SPV_EXT_name
245 // ```
246 // OR
247 // ```
248 // == Name Strings
249 //
250 // SPV_EXT_name
251 // ```
252
253 const ext_spec = try vendor_dir.readFileAlloc(allocator, ext_entry.name, std.math.maxInt(usize));
254 const name_strings = "Name Strings";
255
256 const name_strings_offset = std.mem.indexOf(u8, ext_spec, name_strings) orelse return error.InvalidRegistry;
257
258 // As the specs are inconsistent on this next part, just skip any newlines/minuses
259 var ext_start = name_strings_offset + name_strings.len + 1;
260 while (ext_spec[ext_start] == '\n' or ext_spec[ext_start] == '-') {
261 ext_start += 1;
262 }
263
264 const ext_end = std.mem.indexOfScalarPos(u8, ext_spec, ext_start, '\n') orelse return error.InvalidRegistry;
265 const ext = ext_spec[ext_start .. ext_end];
266
267 std.debug.assert(std.mem.startsWith(u8, ext, "SPV_")); // Sanity check, all extensions should have a name like SPV_VENDOR_extension.
268
269 try extensions.append(try allocator.dupe(u8, ext));
270 }
271 }
272
273 return extensions.items;
274}
275
276fn insertVersion(versions: *std.ArrayList(Version), version: ?[]const u8) !void {
277 const ver_str = version orelse return;
278 if (std.mem.eql(u8, ver_str, "None"))
279 return;
280
281 const ver = try Version.parse(ver_str);
282 for (versions.items) |existing_ver| {
283 if (ver.eql(existing_ver)) return;
284 }
285
286 try versions.append(ver);
287}
288
289fn gatherVersions(allocator: *Allocator, registry: g.CoreRegistry) ![]const Version {
290 // Expected number of versions is small
291 var versions = std.ArrayList(Version).init(allocator);
292
293 for (registry.instructions) |inst| {
294 try insertVersion(&versions, inst.version);
295 }
296
297 for (registry.operand_kinds) |opkind| {
298 const enumerants = opkind.enumerants orelse continue;
299 for (enumerants) |enumerant| {
300 try insertVersion(&versions, enumerant.version);
301 }
302 }
303
304 std.sort.sort(Version, versions.items, {}, Version.lessThan);
305
306 return versions.items;
307}
308
309fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn {
310 file.writer().print(
311 \\Usage: {s} /path/git/SPIRV-Headers /path/git/SPIRV-Registry
312 \\
313 \\Prints to stdout Zig code which can be used to replace the file lib/std/target/spirv.zig.
314 \\
315 \\SPIRV-Headers can be cloned from https://github.com/KhronosGroup/SPIRV-Headers,
316 \\SPIRV-Registry can be cloned from https://github.com/KhronosGroup/SPIRV-Registry.
317 \\
318 , .{arg0}
319 ) catch std.process.exit(1);
320 std.process.exit(code);
321}