working on descriptor sets
All checks were successful
Build / build (push) Successful in 1m58s
Test / build_and_test (push) Successful in 38m44s

This commit is contained in:
2026-02-17 02:22:43 +01:00
parent 12a5902cb9
commit b9ef230c0e
7 changed files with 83 additions and 40 deletions

View File

@@ -5,10 +5,6 @@
.minimum_zig_version = "0.15.2",
.dependencies = .{
//.SPIRV_Tools = .{
// .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Toolz#2eed675251bbcf21ef34368d289be49d83bce781",
// .hash = "SPIRV_Tools-2026.1.0-7hzMwUeVAAA2Q60MBfoAvZypYnJ9Rzf-hxUkZAaJAo57",
//},
.compile_commands = .{
.url = "git+https://github.com/the-argus/zig-compile-commands#f74e2d13e43fafab3a71e19557a0e1cfbf0f2e1b",
.hash = "zig_compile_commands-0.0.1-OZg5-a3CAACM-h32Kjb1obTMqrKGs9YoDhorVZ8-LGle",
@@ -37,10 +33,6 @@
.url = "https://github.com/Aandreba/zigrc/archive/refs/tags/1.1.0.tar.gz",
.hash = "zigrc-1.0.0-lENlWzvQAACulrbkL9PVhWjFsWSkYhi7AmfSbCM-2Xlh",
},
.SPIRV_Interpreter = .{
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#57de432d0b43f050b5117a7c6add09e3906664fd",
.hash = "SPIRV_Interpreter-0.0.1-ajmpnyg_AwCeuAEr4KMaBqdCWA2IUsT8Q3mGuUo1PZ2b",
},
.cpuinfo = .{
.url = "git+https://github.com/Kbz-8/cpuinfo#4883954cfcec3f6c9ca9c4aaddfc26107e08726f",
.hash = "cpuinfo-0.0.1-RLgIQTLRMgF4dLo8AJ-HvnpFsJe6jmXCJjMWWjil6RF1",
@@ -61,6 +53,10 @@
.hash = "N-V-__8AABQ7TgCnPlp8MP4YA8znrjd6E-ZjpF1rvrS8J_2I",
.lazy = true,
},
.SPIRV_Interpreter = .{
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#2ea707ea57ea3e36d51d30c7bf363bfe2eca778c",
.hash = "SPIRV_Interpreter-0.0.1-ajmpn5lyAwBPB_XSXWCQwuUmXgledjEyt3hYXZfbCvSV",
},
},
.paths = .{

View File

@@ -17,7 +17,9 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
var interface = try Interface.init(device, allocator, layout);
interface.vtable = &.{
.copy = copy,
.destroy = destroy,
.write = write,
};
self.* = .{
@@ -26,7 +28,19 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
return self;
}
pub fn copy(interface: *Interface, copy_data: vk.CopyDescriptorSet) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
_ = self;
_ = copy_data;
}
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
allocator.destroy(self);
}
pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
_ = self;
_ = write_data;
}

View File

@@ -18,19 +18,29 @@ layout: *DescriptorSetLayout,
vtable: *const VTable,
pub const VTable = struct {
copy: *const fn (*Self, vk.CopyDescriptorSet) VkError!void,
destroy: *const fn (*Self, std.mem.Allocator) void,
write: *const fn (*Self, vk.WriteDescriptorSet) VkError!void,
};
pub fn init(device: *Device, allocator: std.mem.Allocator, layout: *DescriptorSetLayout) VkError!Self {
_ = allocator;
layout.ref();
return .{
.owner = device,
.layout = layout,
.vtable = undefined,
};
}
pub inline fn copy(self: *Self, copy_data: vk.CopyDescriptorSet) VkError!void {
try self.vtable.copy(self, copy_data);
}
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
allocator.free(self.layouts);
self.layout.unref(allocator);
self.vtable.destroy(self, allocator);
}
pub inline fn write(self: *Self, write_data: vk.WriteDescriptorSet) VkError!void {
try self.vtable.write(self, write_data);
}

View File

@@ -29,6 +29,7 @@ heap: []u8,
bindings: []BindingLayout,
dynamic_offset_count: usize,
dynamic_descriptor_count: usize,
/// Shader stages affected by this descriptor set
stages: vk.ShaderStageFlags,
@@ -113,6 +114,7 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Descr
.heap = heap,
.bindings = bindings,
.dynamic_offset_count = 0,
.dynamic_descriptor_count = 0,
.stages = stages,
.ref_count = std.atomic.Value(usize).init(1),
.vtable = undefined,

View File

