diff --git a/src/Module.zig b/src/Module.zig index 0746041..f474f86 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1,5 +1,6 @@ const std = @import("std"); const lib = @import("lib.zig"); +const spv_data = @import("spv_data.zig"); const SpvVoid = lib.SpvVoid; const SpvByte = lib.SpvByte; @@ -20,13 +21,21 @@ const SpvEntryPoint = struct { globals: []const SpvWord, }; +const ModuleError = error{ + InvalidSpirV, + InvalidMagic, + OutOfMemory, +}; + ctx: *const Interpreter, it: WordIterator, version_major: SpvByte, version_minor: SpvByte, -generator_magic: SpvWord, + +generator_id: u16, +generator_version: u16, bound: SpvWord, @@ -42,14 +51,45 @@ local_size_x: SpvWord, local_size_y: SpvWord, local_size_z: SpvWord, -pub fn init(allocator: std.mem.Allocator, ctx: *const Interpreter, source: []const SpvWord) !Self { +pub fn init(allocator: std.mem.Allocator, ctx: *const Interpreter, source: []const SpvWord) ModuleError!Self { var self: Self = std.mem.zeroInit(Self, .{ .ctx = ctx, - .code = try allocator.dupe(SpvWord, source), + .code = allocator.dupe(SpvWord, source) catch return ModuleError.OutOfMemory, + .local_size_x = 1, + .local_size_y = 1, + .local_size_z = 1, }); + errdefer allocator.free(self.code); self.it = WordIterator.init(self.code); + const magic = self.it.next() orelse return ModuleError.InvalidSpirV; + if (magic != lib.spv.SpvMagicNumber) return ModuleError.InvalidMagic; + + const version = self.it.next() orelse return ModuleError.InvalidSpirV; + self.version_major = @intCast((version & 0x00FF0000) >> 16); + self.version_minor = @intCast((version & 0x0000FF00) >> 8); + + const generator = self.it.next() orelse return ModuleError.InvalidSpirV; + self.generator_id = @intCast((generator & 0xFFFF0000) >> 16); + self.generator_version = @intCast(generator & 0x0000FFFF); + + self.bound = self.it.next() orelse return ModuleError.InvalidSpirV; + + _ = self.it.skip(); // Skip schema + + std.log.scoped(.SPIRV_Interpreter).debug( + \\Loaded shader module with infos: + \\ SPIR-V version: {d}.{d} + \\ Generator: {s} (ID {d}), encoded version {d} + , .{ + self.version_major, + self.version_minor, + spv_data.vendorName(self.generator_id), + self.generator_id, + self.generator_version, + }); + return self; } diff --git a/src/lib.zig b/src/lib.zig index 5cd3975..d1175b8 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -5,7 +5,9 @@ pub const Image = @import("Image.zig"); pub const Interpreter = @import("Interpreter.zig"); pub const Module = @import("Module.zig"); pub const State = @import("State.zig"); + const opcode = @import("opcode.zig"); +const spv_data = @import("spv_data.zig"); pub const SpvVoid = void; pub const SpvByte = u8; @@ -18,4 +20,5 @@ test { std.testing.refAllDecls(Module); std.testing.refAllDecls(State); std.testing.refAllDecls(opcode); + std.testing.refAllDecls(spv_data); } diff --git a/src/spv_data.zig b/src/spv_data.zig new file mode 100644 index 0000000..252463d --- /dev/null +++ b/src/spv_data.zig @@ -0,0 +1,76 @@ +const lib = @import("lib.zig"); +const spv = lib.spv; + +pub const SourceLanguage = enum(u32) { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + Rust = 13, +}; + +pub fn vendorName(id: u32) []const u8 { + return switch (id) { + 0 => "Khronos", + 1 => "LunarG", + 2 => "Valve", + 3 => "Codeplay", + 4 => "NVIDIA", + 5 => "ARM", + 6 => "Khronos LLVM/SPIR-V Translator", + 7 => "Khronos SPIR-V Tools Assembler", + 8 => "Khronos Glslang Reference Front End", + 9 => "Qualcomm", + 10 => "AMD", + 11 => "Intel", + 12 => "Imagination", + 13 => "Google Shaderc over Glslang", + 14 => "Google spiregg", + 15 => "Google rspirv", + 16 => "X-LEGEND Mesa-IR/SPIR-V Translator", + 17 => "Khronos SPIR-V Tools Linker", + 18 => "Wine VKD3D Shader Compiler", + 19 => "Tellusim Clay Shader Compiler", + 20 => "W3C WebGPU Group WHLSL Shader Translator", + 21 => "Google Clspv", + 22 => "LLVM MLIR SPIR-V Serializer", + 23 => "Google Tint Compiler", + 24 => "Google ANGLE Shader Compiler", + 25 => "Netease Games Messiah Shader Compiler", + 26 => "Xenia Xenia Emulator Microcode Translator", + 27 => "Embark Studios Rust GPU Compiler Backend", + 28 => "gfx-rs community Naga", + 29 => "Mikkosoft Productions MSP Shader Compiler", + 30 => "SpvGenTwo community SpvGenTwo SPIR-V IR Tools", + 31 => "Google Skia SkSL", + 32 => "TornadoVM Beehive SPIRV Toolkit", + 33 => "DragonJoker ShaderWriter", + 34 => "Rayan Hatout SPIRVSmith", + 35 => "Saarland University Shady", + 36 => "Taichi Graphics Taichi", + 37 => "heroseh Hero C Compiler", + 38 => "Meta SparkSL", + 39 => "SirLynix Nazara ShaderLang Compiler", + 40 => "Khronos Slang Compiler", + 41 => "Zig Software Foundation Zig Compiler", + 42 => "Rendong Liang spq", + 43 => "LLVM LLVM SPIR-V Backend", + 44 => "Robert Konrad Kongruent", + 45 => "Kitsunebi Games Nuvk SPIR-V Emitter and DLSL compiler", + 46 => "Nintendo", + 47 => "ARM", + 48 => "Goopax", + 49 => "Icyllis Milica Arc3D Shader Compiler", + + else => "Unknown", + }; +}