forked from mirror/vulkan-zig
Make SPIR-V registry parse-able by std.json.parse
This commit is contained in:
@@ -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" {
|
||||||
|
|||||||
14
generator/spirv/generator.zig
Normal file
14
generator/spirv/generator.zig
Normal 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});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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`.
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user