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 {
431431 pub const powerpc = @import("target/powerpc.zig");
432432 pub const riscv = @import("target/riscv.zig");
433433 pub const sparc = @import("target/sparc.zig");
434 pub const spirv = @import("target/spirv.zig");
434435 pub const systemz = @import("target/systemz.zig");
435436 pub const ve = @import("target/ve.zig");
436437 pub const wasm = @import("target/wasm.zig");
......@@ -594,7 +595,7 @@ pub const Target = struct {
594595 pub const Set = struct {
595596 ints: [usize_count]usize,
596597
597 pub const needed_bit_count = 172;
598 pub const needed_bit_count = 288;
598599 pub const byte_count = (needed_bit_count + 7) / 8;
599600 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
600601 pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));
......@@ -822,6 +823,13 @@ pub const Target = struct {
822823 };
823824 }
824825
826 pub fn isSPIRV(arch: Arch) bool {
827 return switch (arch) {
828 .spirv32, .spirv64 => true,
829 else => false,
830 };
831 }
832
825833 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
826834 for (arch.allCpuModels()) |cpu| {
827835 if (mem.eql(u8, cpu_name, cpu.name)) {
......@@ -1116,6 +1124,7 @@ pub const Target = struct {
11161124 .amdgcn => &amdgpu.all_features,
11171125 .riscv32, .riscv64 => &riscv.all_features,
11181126 .sparc, .sparcv9, .sparcel => &sparc.all_features,
1127 .spirv32, .spirv64 => &spirv.all_features,
11191128 .s390x => &systemz.all_features,
11201129 .i386, .x86_64 => &x86.all_features,
11211130 .nvptx, .nvptx64 => &nvptx.all_features,
......@@ -1324,6 +1333,9 @@ pub const Target = struct {
13241333 if (cpu_arch.isWasm()) {
13251334 return .wasm;
13261335 }
1336 if (cpu_arch.isSPIRV()) {
1337 return .spirv;
1338 }
13271339 return .elf;
13281340 }
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 @@
11const std = @import("std");
22const Allocator = std.mem.Allocator;
3const log = std.log.scoped(.codegen);
34
45const spec = @import("spirv/spec.zig");
56const Module = @import("../Module.zig");
67const 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
812pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []const u32) !void {
913 const word_count = @intCast(u32, args.len + 1);
......@@ -12,38 +16,91 @@ pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []c
1216}
1317
1418pub const SPIRVModule = struct {
15 next_id: u32 = 0,
16 free_id_list: std.ArrayList(u32),
19 next_result_id: u32 = 0,
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 {
1929 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),
2134 };
2235 }
2336
2437 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;
2642 }
2743
28 pub fn allocId(self: *SPIRVModule) u32 {
29 if (self.free_id_list.popOrNull()) |id| return id;
44 pub fn allocResultId(self: *SPIRVModule) u32 {
45 defer self.next_result_id += 1;
46 return self.next_result_id;
47 }
3048
31 defer self.next_id += 1;
32 return self.next_id;
49 pub fn resultIdBound(self: *SPIRVModule) u32 {
50 return self.next_result_id;
3351 }
3452
35 pub fn freeId(self: *SPIRVModule, id: u32) void {
36 if (id + 1 == self.next_id) {
37 self.next_id -= 1;
38 } else {
39 // If no more memory to append the id to the free list, just ignore it.
40 self.free_id_list.append(id) catch {};
53 pub fn getOrGenType(self: *SPIRVModule, t: Type) !u32 {
54 // We can't use getOrPut here so we can recursively generate types.
55 if (self.types.get(t)) |already_generated| {
56 return already_generated;
4157 }
42 }
4358
44 pub fn idBound(self: *SPIRVModule) u32 {
45 return self.next_id;
59 const result = self.allocResultId();
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;
4692 }
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 }
49106};
src/codegen/spirv/spec.zig+89-31
......@@ -1,26 +1,5 @@
1// Copyright (c) 2014-2020 The Khronos Group Inc.
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.
1//! This file is auto-generated by tools/gen_spirv_spec.zig.
2
243const Version = @import("builtin").Version;
254pub const version = Version{ .major = 1, .minor = 5, .patch = 4 };
265pub const magic_number: u32 = 0x07230203;
......@@ -443,8 +422,15 @@ pub const Opcode = extern enum(u16) {
443422 OpUSubSatINTEL = 5596,
444423 OpIMul32x16INTEL = 5597,
445424 OpUMul32x16INTEL = 5598,
446 OpFunctionPointerINTEL = 5600,
425 OpConstFunctionPointerINTEL = 5600,
447426 OpFunctionPointerCallINTEL = 5601,
427 OpAsmTargetINTEL = 5609,
428 OpAsmINTEL = 5610,
429 OpAsmCallINTEL = 5611,
430 OpAtomicFMinEXT = 5614,
431 OpAtomicFMaxEXT = 5615,
432 OpAssumeTrueKHR = 5630,
433 OpExpectKHR = 5631,
448434 OpDecorateString = 5632,
449435 OpDecorateStringGOOGLE = 5632,
450436 OpMemberDecorateString = 5633,
......@@ -567,7 +553,12 @@ pub const Opcode = extern enum(u16) {
567553 OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
568554 OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
569555 OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
556 OpVariableLengthArrayINTEL = 5818,
557 OpSaveMemoryINTEL = 5819,
558 OpRestoreMemoryINTEL = 5820,
570559 OpLoopControlINTEL = 5887,
560 OpPtrCastToCrossWorkgroupINTEL = 5934,
561 OpCrossWorkgroupCastToPtrINTEL = 5938,
571562 OpReadPipeBlockingINTEL = 5946,
572563 OpWritePipeBlockingINTEL = 5947,
573564 OpFPGARegINTEL = 5949,
......@@ -589,6 +580,10 @@ pub const Opcode = extern enum(u16) {
589580 OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
590581 OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
591582 OpAtomicFAddEXT = 6035,
583 OpTypeBufferSurfaceINTEL = 6086,
584 OpTypeStructContinuedINTEL = 6090,
585 OpConstantCompositeContinuedINTEL = 6091,
586 OpSpecConstantCompositeContinuedINTEL = 6092,
592587 _,
593588};
594589pub const ImageOperands = packed struct {
......@@ -642,8 +637,8 @@ pub const FPFastMathMode = packed struct {
642637 _reserved_bit_13: bool = false,
643638 _reserved_bit_14: bool = false,
644639 _reserved_bit_15: bool = false,
645 _reserved_bit_16: bool = false,
646 _reserved_bit_17: bool = false,
640 AllowContractFastINTEL: bool = false,
641 AllowReassocINTEL: bool = false,
647642 _reserved_bit_18: bool = false,
648643 _reserved_bit_19: bool = false,
649644 _reserved_bit_20: bool = false,
......@@ -717,7 +712,7 @@ pub const LoopControl = packed struct {
717712 LoopCoalesceINTEL: bool = false,
718713 MaxInterleavingINTEL: bool = false,
719714 SpeculatedIterationsINTEL: bool = false,
720 _reserved_bit_23: bool = false,
715 NoFusionINTEL: bool = false,
721716 _reserved_bit_24: bool = false,
722717 _reserved_bit_25: bool = false,
723718 _reserved_bit_26: bool = false,
......@@ -1037,10 +1032,16 @@ pub const ExecutionMode = extern enum(u32) {
10371032 SampleInterlockUnorderedEXT = 5369,
10381033 ShadingRateInterlockOrderedEXT = 5370,
10391034 ShadingRateInterlockUnorderedEXT = 5371,
1035 SharedLocalMemorySizeINTEL = 5618,
1036 RoundingModeRTPINTEL = 5620,
1037 RoundingModeRTNINTEL = 5621,
1038 FloatingPointModeALTINTEL = 5622,
1039 FloatingPointModeIEEEINTEL = 5623,
10401040 MaxWorkgroupSizeINTEL = 5893,
10411041 MaxWorkDimINTEL = 5894,
10421042 NoGlobalOffsetINTEL = 5895,
10431043 NumSIMDWorkitemsINTEL = 5896,
1044 SchedulerTargetFmaxMhzINTEL = 5903,
10441045 _,
10451046};
10461047pub const StorageClass = extern enum(u32) {
......@@ -1072,6 +1073,8 @@ pub const StorageClass = extern enum(u32) {
10721073 PhysicalStorageBuffer = 5349,
10731074 PhysicalStorageBufferEXT = 5349,
10741075 CodeSectionINTEL = 5605,
1076 DeviceOnlyINTEL = 5936,
1077 HostOnlyINTEL = 5937,
10751078 _,
10761079};
10771080pub const Dim = extern enum(u32) {
......@@ -1192,9 +1195,20 @@ pub const FPRoundingMode = extern enum(u32) {
11921195 RTN = 3,
11931196 _,
11941197};
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};
11951208pub const LinkageType = extern enum(u32) {
11961209 Export = 0,
11971210 Import = 1,
1211 LinkOnceODR = 2,
11981212 _,
11991213};
12001214pub const AccessQualifier = extern enum(u32) {
......@@ -1279,12 +1293,22 @@ pub const Decoration = extern enum(u32) {
12791293 RestrictPointerEXT = 5355,
12801294 AliasedPointer = 5356,
12811295 AliasedPointerEXT = 5356,
1296 SIMTCallINTEL = 5599,
12821297 ReferencedIndirectlyINTEL = 5602,
1298 ClobberINTEL = 5607,
1299 SideEffectsINTEL = 5608,
1300 VectorComputeVariableINTEL = 5624,
1301 FuncParamIOKindINTEL = 5625,
1302 VectorComputeFunctionINTEL = 5626,
1303 StackCallINTEL = 5627,
1304 GlobalVariableOffsetINTEL = 5628,
12831305 CounterBuffer = 5634,
12841306 HlslCounterBufferGOOGLE = 5634,
12851307 UserSemantic = 5635,
12861308 HlslSemanticGOOGLE = 5635,
12871309 UserTypeGOOGLE = 5636,
1310 FunctionRoundingModeINTEL = 5822,
1311 FunctionDenormModeINTEL = 5823,
12881312 RegisterINTEL = 5825,
12891313 MemoryINTEL = 5826,
12901314 NumbanksINTEL = 5827,
......@@ -1297,6 +1321,17 @@ pub const Decoration = extern enum(u32) {
12971321 MergeINTEL = 5834,
12981322 BankBitsINTEL = 5835,
12991323 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,
13001335 _,
13011336};
13021337pub const BuiltIn = extern enum(u32) {
......@@ -1342,14 +1377,14 @@ pub const BuiltIn = extern enum(u32) {
13421377 VertexIndex = 42,
13431378 InstanceIndex = 43,
13441379 SubgroupEqMask = 4416,
1345 SubgroupGeMask = 4417,
1346 SubgroupGtMask = 4418,
1347 SubgroupLeMask = 4419,
1348 SubgroupLtMask = 4420,
13491380 SubgroupEqMaskKHR = 4416,
1381 SubgroupGeMask = 4417,
13501382 SubgroupGeMaskKHR = 4417,
1383 SubgroupGtMask = 4418,
13511384 SubgroupGtMaskKHR = 4418,
1385 SubgroupLeMask = 4419,
13521386 SubgroupLeMaskKHR = 4419,
1387 SubgroupLtMask = 4420,
13531388 SubgroupLtMaskKHR = 4420,
13541389 BaseVertex = 4424,
13551390 BaseInstance = 4425,
......@@ -1520,6 +1555,9 @@ pub const Capability = extern enum(u32) {
15201555 FragmentShadingRateKHR = 4422,
15211556 SubgroupBallotKHR = 4423,
15221557 DrawParameters = 4427,
1558 WorkgroupMemoryExplicitLayoutKHR = 4428,
1559 WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
1560 WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
15231561 SubgroupVoteKHR = 4431,
15241562 StorageBuffer16BitAccess = 4433,
15251563 StorageUniformBufferBlock16 = 4433,
......@@ -1610,21 +1648,41 @@ pub const Capability = extern enum(u32) {
16101648 SubgroupBufferBlockIOINTEL = 5569,
16111649 SubgroupImageBlockIOINTEL = 5570,
16121650 SubgroupImageMediaBlockIOINTEL = 5579,
1651 RoundToInfinityINTEL = 5582,
1652 FloatingPointModeINTEL = 5583,
16131653 IntegerFunctions2INTEL = 5584,
16141654 FunctionPointersINTEL = 5603,
16151655 IndirectReferencesINTEL = 5604,
1656 AsmINTEL = 5606,
1657 AtomicFloat32MinMaxEXT = 5612,
1658 AtomicFloat64MinMaxEXT = 5613,
1659 AtomicFloat16MinMaxEXT = 5616,
1660 VectorComputeINTEL = 5617,
1661 VectorAnyINTEL = 5619,
1662 ExpectAssumeKHR = 5629,
16161663 SubgroupAvcMotionEstimationINTEL = 5696,
16171664 SubgroupAvcMotionEstimationIntraINTEL = 5697,
16181665 SubgroupAvcMotionEstimationChromaINTEL = 5698,
1666 VariableLengthArrayINTEL = 5817,
1667 FunctionFloatControlINTEL = 5821,
16191668 FPGAMemoryAttributesINTEL = 5824,
1669 FPFastMathModeINTEL = 5837,
1670 ArbitraryPrecisionIntegersINTEL = 5844,
16201671 UnstructuredLoopControlsINTEL = 5886,
16211672 FPGALoopControlsINTEL = 5888,
16221673 KernelAttributesINTEL = 5892,
16231674 FPGAKernelAttributesINTEL = 5897,
1675 FPGAMemoryAccessesINTEL = 5898,
1676 FPGAClusterAttributesINTEL = 5904,
1677 LoopFuseINTEL = 5906,
1678 FPGABufferLocationINTEL = 5920,
1679 USMStorageClassesINTEL = 5935,
1680 IOPipesINTEL = 5943,
16241681 BlockingPipesINTEL = 5945,
16251682 FPGARegINTEL = 5948,
16261683 AtomicFloat32AddEXT = 6033,
16271684 AtomicFloat64AddEXT = 6034,
1685 LongConstantCompositeINTEL = 6089,
16281686 _,
16291687};
16301688pub const RayQueryIntersection = extern enum(u32) {
src/link/SpirV.zig+56-63
......@@ -16,11 +16,16 @@
1616//! All function declarations without a body (extern functions presumably).
1717//! 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
1923const SpirV = @This();
2024
2125const std = @import("std");
2226const Allocator = std.mem.Allocator;
2327const assert = std.debug.assert;
28const log = std.log.scoped(.link);
2429
2530const Module = @import("../Module.zig");
2631const Compilation = @import("../Compilation.zig");
......@@ -30,16 +35,15 @@ const trace = @import("../tracy.zig").trace;
3035const build_options = @import("build_options");
3136const 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?
3339pub const FnData = struct {
34 id: ?u32 = null,
35 code: std.ArrayListUnmanaged(u32) = .{},
40 // We're going to fill these in flushModule, and we're going to fill them unconditionally,
41 // so just set it to undefined.
42 id: u32 = undefined
3643};
3744
3845base: link.File,
3946
40// TODO: Does this file need to support multiple independent modules?
41spirv_module: codegen.SPIRVModule,
42
4347pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {
4448 const spirv = try gpa.create(SpirV);
4549 spirv.* = .{
......@@ -49,7 +53,6 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*SpirV {
4953 .file = null,
5054 .allocator = gpa,
5155 },
52 .spirv_module = codegen.SPIRVModule.init(gpa),
5356 };
5457
5558 // 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
8790 return spirv;
8891}
8992
90pub 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();
93pub fn deinit(self: *SpirV) void {}
10894
109 // Free excess allocated memory for this Decl.
110 fn_data.code.shrinkAndFree(self.base.allocator, fn_data.code.items.len);
111}
95pub fn updateDecl(self: *SpirV, module: *Module, decl: *Module.Decl) !void {}
11296
11397pub fn updateDeclExports(
11498 self: *SpirV,
......@@ -117,12 +101,7 @@ pub fn updateDeclExports(
117101 exports: []const *Module.Export,
118102) !void {}
119103
120pub 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}
104pub fn freeDecl(self: *SpirV, decl: *Module.Decl) void {}
126105
127106pub fn flush(self: *SpirV, comp: *Compilation) !void {
128107 if (build_options.have_llvm and self.base.options.use_lld) {
......@@ -139,55 +118,69 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
139118 const module = self.base.options.module.?;
140119 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
142151 var binary = std.ArrayList(u32).init(self.base.allocator);
143152 defer binary.deinit();
144153
145 // Note: The order of adding sections to the final binary
146 // follows the SPIR-V logical module format!
147
148154 try binary.appendSlice(&[_]u32{
149155 spec.magic_number,
150156 (spec.version.major << 16) | (spec.version.minor << 8),
151157 0, // TODO: Register Zig compiler magic number.
152 self.spirv_module.idBound(),
158 spirv_module.resultIdBound(), // ID bound.
153159 0, // Schema (currently reserved for future use in the SPIR-V spec).
154160 });
155161
156162 try writeCapabilities(&binary, target);
157163 try writeMemoryModel(&binary, target);
158164
159 // Collect list of buffers to write.
160 // SPIR-V files support both little and big endian words. The actual format is
161 // disambiguated by the magic number, and so theoretically we don't need to worry
162 // about endian-ness when writing the final binary.
163 var all_buffers = std.ArrayList(std.os.iovec_const).init(self.base.allocator);
164 defer all_buffers.deinit();
165
166 // Pre-allocate enough for the binary info + all functions
167 try all_buffers.ensureCapacity(module.decl_table.count() + 1);
168
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 }
165 // Note: The order of adding sections to the final binary
166 // follows the SPIR-V logical module format!
167 var all_buffers = [_]std.os.iovec_const{
168 wordsToIovConst(binary.items),
169 wordsToIovConst(spirv_module.types_and_globals.items),
170 wordsToIovConst(spirv_module.fn_decls.items),
171 };
172
173 const file = self.base.file.?;
174 const bytes = std.mem.sliceAsBytes(binary.items);
181175
182176 var file_size: u64 = 0;
183 for (all_buffers.items) |iov| {
177 for (all_buffers) |iov| {
184178 file_size += iov.iov_len;
185179 }
186180
187 const file = self.base.file.?;
188181 try file.seekTo(0);
189182 try file.setEndPos(file_size);
190 try file.pwritevAll(all_buffers.items, 0);
183 try file.pwritevAll(&all_buffers, 0);
191184}
192185
193186fn writeCapabilities(binary: *std.ArrayList(u32), target: std.Target) !void {
......@@ -231,4 +224,4 @@ fn wordsToIovConst(words: []const u32) std.os.iovec_const {
231224 .iov_base = bytes.ptr,
232225 .iov_len = bytes.len,
233226 };
234}
227}
\ No newline at end of file
tools/gen_spirv_spec.zig+25-122
......@@ -1,96 +1,5 @@
11const std = @import("std");
2const Writer = std.ArrayList(u8).Writer;
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};
2const g = @import("spirv/grammar.zig");
943
954pub fn main() !void {
965 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
......@@ -106,24 +15,25 @@ pub fn main() !void {
10615 const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));
10716
10817 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);
112 defer buf.deinit();
113
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);
20 var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
21 try render(bw.writer(), registry);
22 try bw.flush();
11823}
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
12133 switch (registry) {
12234 .core => |core_reg| {
123 try renderCopyRight(writer, core_reg.copyright);
12435 try writer.print(
125 \\const Version = @import("builtin").Version;
126 \\pub const version = Version{{.major = {}, .minor = {}, .patch = {}}};
36 \\pub const version = Version{{ .major = {}, .minor = {}, .patch = {} }};
12737 \\pub const magic_number: u32 = {s};
12838 \\
12939 , .{ 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 {
13242 try renderOperandKinds(writer, core_reg.operand_kinds);
13343 },
13444 .extension => |ext_reg| {
135 try renderCopyRight(writer, ext_reg.copyright);
13645 try writer.print(
137 \\const Version = @import("builtin").Version;
138 \\pub const version = Version{{.major = {}, .minor = 0, .patch = {}}};
46 \\pub const version = Version{{ .major = {}, .minor = 0, .patch = {} }};
13947 \\
14048 , .{ ext_reg.version, ext_reg.revision },
14149 );
......@@ -145,21 +53,15 @@ fn render(writer: Writer, registry: Registry) !void {
14553 }
14654}
14755
148fn renderCopyRight(writer: Writer, copyright: []const []const u8) !void {
149 for (copyright) |line| {
150 try writer.print("// {s}\n", .{ line });
151 }
152}
153
154fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {
56fn renderOpcodes(writer: anytype, instructions: []const g.Instruction) !void {
15557 try writer.writeAll("pub const Opcode = extern enum(u16) {\n");
15658 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 });
15860 }
159 try writer.writeAll("_,\n};\n");
61 try writer.writeAll(" _,\n};\n");
16062}
16163
162fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {
64fn renderOperandKinds(writer: anytype, kinds: []const g.OperandKind) !void {
16365 for (kinds) |kind| {
16466 switch (kind.category) {
16567 .ValueEnum => try renderValueEnum(writer, kind),
......@@ -169,20 +71,20 @@ fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {
16971 }
17072}
17173
172fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {
74fn renderValueEnum(writer: anytype, enumeration: g.OperandKind) !void {
17375 try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });
17476
17577 const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;
17678 for (enumerants) |enumerant| {
17779 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 });
18082 }
18183
182 try writer.writeAll("_,\n};\n");
84 try writer.writeAll(" _,\n};\n");
18385}
18486
185fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {
87fn renderBitEnum(writer: anytype, enumeration: g.OperandKind) !void {
18688 try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });
18789
18890 var flags_by_bitpos = [_]?[]const u8{null} ** 32;
......@@ -205,6 +107,7 @@ fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {
205107 }
206108
207109 for (flags_by_bitpos) |maybe_flag_name, bitpos| {
110 try writer.writeAll(" ");
208111 if (maybe_flag_name) |flag_name| {
209112 try writer.writeAll(flag_name);
210113 } else {
......@@ -215,7 +118,7 @@ fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {
215118 if (bitpos == 0) { // Force alignment to integer boundaries
216119 try writer.writeAll("align(@alignOf(u32)) ");
217120 }
218 try writer.writeAll("= false, ");
121 try writer.writeAll("= false,\n");
219122 }
220123
221124 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}