Files
vulkan-zig/generator/spirv/render.zig
2020-08-15 23:51:37 +02:00

70 lines
2.0 KiB
Zig

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();
}