Make SPIR-V registry parse-able by std.json.parse

This commit is contained in:
Robin Voetter
2020-08-12 02:20:07 +02:00
parent c708f01e3a
commit c761d8e635
3 changed files with 63 additions and 41 deletions

View File

@@ -1,5 +1,6 @@
pub const generateVk = @import("vulkan/generator.zig").generate; pub const generateVk = @import("vulkan/generator.zig").generate;
pub const VkGenerateStep = @import("vulkan/build_integration.zig").GenerateStep; pub const VkGenerateStep = @import("vulkan/build_integration.zig").GenerateStep;
pub const generateSpirv = @import("spirv/generator.zig").generate;
pub const ShaderCompileStep = @import("build_integration.zig").ShaderCompileStep; pub const ShaderCompileStep = @import("build_integration.zig").ShaderCompileStep;
test "main" { test "main" {

View File

@@ -0,0 +1,14 @@
const std = @import("std");
const reg = @import("registry.zig");
const Allocator = std.mem.Allocator;
pub fn generate(allocator: *Allocator, spec_jsons: []const []const u8, writer: anytype) !void {
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
const registries = try arena.allocator.alloc(reg.Registry, spec_jsons.len);
for (registries) |*registry, i| {
var tokens = std.json.TokenStream.init(spec_jsons[i]);
registry.* = try std.json.parse(reg.Registry, &tokens, .{.allocator = &arena.allocator});
}
}

View File

@@ -1,65 +1,72 @@
// See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html // See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
pub const Registry = struct { pub const Registry = union(enum) {
copyright: []const u8, core: CoreRegistry,
registry_type: RegistryType, extension: ExtensionRegistry,
instruction: []Instruction,
operand_kinds: []OperandKind,
}; };
pub const RegistryType = union(enum) { pub const CoreRegistry = struct {
core: struct { copyright: [][]const u8,
magic_number: u32, magic_number: []const u8, // Hexadecimal representation of the magic number
major_version: u32, major_version: u32,
minor_version: u32, minor_version: u32,
revision: u32, revision: u32,
}, instructions: []Instruction,
extension: struct { operand_kinds: []OperandKind,
};
pub const ExtensionRegistry = struct {
copyright: [][]const u8,
version: u32, version: u32,
minor_version: u32,
revision: u32, revision: u32,
}, instructions: []Instruction,
operand_kinds: []OperandKind,
}; };
pub const Instruction = struct { pub const Instruction = struct {
opname: []const u8, opname: []const u8,
opcode: u32, opcode: u32,
operands: []Operand, operands: []Operand = &[_]Operand{},
capabilities: [][]const u8, capabilities: [][]const u8 = &[_][]const u8{},
extensions: [][]const u8 = &[_][]const u8{},
}; };
pub const Operand = struct { pub const Operand = struct {
kind: []const u8, kind: []const u8,
quantifier: Quantifier,
name: []const u8, /// Either
/// - null: exactly once.
/// - "?": zero or once.
/// - "*": zero or more.
quantifier: ?[]const u8 = null,
name: []const u8 = "",
}; };
pub const Quantifier = enum { pub const OperandCategory = enum {
one, // Note: non-canonical casing to match Spir-V JSON spec/
zero_or_one, BitEnum,
zero_or_more, ValueEnum,
}; Id,
Literal,
pub const OperandCategory = union(enum) { Composite,
bit_enum: []Enumerant,
value_enum: []Enumerant,
id,
literal,
composite: Composite,
}; };
pub const OperandKind = struct { pub const OperandKind = struct {
category: OperandCategory, category: OperandCategory,
name: []const u8, kind: []const u8,
doc: []const u8, doc: []const u8 = "",
enumerants: ?[]Enumerant = null,
bases: ?[]const []const u8 = null,
}; };
pub const Enumerant = struct { pub const Enumerant = struct {
name: []const u8, enumerant: []const u8,
value: u32, // A power of 2 for `.bit_enum`. value: union(enum) {
capabilities: [][]const u8, bitflag: []const u8, // Hexadecimal representation of the value
parameters: []Operand, // `quantifier` will always be `.one`. int: u31,
}; },
capabilities: [][]const u8 = &[_][]const u8{},
pub const Composite = struct { extensions: [][]const u8 = &[_][]const u8{}, // Valid for .ValueEnum
bases: [][]const u8, parameters: []Operand = &[_]Operand{}, // `quantifier` will always be `null`.
}; };