2026-08-11 21:06:28 +01:00
|
|
|
//! ----------------------------------------------------
|
|
|
|
|
//! `🗲` Vulkan Shader `🗲`
|
|
|
|
|
//! ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const std = @import("std");
|
|
|
|
|
const vk = @import("vulkan");
|
|
|
|
|
const gtl = @import("gtl");
|
|
|
|
|
const Device = @import("device.zig");
|
|
|
|
|
const Self = @This();
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// FIELDS
|
|
|
|
|
//
|
|
|
|
|
|
2026-08-12 20:31:05 +01:00
|
|
|
raw: vk.VkShaderModule,
|
2026-08-11 21:06:28 +01:00
|
|
|
device: *const Device,
|
|
|
|
|
|
|
|
|
|
/// ----------------------------------------------------
|
|
|
|
|
/// ----------------------------------------------------
|
|
|
|
|
pub fn init(
|
2026-08-12 02:11:57 +01:00
|
|
|
spv_path: []const u8,
|
2026-08-11 21:06:28 +01:00
|
|
|
device: *const Device,
|
|
|
|
|
alloc: std.mem.Allocator,
|
|
|
|
|
io: std.Io,
|
|
|
|
|
) !Self {
|
2026-08-12 02:11:57 +01:00
|
|
|
const code = try readFile(spv_path, alloc, io);
|
|
|
|
|
defer alloc.free(code);
|
2026-08-11 21:06:28 +01:00
|
|
|
|
2026-08-12 02:11:57 +01:00
|
|
|
const module = try createModule(
|
|
|
|
|
code,
|
|
|
|
|
device,
|
|
|
|
|
);
|
2026-08-11 21:06:28 +01:00
|
|
|
|
|
|
|
|
return .{
|
2026-08-12 02:11:57 +01:00
|
|
|
.raw = module,
|
2026-08-11 21:06:28 +01:00
|
|
|
.device = device,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ----------------------------------------------------
|
|
|
|
|
/// ----------------------------------------------------
|
|
|
|
|
pub fn deinit(self: *Self) void {
|
2026-08-12 20:31:05 +01:00
|
|
|
if (self.raw) |raw| {
|
|
|
|
|
vk.vkDestroyShaderModule(self.device.raw, raw, null);
|
|
|
|
|
self.raw = null;
|
|
|
|
|
}
|
2026-08-11 21:06:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// ----------------------------------------------------
|
|
|
|
|
/// 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;
|
|
|
|
|
};
|
|
|
|
|
}
|