Skip to content

Commit b4ff6f5

Browse files
committed
adding spirv header parsing
1 parent 977d05f commit b4ff6f5

3 files changed

Lines changed: 122 additions & 3 deletions

File tree

src/Module.zig

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const std = @import("std");
22
const lib = @import("lib.zig");
3+
const spv_data = @import("spv_data.zig");
34

45
const SpvVoid = lib.SpvVoid;
56
const SpvByte = lib.SpvByte;
@@ -20,13 +21,21 @@ const SpvEntryPoint = struct {
2021
globals: []const SpvWord,
2122
};
2223

24+
const ModuleError = error{
25+
InvalidSpirV,
26+
InvalidMagic,
27+
OutOfMemory,
28+
};
29+
2330
ctx: *const Interpreter,
2431

2532
it: WordIterator,
2633

2734
version_major: SpvByte,
2835
version_minor: SpvByte,
29-
generator_magic: SpvWord,
36+
37+
generator_id: u16,
38+
generator_version: u16,
3039

3140
bound: SpvWord,
3241

@@ -42,14 +51,45 @@ local_size_x: SpvWord,
4251
local_size_y: SpvWord,
4352
local_size_z: SpvWord,
4453

45-
pub fn init(allocator: std.mem.Allocator, ctx: *const Interpreter, source: []const SpvWord) !Self {
54+
pub fn init(allocator: std.mem.Allocator, ctx: *const Interpreter, source: []const SpvWord) ModuleError!Self {
4655
var self: Self = std.mem.zeroInit(Self, .{
4756
.ctx = ctx,
48-
.code = try allocator.dupe(SpvWord, source),
57+
.code = allocator.dupe(SpvWord, source) catch return ModuleError.OutOfMemory,
58+
.local_size_x = 1,
59+
.local_size_y = 1,
60+
.local_size_z = 1,
4961
});
62+
errdefer allocator.free(self.code);
5063

5164
self.it = WordIterator.init(self.code);
5265

66+
const magic = self.it.next() orelse return ModuleError.InvalidSpirV;
67+
if (magic != lib.spv.SpvMagicNumber) return ModuleError.InvalidMagic;
68+
69+
const version = self.it.next() orelse return ModuleError.InvalidSpirV;
70+
self.version_major = @intCast((version & 0x00FF0000) >> 16);
71+
self.version_minor = @intCast((version & 0x0000FF00) >> 8);
72+
73+
const generator = self.it.next() orelse return ModuleError.InvalidSpirV;
74+
self.generator_id = @intCast((generator & 0xFFFF0000) >> 16);
75+
self.generator_version = @intCast(generator & 0x0000FFFF);
76+
77+
self.bound = self.it.next() orelse return ModuleError.InvalidSpirV;
78+
79+
_ = self.it.skip(); // Skip schema
80+
81+
std.log.scoped(.SPIRV_Interpreter).debug(
82+
\\Loaded shader module with infos:
83+
\\ SPIR-V version: {d}.{d}
84+
\\ Generator: {s} (ID {d}), encoded version {d}
85+
, .{
86+
self.version_major,
87+
self.version_minor,
88+
spv_data.vendorName(self.generator_id),
89+
self.generator_id,
90+
self.generator_version,
91+
});
92+
5393
return self;
5494
}
5595

src/lib.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ pub const Image = @import("Image.zig");
55
pub const Interpreter = @import("Interpreter.zig");
66
pub const Module = @import("Module.zig");
77
pub const State = @import("State.zig");
8+
89
const opcode = @import("opcode.zig");
10+
const spv_data = @import("spv_data.zig");
911

1012
pub const SpvVoid = void;
1113
pub const SpvByte = u8;
@@ -18,4 +20,5 @@ test {
1820
std.testing.refAllDecls(Module);
1921
std.testing.refAllDecls(State);
2022
std.testing.refAllDecls(opcode);
23+
std.testing.refAllDecls(spv_data);
2124
}

src/spv_data.zig

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const lib = @import("lib.zig");
2+
const spv = lib.spv;
3+
4+
pub const SourceLanguage = enum(u32) {
5+
Unknown = 0,
6+
ESSL = 1,
7+
GLSL = 2,
8+
OpenCL_C = 3,
9+
OpenCL_CPP = 4,
10+
HLSL = 5,
11+
CPP_for_OpenCL = 6,
12+
SYCL = 7,
13+
HERO_C = 8,
14+
NZSL = 9,
15+
WGSL = 10,
16+
Slang = 11,
17+
Zig = 12,
18+
Rust = 13,
19+
};
20+
21+
pub fn vendorName(id: u32) []const u8 {
22+
return switch (id) {
23+
0 => "Khronos",
24+
1 => "LunarG",
25+
2 => "Valve",
26+
3 => "Codeplay",
27+
4 => "NVIDIA",
28+
5 => "ARM",
29+
6 => "Khronos LLVM/SPIR-V Translator",
30+
7 => "Khronos SPIR-V Tools Assembler",
31+
8 => "Khronos Glslang Reference Front End",
32+
9 => "Qualcomm",
33+
10 => "AMD",
34+
11 => "Intel",
35+
12 => "Imagination",
36+
13 => "Google Shaderc over Glslang",
37+
14 => "Google spiregg",
38+
15 => "Google rspirv",
39+
16 => "X-LEGEND Mesa-IR/SPIR-V Translator",
40+
17 => "Khronos SPIR-V Tools Linker",
41+
18 => "Wine VKD3D Shader Compiler",
42+
19 => "Tellusim Clay Shader Compiler",
43+
20 => "W3C WebGPU Group WHLSL Shader Translator",
44+
21 => "Google Clspv",
45+
22 => "LLVM MLIR SPIR-V Serializer",
46+
23 => "Google Tint Compiler",
47+
24 => "Google ANGLE Shader Compiler",
48+
25 => "Netease Games Messiah Shader Compiler",
49+
26 => "Xenia Xenia Emulator Microcode Translator",
50+
27 => "Embark Studios Rust GPU Compiler Backend",
51+
28 => "gfx-rs community Naga",
52+
29 => "Mikkosoft Productions MSP Shader Compiler",
53+
30 => "SpvGenTwo community SpvGenTwo SPIR-V IR Tools",
54+
31 => "Google Skia SkSL",
55+
32 => "TornadoVM Beehive SPIRV Toolkit",
56+
33 => "DragonJoker ShaderWriter",
57+
34 => "Rayan Hatout SPIRVSmith",
58+
35 => "Saarland University Shady",
59+
36 => "Taichi Graphics Taichi",
60+
37 => "heroseh Hero C Compiler",
61+
38 => "Meta SparkSL",
62+
39 => "SirLynix Nazara ShaderLang Compiler",
63+
40 => "Khronos Slang Compiler",
64+
41 => "Zig Software Foundation Zig Compiler",
65+
42 => "Rendong Liang spq",
66+
43 => "LLVM LLVM SPIR-V Backend",
67+
44 => "Robert Konrad Kongruent",
68+
45 => "Kitsunebi Games Nuvk SPIR-V Emitter and DLSL compiler",
69+
46 => "Nintendo",
70+
47 => "ARM",
71+
48 => "Goopax",
72+
49 => "Icyllis Milica Arc3D Shader Compiler",
73+
74+
else => "Unknown",
75+
};
76+
}

0 commit comments

Comments
 (0)