Files
VulkanDriver/src/vulkan/PipelineLayout.zig
T
2026-05-12 03:01:17 +02:00

85 lines
2.5 KiB
Zig

const std = @import("std");
const vk = @import("vulkan");
const lib = @import("lib.zig");
const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
const DescriptorSetLayout = @import("DescriptorSetLayout.zig");
const VkError = @import("error_set.zig").VkError;
const Device = @import("Device.zig");
const Self = @This();
pub const ObjectType: vk.ObjectType = .pipeline_layout;
owner: *Device,
set_count: usize,
set_layouts: [lib.VULKAN_MAX_DESCRIPTOR_SETS]?*DescriptorSetLayout,
dynamic_descriptor_offsets: [lib.VULKAN_MAX_DESCRIPTOR_SETS]usize,
push_ranges_count: usize,
push_ranges: [lib.VULKAN_MAX_PUSH_CONSTANT_RANGES]vk.PushConstantRange,
ref_count: std.atomic.Value(usize),
vtable: *const VTable,
pub const VTable = struct {
destroy: *const fn (*Self, std.mem.Allocator) void,
};
pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.PipelineLayoutCreateInfo) VkError!Self {
_ = allocator;
var self: Self = .{
.owner = device,
.set_count = info.set_layout_count,
.set_layouts = [_]?*DescriptorSetLayout{null} ** lib.VULKAN_MAX_DESCRIPTOR_SETS,
.dynamic_descriptor_offsets = [_]usize{0} ** lib.VULKAN_MAX_DESCRIPTOR_SETS,
.push_ranges_count = info.push_constant_range_count,
.push_ranges = undefined,
.ref_count = std.atomic.Value(usize).init(1),
.vtable = undefined,
};
if (info.p_set_layouts) |set_layouts| {
var dynamic_descriptor_count: usize = 0;
for (set_layouts, 0..info.set_layout_count) |handle, i| {
self.dynamic_descriptor_offsets[i] = dynamic_descriptor_count;
if (handle != .null_handle) {
const layout = try NonDispatchable(DescriptorSetLayout).fromHandleObject(handle);
self.set_layouts[i] = layout;
layout.ref();
dynamic_descriptor_count += layout.dynamic_descriptor_count;
}
}
}
return self;
}
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
self.unref(allocator);
}
pub inline fn drop(self: *Self, allocator: std.mem.Allocator) void {
for (self.set_layouts) |set_layout| {
if (set_layout) |layout| {
layout.unref(allocator);
}
}
self.vtable.destroy(self, allocator);
}
pub inline fn ref(self: *Self) void {
_ = self.ref_count.fetchAdd(1, .monotonic);
}
pub inline fn unref(self: *Self, allocator: std.mem.Allocator) void {
if (self.ref_count.fetchSub(1, .release) == 1) {
self.drop(allocator);
}
}