{vulkan,examples}: fix descriptor set bug

This commit is contained in:
Ali Cheraghi 2024-07-13 05:42:16 +03:30 committed by Stephen Gutekanst
parent 266e7a548b
commit 0023ab14fb
6 changed files with 45 additions and 48 deletions

View file

@ -106,6 +106,8 @@ fn update(core: *mach.Core.Mod, game: *Mod) !void {
defer command.release();
core.state().queue.submit(&[_]*gpu.CommandBuffer{command});
core.schedule(.present_frame);
// update the window title every second
if (game.state().title_timer.read() >= 1.0) {
game.state().title_timer.reset();

View file

@ -104,6 +104,8 @@ fn update(core: *mach.Core.Mod, game: *Mod) !void {
defer command.release();
core.state().queue.submit(&[_]*gpu.CommandBuffer{command});
core.schedule(.present_frame);
// update the window title every second
if (game.state().title_timer.read() >= 1.0) {
game.state().title_timer.reset();

View file

@ -110,9 +110,7 @@ fn init(
});
}
fn deinit(
renderer: *Mod,
) !void {
fn deinit(renderer: *Mod) !void {
renderer.state().pipeline.release();
for (renderer.state().bind_groups) |bind_group| bind_group.release();
renderer.state().uniform_buffer.release();
@ -178,4 +176,6 @@ fn renderFrame(
var command = encoder.finish(&.{ .label = label });
defer command.release();
core.state().queue.submit(&[_]*gpu.CommandBuffer{command});
core.schedule(.present_frame);
}

View file

@ -69,9 +69,8 @@ fn afterInit(audio: *mach.Audio.Mod, app: *Mod) void {
audio.state().on_state_change = app.system(.audio_state_change);
}
fn deinit(core: *mach.Core.Mod, audio: *mach.Audio.Mod) void {
fn deinit(audio: *mach.Audio.Mod) void {
audio.schedule(.deinit);
core.schedule(.deinit);
}
fn audioStateChange(

View file

@ -77,12 +77,12 @@ pub const App = struct {
try app.mods.dispatch(&stack_space, .{});
// Run `update` when `init` and all other systems are exectued
app.mods.schedule(app.main_mod, .update);
app.mods.schedule(.mach_core, .present_frame);
}
app.mods.schedule(app.main_mod, .deinit);
app.mods.schedule(.mach_core, .deinit);
// Final Dispatch to deinitalize resources
app.mods.schedule(app.main_mod, .deinit);
try app.mods.dispatch(&stack_space, .{});
app.mods.schedule(.mach_core, .deinit);
try app.mods.dispatch(&stack_space, .{});
}
};

View file

@ -1568,19 +1568,15 @@ pub const BindGroupLayout = struct {
manager: utils.Manager(BindGroupLayout) = .{},
device: *Device,
vk_layout: vk.DescriptorSetLayout,
desc_pool: vk.DescriptorPool,
desc_types: std.AutoArrayHashMapUnmanaged(vk.DescriptorType, u32),
entries: std.ArrayListUnmanaged(Entry),
const max_sets = 512;
pub fn init(device: *Device, desc: *const sysgpu.BindGroupLayout.Descriptor) !*BindGroupLayout {
const vk_device = device.vk_device;
var bindings = try std.ArrayListUnmanaged(vk.DescriptorSetLayoutBinding).initCapacity(allocator, desc.entry_count);
defer bindings.deinit(allocator);
var desc_types = std.AutoArrayHashMap(vk.DescriptorType, u32).init(allocator);
defer desc_types.deinit();
errdefer desc_types.deinit();
var entries = try std.ArrayListUnmanaged(Entry).initCapacity(allocator, desc.entry_count);
errdefer entries.deinit(allocator);
@ -1608,47 +1604,25 @@ pub const BindGroupLayout = struct {
});
}
const vk_layout = try vkd.createDescriptorSetLayout(vk_device, &vk.DescriptorSetLayoutCreateInfo{
const vk_layout = try vkd.createDescriptorSetLayout(device.vk_device, &.{
.binding_count = @intCast(bindings.items.len),
.p_bindings = bindings.items.ptr,
}, null);
// Descriptor Pool
var pool_sizes = try std.ArrayList(vk.DescriptorPoolSize).initCapacity(allocator, desc_types.count());
defer pool_sizes.deinit();
var desc_types_iter = desc_types.iterator();
while (desc_types_iter.next()) |entry| {
pool_sizes.appendAssumeCapacity(.{
.type = entry.key_ptr.*,
.descriptor_count = max_sets * entry.value_ptr.*,
});
}
const desc_pool = try vkd.createDescriptorPool(vk_device, &vk.DescriptorPoolCreateInfo{
.flags = .{ .free_descriptor_set_bit = true },
.max_sets = max_sets,
.pool_size_count = @intCast(pool_sizes.items.len),
.p_pool_sizes = pool_sizes.items.ptr,
}, null);
// Result
const layout = try allocator.create(BindGroupLayout);
layout.* = .{
.device = device,
.vk_layout = vk_layout,
.desc_pool = desc_pool,
.desc_types = desc_types.unmanaged,
.entries = entries,
};
return layout;
}
pub fn deinit(layout: *BindGroupLayout) void {
const vk_device = layout.device.vk_device;
vkd.destroyDescriptorSetLayout(vk_device, layout.vk_layout, null);
vkd.destroyDescriptorPool(vk_device, layout.desc_pool, null);
vkd.destroyDescriptorSetLayout(layout.device.vk_device, layout.vk_layout, null);
layout.desc_types.deinit(allocator);
layout.entries.deinit(allocator);
allocator.destroy(layout);
}
@ -1676,20 +1650,41 @@ pub const BindGroup = struct {
manager: utils.Manager(BindGroup) = .{},
device: *Device,
layout: *BindGroupLayout,
desc_pool: vk.DescriptorPool,
desc_set: vk.DescriptorSet,
buffers: std.ArrayListUnmanaged(BufferAccess),
texture_views: std.ArrayListUnmanaged(TextureViewAccess),
samplers: std.ArrayListUnmanaged(*Sampler),
pub fn init(device: *Device, desc: *const sysgpu.BindGroup.Descriptor) !*BindGroup {
const vk_device = device.vk_device;
const layout: *BindGroupLayout = @ptrCast(@alignCast(desc.layout));
layout.manager.reference();
// The total number of descriptors sets that fits given the max.
const max_sets: u32 = @intCast(256 / @max(desc.entry_count, 1));
var pool_sizes = try std.ArrayList(vk.DescriptorPoolSize).initCapacity(allocator, layout.desc_types.count());
defer pool_sizes.deinit();
var desc_types_iter = layout.desc_types.iterator();
while (desc_types_iter.next()) |entry| {
pool_sizes.appendAssumeCapacity(.{
.type = entry.key_ptr.*,
// Grow the number of desciptors in the pool to fit the computed max_sets.
.descriptor_count = max_sets * entry.value_ptr.*,
});
}
const desc_pool = try vkd.createDescriptorPool(device.vk_device, &vk.DescriptorPoolCreateInfo{
.flags = .{},
.max_sets = max_sets,
.pool_size_count = @intCast(pool_sizes.items.len),
.p_pool_sizes = pool_sizes.items.ptr,
}, null);
var desc_set: vk.DescriptorSet = undefined;
try vkd.allocateDescriptorSets(vk_device, &vk.DescriptorSetAllocateInfo{
.descriptor_pool = layout.desc_pool,
try vkd.allocateDescriptorSets(device.vk_device, &vk.DescriptorSetAllocateInfo{
.descriptor_pool = desc_pool,
.descriptor_set_count = 1,
.p_set_layouts = @ptrCast(&layout.vk_layout),
}, @ptrCast(&desc_set));
@ -1755,7 +1750,7 @@ pub const BindGroup = struct {
}
}
vkd.updateDescriptorSets(vk_device, @intCast(writes.len), writes.ptr, 0, undefined);
vkd.updateDescriptorSets(device.vk_device, @intCast(writes.len), writes.ptr, 0, undefined);
// Resource tracking
var buffers = std.ArrayListUnmanaged(BufferAccess){};
@ -1806,6 +1801,7 @@ pub const BindGroup = struct {
bind_group.* = .{
.device = device,
.layout = layout,
.desc_pool = desc_pool,
.desc_set = desc_set,
.buffers = buffers,
.texture_views = texture_views,
@ -1815,9 +1811,7 @@ pub const BindGroup = struct {
}
pub fn deinit(group: *BindGroup) void {
const vk_device = group.device.vk_device;
vkd.freeDescriptorSets(vk_device, group.layout.desc_pool, 1, @ptrCast(&group.desc_set)) catch unreachable;
vkd.destroyDescriptorPool(group.device.vk_device, group.desc_pool, null);
for (group.buffers.items) |access| access.buffer.manager.release();
for (group.texture_views.items) |access| access.texture_view.manager.release();