forked from mirror/vulkan-zig
Remove SPIR-V stuff
After experimenting somewhat, i realize this is gonna require more effort than i thought it was gonna be. This is probably also not the right repository for it.
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
const std = @import("std");
|
||||
const reg = @import("registry.zig");
|
||||
const renderSpirv = @import("render.zig").render;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn mergeRegistries(allocator: *Allocator, core: reg.CoreRegistry, extensions: []const reg.ExtensionRegistry) !reg.CoreRegistry {
|
||||
var merged = core;
|
||||
|
||||
var total_instructions = core.instructions.len;
|
||||
var total_operand_kinds = core.operand_kinds.len;
|
||||
for (extensions) |ext| {
|
||||
total_instructions += ext.instructions.len;
|
||||
total_operand_kinds += ext.operand_kinds.len;
|
||||
}
|
||||
|
||||
merged.instructions = try allocator.alloc(reg.Instruction, total_instructions);
|
||||
merged.operand_kinds = try allocator.alloc(reg.OperandKind, total_operand_kinds);
|
||||
|
||||
// Assume the core and extension registries contain no common operand kinds and instructions.
|
||||
for (core.instructions) |inst, i| merged.instructions[i] = inst;
|
||||
for (core.operand_kinds) |operand_kind, i| merged.operand_kinds[i] = operand_kind;
|
||||
|
||||
var inst_i = core.instructions.len;
|
||||
var oper_i = core.operand_kinds.len;
|
||||
|
||||
for (extensions) |ext| {
|
||||
for (ext.instructions) |inst| {
|
||||
merged.instructions[inst_i] = inst;
|
||||
inst_i += 1;
|
||||
}
|
||||
|
||||
for (ext.operand_kinds) |operand_kind| {
|
||||
merged.operand_kinds[oper_i] = operand_kind;
|
||||
oper_i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
pub fn generate(allocator: *Allocator, spec_jsons: []const []const u8, writer: anytype) !void {
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
// Exactly one of the passed specs must be core - the others must be exensions.
|
||||
var core_registry: reg.CoreRegistry = undefined;
|
||||
const num_ext_registries = spec_jsons.len - 1;
|
||||
const ext_registries = try arena.allocator.alloc(reg.ExtensionRegistry, num_ext_registries);
|
||||
|
||||
var ext_registry_i: usize = 0;
|
||||
for (spec_jsons) |spec_json| {
|
||||
var tokens = std.json.TokenStream.init(spec_json);
|
||||
const registry = try std.json.parse(reg.Registry, &tokens, .{.allocator = &arena.allocator});
|
||||
switch (registry) {
|
||||
.core => |parsed_core_registry| core_registry = parsed_core_registry,
|
||||
.extension => |parsed_ext_registry| {
|
||||
if (ext_registry_i == num_ext_registries) {
|
||||
return error.NoCoreRegistry;
|
||||
}
|
||||
|
||||
ext_registries[ext_registry_i] = parsed_ext_registry;
|
||||
ext_registry_i += 1;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (ext_registry_i != num_ext_registries) {
|
||||
return error.MultipleCoreRegistries;
|
||||
}
|
||||
|
||||
const merged = try mergeRegistries(&arena.allocator, core_registry, ext_registries);
|
||||
try renderSpirv(writer, &arena.allocator, &merged);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
|
||||
|
||||
pub const Registry = union(enum) {
|
||||
core: CoreRegistry,
|
||||
extension: ExtensionRegistry,
|
||||
};
|
||||
|
||||
pub const CoreRegistry = struct {
|
||||
copyright: [][]const u8,
|
||||
magic_number: []const u8, // Hexadecimal representation of the magic number
|
||||
major_version: u32,
|
||||
minor_version: u32,
|
||||
revision: u32,
|
||||
instructions: []Instruction,
|
||||
operand_kinds: []OperandKind,
|
||||
};
|
||||
|
||||
pub const ExtensionRegistry = struct {
|
||||
copyright: [][]const u8,
|
||||
version: u32,
|
||||
revision: u32,
|
||||
instructions: []Instruction,
|
||||
operand_kinds: []OperandKind = &[_]OperandKind{},
|
||||
};
|
||||
|
||||
pub const Instruction = struct {
|
||||
opname: []const u8,
|
||||
opcode: u32,
|
||||
operands: []Operand = &[_]Operand{},
|
||||
capabilities: [][]const u8 = &[_][]const u8{},
|
||||
extensions: [][]const u8 = &[_][]const u8{},
|
||||
};
|
||||
|
||||
pub const Operand = struct {
|
||||
kind: []const u8,
|
||||
|
||||
/// Either
|
||||
/// - null: exactly once.
|
||||
/// - "?": zero or once.
|
||||
/// - "*": zero or more.
|
||||
quantifier: ?[]const u8 = null,
|
||||
name: []const u8 = "",
|
||||
};
|
||||
|
||||
pub const OperandCategory = enum {
|
||||
// Note: non-canonical casing to match Spir-V JSON spec/
|
||||
BitEnum,
|
||||
ValueEnum,
|
||||
Id,
|
||||
Literal,
|
||||
Composite,
|
||||
};
|
||||
|
||||
pub const OperandKind = struct {
|
||||
category: OperandCategory,
|
||||
kind: []const u8,
|
||||
doc: []const u8 = "",
|
||||
enumerants: ?[]Enumerant = null,
|
||||
bases: ?[]const []const u8 = null,
|
||||
};
|
||||
|
||||
pub const Enumerant = struct {
|
||||
enumerant: []const u8,
|
||||
value: union(enum) {
|
||||
bitflag: []const u8, // Hexadecimal representation of the value
|
||||
int: u31,
|
||||
},
|
||||
capabilities: [][]const u8 = &[_][]const u8{},
|
||||
extensions: [][]const u8 = &[_][]const u8{}, // Valid for .ValueEnum
|
||||
parameters: []Operand = &[_]Operand{}, // `quantifier` will always be `null`.
|
||||
};
|
||||
@@ -1,69 +0,0 @@
|
||||
const std = @import("std");
|
||||
const reg = @import("registry.zig");
|
||||
const IdRenderer = @import("../id_render.zig").IdRenderer;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
// The SPIR-V spec doesn't contain any tag information like vulkan.xml does,
|
||||
// so the tags are just hardcoded. They are retrieved from
|
||||
// https://github.com/KhronosGroup/SPIRV-Registry/tree/master/extensions
|
||||
const tags = [_][]const u8{
|
||||
"AMD",
|
||||
"EXT",
|
||||
"GOOGLE",
|
||||
"INTEL",
|
||||
"KHR",
|
||||
"NV",
|
||||
};
|
||||
|
||||
const preamble =
|
||||
\\
|
||||
\\ This file is generated from the SPIR-V JSON registry
|
||||
;
|
||||
|
||||
fn stripOpPrefix(name: []const u8) []const u8 {
|
||||
// Some instructions (those from the core) are prefixed with 'Op'
|
||||
const prefix = "Op";
|
||||
return if (std.mem.startsWith(u8, name, prefix))
|
||||
name[prefix.len ..]
|
||||
else
|
||||
name;
|
||||
}
|
||||
|
||||
fn Renderer(comptime WriterType: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
writer: WriterType,
|
||||
registry: *const reg.CoreRegistry,
|
||||
id_renderer: IdRenderer,
|
||||
|
||||
fn render(self: *Self) !void {
|
||||
for (self.registry.copyright) |line| {
|
||||
try self.writer.print("// {}\n", .{ line });
|
||||
}
|
||||
try self.writer.writeAll(preamble);
|
||||
try self.renderOpcodes();
|
||||
}
|
||||
|
||||
fn renderOpcodes(self: *Self) !void {
|
||||
try self.writer.writeAll("pub const Opcode = enum(u16) {\n");
|
||||
for (self.registry.instructions) |instr| {
|
||||
try self.id_renderer.renderWithCase(self.writer, .snake, stripOpPrefix(instr.opname));
|
||||
try self.writer.print(" = {},\n", .{ instr.opcode });
|
||||
}
|
||||
try self.writer.writeAll("};\n");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn render(writer: anytype, allocator: *Allocator, registry: *const reg.CoreRegistry) !void {
|
||||
const id_renderer = IdRenderer.init(allocator, &tags);
|
||||
defer id_renderer.deinit();
|
||||
var renderer = Renderer(@TypeOf(writer)) {
|
||||
.writer = writer,
|
||||
.registry = registry,
|
||||
.id_renderer = id_renderer,
|
||||
};
|
||||
try renderer.render();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user