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 {...@@ -102,6 +102,7 @@ pub const Class = enum {
102};102};
103103
104pub const OperandKind = enum {104pub const OperandKind = enum {
105 Opcode,
105 ImageOperands,106 ImageOperands,
106 FPFastMathMode,107 FPFastMathMode,
107 SelectionControl,108 SelectionControl,
...@@ -187,6 +188,7 @@ pub const OperandKind = enum {...@@ -187,6 +188,7 @@ pub const OperandKind = enum {
187188
188 pub fn category(self: OperandKind) OperandCategory {189 pub fn category(self: OperandKind) OperandCategory {
189 return switch (self) {190 return switch (self) {
191 .Opcode => .literal,
190 .ImageOperands => .bit_enum,192 .ImageOperands => .bit_enum,
191 .FPFastMathMode => .bit_enum,193 .FPFastMathMode => .bit_enum,
192 .SelectionControl => .bit_enum,194 .SelectionControl => .bit_enum,
...@@ -273,6 +275,7 @@ pub const OperandKind = enum {...@@ -273,6 +275,7 @@ pub const OperandKind = enum {
273 }275 }
274 pub fn enumerants(self: OperandKind) []const Enumerant {276 pub fn enumerants(self: OperandKind) []const Enumerant {
275 return switch (self) {277 return switch (self) {
278 .Opcode => unreachable,
276 .ImageOperands => &[_]Enumerant{279 .ImageOperands => &[_]Enumerant{
277 .{ .name = "Bias", .value = 0x0001, .parameters = &[_]OperandKind{.IdRef} },280 .{ .name = "Bias", .value = 0x0001, .parameters = &[_]OperandKind{.IdRef} },
278 .{ .name = "Lod", .value = 0x0002, .parameters = &[_]OperandKind{.IdRef} },281 .{ .name = "Lod", .value = 0x0002, .parameters = &[_]OperandKind{.IdRef} },
...@@ -2104,7 +2107,6 @@ pub const Opcode = enum(u16) {...@@ -2104,7 +2107,6 @@ pub const Opcode = enum(u16) {
2104 OpGroupLogicalXorKHR = 6408,2107 OpGroupLogicalXorKHR = 6408,
2105 OpMaskedGatherINTEL = 6428,2108 OpMaskedGatherINTEL = 6428,
2106 OpMaskedScatterINTEL = 6429,2109 OpMaskedScatterINTEL = 6429,
2107
2108 pub const OpSDotKHR = Opcode.OpSDot;2110 pub const OpSDotKHR = Opcode.OpSDot;
2109 pub const OpUDotKHR = Opcode.OpUDot;2111 pub const OpUDotKHR = Opcode.OpUDot;
2110 pub const OpSUDotKHR = Opcode.OpSUDot;2112 pub const OpSUDotKHR = Opcode.OpSUDot;
...@@ -5278,6 +5280,7 @@ pub const InstructionSet = enum {...@@ -5278,6 +5280,7 @@ pub const InstructionSet = enum {
5278 @"nonsemantic.debugprintf",5280 @"nonsemantic.debugprintf",
5279 @"spv-amd-shader-explicit-vertex-parameter",5281 @"spv-amd-shader-explicit-vertex-parameter",
5280 @"nonsemantic.debugbreak",5282 @"nonsemantic.debugbreak",
5283 zig,
52815284
5282 pub fn instructions(self: InstructionSet) []const Instruction {5285 pub fn instructions(self: InstructionSet) []const Instruction {
5283 return switch (self) {5286 return switch (self) {
...@@ -16505,6 +16508,15 @@ pub const InstructionSet = enum {...@@ -16505,6 +16508,15 @@ pub const InstructionSet = enum {
16505 .operands = &[_]Operand{},16508 .operands = &[_]Operand{},
16506 },16509 },
16507 },16510 },
16511 .zig => &[_]Instruction{
16512 .{
16513 .name = "InvocationGlobal",
16514 .opcode = 0,
16515 .operands = &[_]Operand{
16516 .{ .kind = .IdRef, .quantifier = .required },
16517 },
16518 },
16519 },
16508 };16520 };
16509 }16521 }
16510};16522};
tools/gen_spirv_spec.zig+43-22
...@@ -48,16 +48,13 @@ pub fn main() !void {...@@ -48,16 +48,13 @@ pub fn main() !void {
48 const a = arena.allocator();48 const a = arena.allocator();
4949
50 const args = try std.process.argsAlloc(a);50 const args = try std.process.argsAlloc(a);
51 if (args.len != 2) {51 if (args.len != 3) {
52 usageAndExit(args[0], 1);52 usageAndExit(args[0], 1);
53 }53 }
5454
55 const json_path = try std.fs.path.join(a, &.{ args[1], "include/spirv/unified1/" });55 const json_path = try std.fs.path.join(a, &.{ args[1], "include/spirv/unified1/" });
56 const dir = try std.fs.cwd().openDir(json_path, .{ .iterate = true });56 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
61 const core_spec = try readRegistry(CoreRegistry, a, dir, "spirv.core.grammar.json");58 const core_spec = try readRegistry(CoreRegistry, a, dir, "spirv.core.grammar.json");
62 std.sort.block(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt);59 std.sort.block(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt);
6360
...@@ -65,24 +62,35 @@ pub fn main() !void {...@@ -65,24 +62,35 @@ pub fn main() !void {
6562
66 var it = dir.iterate();63 var it = dir.iterate();
67 while (try it.next()) |entry| {64 while (try it.next()) |entry| {
68 if (entry.kind != .file or !std.mem.startsWith(u8, entry.name, "extinst.")) {65 if (entry.kind != .file) {
69 continue;66 continue;
70 }67 }
7168
72 std.debug.assert(std.mem.endsWith(u8, entry.name, ".grammar.json"));69 try readExtRegistry(&exts, a, dir, entry.name);
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 });
79 }70 }
8071
72 try readExtRegistry(&exts, a, std.fs.cwd(), args[2]);
73
81 var bw = std.io.bufferedWriter(std.io.getStdOut().writer());74 var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
82 try render(bw.writer(), a, core_spec, exts.items);75 try render(bw.writer(), a, core_spec, exts.items);
83 try bw.flush();76 try bw.flush();
84}77}
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
86fn readRegistry(comptime RegistryType: type, a: Allocator, dir: std.fs.Dir, path: []const u8) !RegistryType {94fn readRegistry(comptime RegistryType: type, a: Allocator, dir: std.fs.Dir, path: []const u8) !RegistryType {
87 const spec = try dir.readFileAlloc(a, path, std.math.maxInt(usize));95 const spec = try dir.readFileAlloc(a, path, std.math.maxInt(usize));
88 // Required for json parsing.96 // Required for json parsing.
...@@ -374,14 +382,19 @@ fn renderInstructionClass(writer: anytype, class: []const u8) !void {...@@ -374,14 +382,19 @@ fn renderInstructionClass(writer: anytype, class: []const u8) !void {
374}382}
375383
376fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {384fn 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 );
378 for (operands) |operand| {390 for (operands) |operand| {
379 try writer.print("{},\n", .{std.zig.fmtId(operand.kind)});391 try writer.print("{},\n", .{std.zig.fmtId(operand.kind)});
380 }392 }
381 try writer.writeAll(393 try writer.writeAll(
382 \\394 \\
383 \\pub fn category(self: OperandKind) OperandCategory {395 \\pub fn category(self: OperandKind) OperandCategory {
384 \\return switch (self) {396 \\ return switch (self) {
397 \\ .Opcode => .literal,
385 \\398 \\
386 );399 );
387 for (operands) |operand| {400 for (operands) |operand| {
...@@ -395,10 +408,11 @@ fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {...@@ -395,10 +408,11 @@ fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {
395 try writer.print(".{} => .{s},\n", .{ std.zig.fmtId(operand.kind), cat });408 try writer.print(".{} => .{s},\n", .{ std.zig.fmtId(operand.kind), cat });
396 }409 }
397 try writer.writeAll(410 try writer.writeAll(
398 \\};411 \\ };
399 \\}412 \\}
400 \\pub fn enumerants(self: OperandKind) []const Enumerant {413 \\pub fn enumerants(self: OperandKind) []const Enumerant {
401 \\return switch (self) {414 \\ return switch (self) {
415 \\ .Opcode => unreachable,
402 \\416 \\
403 );417 );
404 for (operands) |operand| {418 for (operands) |operand| {
...@@ -483,7 +497,9 @@ fn renderOpcodes(...@@ -483,7 +497,9 @@ fn renderOpcodes(
483 try writer.print("{} = {},\n", .{ std.zig.fmtId(inst.opname), inst.opcode });497 try writer.print("{} = {},\n", .{ std.zig.fmtId(inst.opname), inst.opcode });
484 }498 }
485499
486 try writer.writeByte('\n');500 try writer.writeAll(
501 \\
502 );
487503
488 for (aliases.items) |alias| {504 for (aliases.items) |alias| {
489 try writer.print("pub const {} = Opcode.{};\n", .{505 try writer.print("pub const {} = Opcode.{};\n", .{
...@@ -495,7 +511,7 @@ fn renderOpcodes(...@@ -495,7 +511,7 @@ fn renderOpcodes(
495 try writer.writeAll(511 try writer.writeAll(
496 \\512 \\
497 \\pub fn Operands(comptime self: Opcode) type {513 \\pub fn Operands(comptime self: Opcode) type {
498 \\return switch (self) {514 \\ return switch (self) {
499 \\515 \\
500 );516 );
501517
...@@ -505,10 +521,10 @@ fn renderOpcodes(...@@ -505,10 +521,10 @@ fn renderOpcodes(
505 }521 }
506522
507 try writer.writeAll(523 try writer.writeAll(
508 \\};524 \\ };
509 \\}525 \\}
510 \\pub fn class(self: Opcode) Class {526 \\pub fn class(self: Opcode) Class {
511 \\return switch (self) {527 \\ return switch (self) {
512 \\528 \\
513 );529 );
514530
...@@ -519,7 +535,12 @@ fn renderOpcodes(...@@ -519,7 +535,12 @@ fn renderOpcodes(
519 try writer.writeAll(",\n");535 try writer.writeAll(",\n");
520 }536 }
521537
522 try writer.writeAll("};\n}\n};\n");538 try writer.writeAll(
539 \\ };
540 \\}
541 \\};
542 \\
543 );
523}544}
524545
525fn renderOperandKinds(546fn renderOperandKinds(
...@@ -844,7 +865,7 @@ fn parseHexInt(text: []const u8) !u31 {...@@ -844,7 +865,7 @@ fn parseHexInt(text: []const u8) !u31 {
844865
845fn usageAndExit(arg0: []const u8, code: u8) noreturn {866fn usageAndExit(arg0: []const u8, code: u8) noreturn {
846 std.io.getStdErr().writer().print(867 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>
848 \\869 \\
849 \\Generates Zig bindings for SPIR-V specifications found in the SPIRV-Headers870 \\Generates Zig bindings for SPIR-V specifications found in the SPIRV-Headers
850 \\repository. The result, printed to stdout, should be used to update871 \\repository. The result, printed to stdout, should be used to update