//! ---------------------------------------------------- //! `🗲` Vulkan Shader `🗲` //! ---------------------------------------------------- const std = @import("std"); const vk = @import("vulkan"); const gtl = @import("gtl"); const Device = @import("device.zig"); const Self = @This(); // // FIELDS // raw: vk.VkShaderModule, device: *const Device, /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn init( spv_path: []const u8, device: *const Device, alloc: std.mem.Allocator, io: std.Io, ) !Self { const code = try readFile(spv_path, alloc, io); defer alloc.free(code); const module = try createModule( code, device, ); return .{ .raw = module, .device = device, }; } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn deinit(self: *Self) void { if (self.raw) |raw| { vk.vkDestroyShaderModule(self.device.raw, raw, null); self.raw = null; } } /// ---------------------------------------------------- /// Helper /// ---------------------------------------------------- fn createModule( code: []u8, device: *const Device, ) !*vk.VkShaderModule_T { var create_info: vk.VkShaderModuleCreateInfo = .{ .sType = vk.VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, .pCode = @ptrCast(@alignCast(code.ptr)), .codeSize = code.len, }; var module: vk.VkShaderModule = null; if (vk.vkCreateShaderModule(device.raw, &create_info, null, &module) != vk.VK_SUCCESS) { return error.FailedToCreateShaderModule; } return module.?; } /// ---------------------------------------------------- /// Helper /// ---------------------------------------------------- fn readFile( path: []const u8, alloc: std.mem.Allocator, io: std.Io, ) ![]u8 { return std.Io.Dir.cwd().readFileAlloc(io, path, alloc, .unlimited) catch |err| { gtl.log.err("{s}: {s}\n", .{ @errorName(err), path }, null); return err; }; }