NYXGFX/src/rhi/vulkan/resource/shader.zig
2026-08-11 21:06:28 +01:00

84 lines
2.3 KiB
Zig

//! ----------------------------------------------------
//! `🗲` Vulkan Shader `🗲`
//! ----------------------------------------------------
const std = @import("std");
const vk = @import("vulkan");
const gtl = @import("gtl");
const Device = @import("device.zig");
const Self = @This();
//
// FIELDS
//
vert: *vk.VkShaderModule_T,
frag: *vk.VkShaderModule_T,
device: *const Device,
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn init(
vert_spv_path: []const u8,
frag_spv_path: []const u8,
device: *const Device,
alloc: std.mem.Allocator,
io: std.Io,
) !Self {
const vert_code = try readFile(vert_spv_path, alloc, io);
defer alloc.free(vert_code);
const frag_code = try readFile(frag_spv_path, alloc, io);
defer alloc.free(frag_code);
const vert_module = try createModule(vert_code, device);
const frag_module = try createModule(frag_code, device);
return .{
.vert = vert_module,
.frag = frag_module,
.device = device,
};
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn deinit(self: *Self) void {
vk.vkDestroyShaderModule(self.device.raw, self.vert, null);
vk.vkDestroyShaderModule(self.device.raw, self.frag, 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;
};
}