authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-03-11 23:23:02+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-03-18 19:13:49+01:00
log20d7bb68ac7043e7d4ec8f0653ec73a1090187da
tree54678146af0e606e2a243099e1f1c62749dbfd1f
parente566158acf034105a43690501664c45b8a065f6a
signaturebadge-check Signed by SSH key SHA256:ZS52FNyUv2WUXvO4njmVaFVO46RHojFuOrxRc4LuKzg

spirv: add zig-specific ext inst

This may be removed again in the future...

3 files changed, 69 insertions(+), 23 deletions(-)

src/codegen/spirv/extinst.zig.grammar.json created+13
......@@ -0,0 +1,13 @@
1{
2 "version": 0,
3 "revision": 0,
4 "instructions": [
5 {
6 "opname": "InvocationGlobal",
7 "opcode": 0,
8 "operands": [
9 { "kind": "IdRef", "name": "initializer function" }
10 ]
11 }
12 ]
13}
src/codegen/spirv/spec.zig+13-1
......@@ -102,6 +102,7 @@ pub const Class = enum {
102102};
103103
104104pub const OperandKind = enum {
105 Opcode,
105106 ImageOperands,
106107 FPFastMathMode,
107108 SelectionControl,
......@@ -187,6 +188,7 @@ pub const OperandKind = enum {
187188
188189 pub fn category(self: OperandKind) OperandCategory {
189190 return switch (self) {
191 .Opcode => .literal,
190192 .ImageOperands => .bit_enum,
191193 .FPFastMathMode => .bit_enum,
192194 .SelectionControl => .bit_enum,
......@@ -273,6 +275,7 @@ pub const OperandKind = enum {
273275 }
274276 pub fn enumerants(self: OperandKind) []const Enumerant {
275277 return switch (self) {
278 .Opcode => unreachable,
276279 .ImageOperands => &[_]Enumerant{
277280 .{ .name = "Bias", .value = 0x0001, .parameters = &[_]OperandKind{.IdRef} },
278281 .{ .name = "Lod", .value = 0x0002, .parameters = &[_]OperandKind{.IdRef} },
......@@ -2104,7 +2107,6 @@ pub const Opcode = enum(u16) {
21042107 OpGroupLogicalXorKHR = 6408,
21052108 OpMaskedGatherINTEL = 6428,
21062109 OpMaskedScatterINTEL = 6429,
2107
21082110 pub const OpSDotKHR = Opcode.OpSDot;
21092111 pub const OpUDotKHR = Opcode.OpUDot;
21102112 pub const OpSUDotKHR = Opcode.OpSUDot;
......@@ -5278,6 +5280,7 @@ pub const InstructionSet = enum {
52785280 @"nonsemantic.debugprintf",
52795281 @"spv-amd-shader-explicit-vertex-parameter",
52805282 @"nonsemantic.debugbreak",
5283 zig,
52815284
52825285 pub fn instructions(self: InstructionSet) []const Instruction {
52835286 return switch (self) {
......@@ -16505,6 +16508,15 @@ pub const InstructionSet = enum {
1650516508 .operands = &[_]Operand{},
1650616509 },
1650716510 },
16511 .zig => &[_]Instruction{
16512 .{
16513 .name = "InvocationGlobal",
16514 .opcode = 0,
16515 .operands = &[_]Operand{
16516 .{ .kind = .IdRef, .quantifier = .required },
16517 },
16518 },
16519 },
1650816520 };
1650916521 }
1651016522};
tools/gen_spirv_spec.zig+43-22
......@@ -48,16 +48,13 @@ pub fn main() !void {
4848 const a = arena.allocator();
4949
5050 const args = try std.process.argsAlloc(a);
51 if (args.len != 2) {
51 if (args.len != 3) {
5252 usageAndExit(args[0], 1);
5353 }
5454
5555 const json_path = try std.fs.path.join(a, &.{ args[1], "include/spirv/unified1/" });
5656 const dir = try std.fs.cwd().openDir(json_path, .{ .iterate = true });
5757
58 // const spec_path = try std.fs.path.join(a, &.{spirv_headers_dir_path, "spirv.core.grammar.json"});
59 // const core_spec = try std.fs.cwd().readFileAlloc(a, spec_path, std.math.maxInt(usize));
60
6158 const core_spec = try readRegistry(CoreRegistry, a, dir, "spirv.core.grammar.json");
6259 std.sort.block(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt);
6360
......@@ -65,24 +62,35 @@ pub fn main() !void {
6562
6663 var it = dir.iterate();
6764 while (try it.next()) |entry| {
68 if (entry.kind != .file or !std.mem.startsWith(u8, entry.name, "extinst.")) {
65 if (entry.kind != .file) {
6966 continue;
7067 }
7168
72 std.debug.assert(std.mem.endsWith(u8, entry.name, ".grammar.json"));
73 const name = entry.name["extinst.".len .. entry.name.len - ".grammar.json".len];
74 const spec = try readRegistry(ExtensionRegistry, a, dir, entry.name);
75
76 std.sort.block(Instruction, spec.instructions, CmpInst{}, CmpInst.lt);
77
78 try exts.append(.{ .name = try a.dupe(u8, name), .spec = spec });
69 try readExtRegistry(&exts, a, dir, entry.name);
7970 }
8071
72 try readExtRegistry(&exts, a, std.fs.cwd(), args[2]);
73
8174 var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
8275 try render(bw.writer(), a, core_spec, exts.items);
8376 try bw.flush();
8477}
8578
79fn readExtRegistry(exts: *std.ArrayList(Extension), a: Allocator, dir: std.fs.Dir, sub_path: []const u8) !void {
80 const filename = std.fs.path.basename(sub_path);
81 if (!std.mem.startsWith(u8, filename, "extinst.")) {
82 return;
83 }
84
85 std.debug.assert(std.mem.endsWith(u8, filename, ".grammar.json"));
86 const name = filename["extinst.".len .. filename.len - ".grammar.json".len];
87 const spec = try readRegistry(ExtensionRegistry, a, dir, sub_path);
88
89 std.sort.block(Instruction, spec.instructions, CmpInst{}, CmpInst.lt);
90
91 try exts.append(.{ .name = try a.dupe(u8, name), .spec = spec });
92}
93
8694fn readRegistry(comptime RegistryType: type, a: Allocator, dir: std.fs.Dir, path: []const u8) !RegistryType {
8795 const spec = try dir.readFileAlloc(a, path, std.math.maxInt(usize));
8896 // Required for json parsing.
......@@ -374,14 +382,19 @@ fn renderInstructionClass(writer: anytype, class: []const u8) !void {
374382}
375383
376384fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {
377 try writer.writeAll("pub const OperandKind = enum {\n");
385 try writer.writeAll(
386 \\pub const OperandKind = enum {
387 \\ Opcode,
388 \\
389 );
378390 for (operands) |operand| {
379391 try writer.print("{},\n", .{std.zig.fmtId(operand.kind)});
380392 }
381393 try writer.writeAll(
382394 \\
383395 \\pub fn category(self: OperandKind) OperandCategory {
384 \\return switch (self) {
396 \\ return switch (self) {
397 \\ .Opcode => .literal,
385398 \\
386399 );
387400 for (operands) |operand| {
......@@ -395,10 +408,11 @@ fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {
395408 try writer.print(".{} => .{s},\n", .{ std.zig.fmtId(operand.kind), cat });
396409 }
397410 try writer.writeAll(
398 \\};
411 \\ };
399412 \\}
400413 \\pub fn enumerants(self: OperandKind) []const Enumerant {
401 \\return switch (self) {
414 \\ return switch (self) {
415 \\ .Opcode => unreachable,
402416 \\
403417 );
404418 for (operands) |operand| {
......@@ -483,7 +497,9 @@ fn renderOpcodes(
483497 try writer.print("{} = {},\n", .{ std.zig.fmtId(inst.opname), inst.opcode });
484498 }
485499
486 try writer.writeByte('\n');
500 try writer.writeAll(
501 \\
502 );
487503
488504 for (aliases.items) |alias| {
489505 try writer.print("pub const {} = Opcode.{};\n", .{
......@@ -495,7 +511,7 @@ fn renderOpcodes(
495511 try writer.writeAll(
496512 \\
497513 \\pub fn Operands(comptime self: Opcode) type {
498 \\return switch (self) {
514 \\ return switch (self) {
499515 \\
500516 );
501517
......@@ -505,10 +521,10 @@ fn renderOpcodes(
505521 }
506522
507523 try writer.writeAll(
508 \\};
524 \\ };
509525 \\}
510526 \\pub fn class(self: Opcode) Class {
511 \\return switch (self) {
527 \\ return switch (self) {
512528 \\
513529 );
514530
......@@ -519,7 +535,12 @@ fn renderOpcodes(
519535 try writer.writeAll(",\n");
520536 }
521537
522 try writer.writeAll("};\n}\n};\n");
538 try writer.writeAll(
539 \\ };
540 \\}
541 \\};
542 \\
543 );
523544}
524545
525546fn renderOperandKinds(
......@@ -844,7 +865,7 @@ fn parseHexInt(text: []const u8) !u31 {
844865
845866fn usageAndExit(arg0: []const u8, code: u8) noreturn {
846867 std.io.getStdErr().writer().print(
847 \\Usage: {s} <SPIRV-Headers repository path>
868 \\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json>
848869 \\
849870 \\Generates Zig bindings for SPIR-V specifications found in the SPIRV-Headers
850871 \\repository. The result, printed to stdout, should be used to update