@@ -2,7 +2,7 @@ const std = @import("std");
const vk = @import("vulkan");
const lib = @import("lib.zig");
const NonDispatchable = @import("NonDispatchable.zig");
const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
const DescriptorSetLayout = @import("DescriptorSetLayout.zig");
const VkError = @import("error_set.zig").VkError;
@@ -16,7 +16,7 @@ owner: *Device,
set_count: usize,
set_layouts: [lib.VULKAN_MAX_DESCRIPTOR_SETS]*DescriptorSetLayout,
set_layouts: [lib.VULKAN_MAX_DESCRIPTOR_SETS]?*DescriptorSetLayout,
dynamic_descriptor_offsets: [lib.VULKAN_MAX_DESCRIPTOR_SETS]usize,
@@ -46,17 +46,31 @@ pub const VTable = struct {
pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.PipelineLayoutCreateInfo) VkError!Self {
_ = allocator;
_ = info;
return .{
var self: Self = .{
.owner = device,
.set_count = 0,
.set_layouts = undefined,
.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 = 0,
.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 {
@@ -64,6 +78,11 @@ pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
}
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);
}

View File

@@ -62,22 +62,21 @@ pub const VULKAN_MAX_DESCRIPTOR_SETS = 32;
/// by the number of possible shader stages. Not the number of stages that can
/// be compiled together (a pipeline layout can be used in multiple pipelnes
/// wth different sets of shaders) but the total number of stage bits supported
/// by the implementation. Currently, those are
///
/// - VK_SHADER_STAGE_VERTEX_BIT
/// - VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
/// - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
/// - VK_SHADER_STAGE_GEOMETRY_BIT
/// - VK_SHADER_STAGE_FRAGMENT_BIT
/// - VK_SHADER_STAGE_COMPUTE_BIT
/// - VK_SHADER_STAGE_RAYGEN_BIT_KHR
/// - VK_SHADER_STAGE_ANY_HIT_BIT_KHR
/// - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
/// - VK_SHADER_STAGE_MISS_BIT_KHR
/// - VK_SHADER_STAGE_INTERSECTION_BIT_KHR
/// - VK_SHADER_STAGE_CALLABLE_BIT_KHR
/// - VK_SHADER_STAGE_TASK_BIT_EXT
/// - VK_SHADER_STAGE_MESH_BIT_EXT
/// by the implementation. Currently, those are
/// - VK_SHADER_STAGE_VERTEX_BIT
/// - VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
/// - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
/// - VK_SHADER_STAGE_GEOMETRY_BIT
/// - VK_SHADER_STAGE_FRAGMENT_BIT
/// - VK_SHADER_STAGE_COMPUTE_BIT
/// - VK_SHADER_STAGE_RAYGEN_BIT_KHR
/// - VK_SHADER_STAGE_ANY_HIT_BIT_KHR
/// - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
/// - VK_SHADER_STAGE_MISS_BIT_KHR
/// - VK_SHADER_STAGE_INTERSECTION_BIT_KHR
/// - VK_SHADER_STAGE_CALLABLE_BIT_KHR
/// - VK_SHADER_STAGE_TASK_BIT_EXT
/// - VK_SHADER_STAGE_MESH_BIT_EXT
pub const VULKAN_MAX_PUSH_CONSTANT_RANGES = 14;
pub const std_options: std.Options = .{

View File

@@ -943,7 +943,8 @@ pub export fn strollCreatePipelineLayout(p_device: vk.Device, info: *const vk.Pi
return .error_validation_failed;
}
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
// Device scoped because we're reference counting and layout may not be destroyed when vkDestroyPipelineLayout is called
const allocator = VulkanAllocator.init(callbacks, .device).allocator();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
const layout = device.createPipelineLayout(allocator, info) catch |err| return toVkResult(err);
p_layout.* = (NonDispatchable(PipelineLayout).wrap(allocator, layout) catch |err| return toVkResult(err)).toVkHandle(vk.PipelineLayout);
@@ -1589,15 +1590,17 @@ pub export fn strollUpdateDescriptorSets(p_device: vk.Device, write_count: u32,
entryPointBeginLogTrace(.vkUpdateDescriptorSets);
defer entryPointEndLogTrace();
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return errorLogger(err);
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
notImplementedWarning();
for (writes, 0..write_count) |write, _| {
const set = NonDispatchable(DescriptorSet).fromHandleObject(write.dst_set) catch |err| return errorLogger(err);
set.write(write) catch |err| return errorLogger(err);
}
_ = device;
_ = write_count;
_ = writes;
_ = copy_count;
_ = copies;
for (copies, 0..copy_count) |copy, _| {
const set = NonDispatchable(DescriptorSet).fromHandleObject(copy.dst_set) catch |err| return errorLogger(err);
set.copy(copy) catch |err| return errorLogger(err);
}
}
pub export fn strollWaitForFences(p_device: vk.Device, count: u32, p_fences: [*]const vk.Fence, waitForAll: vk.Bool32, timeout: u64) callconv(vk.vulkan_call_conv) vk.Result {