From b9ef230c0e717ced43f09e0768234df248ee028a Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Tue, 17 Feb 2026 02:22:43 +0100 Subject: [PATCH] working on descriptor sets --- build.zig.zon | 12 ++++------- src/soft/SoftDescriptorSet.zig | 14 +++++++++++++ src/vulkan/DescriptorSet.zig | 12 ++++++++++- src/vulkan/DescriptorSetLayout.zig | 2 ++ src/vulkan/PipelineLayout.zig | 33 +++++++++++++++++++++++------- src/vulkan/lib.zig | 31 ++++++++++++++-------------- src/vulkan/lib_vulkan.zig | 19 +++++++++-------- 7 files changed, 83 insertions(+), 40 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 511e029..468fb33 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -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 = .{ diff --git a/src/soft/SoftDescriptorSet.zig b/src/soft/SoftDescriptorSet.zig index 0907251..4fa2e8c 100644 --- a/src/soft/SoftDescriptorSet.zig +++ b/src/soft/SoftDescriptorSet.zig @@ -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; +} diff --git a/src/vulkan/DescriptorSet.zig b/src/vulkan/DescriptorSet.zig index 7afc508..4839fe2 100644 --- a/src/vulkan/DescriptorSet.zig +++ b/src/vulkan/DescriptorSet.zig @@ -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); +} diff --git a/src/vulkan/DescriptorSetLayout.zig b/src/vulkan/DescriptorSetLayout.zig index 2b5b39f..f9b23f2 100644 --- a/src/vulkan/DescriptorSetLayout.zig +++ b/src/vulkan/DescriptorSetLayout.zig @@ -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, diff --git a/src/vulkan/PipelineLayout.zig b/src/vulkan/PipelineLayout.zig index 3fb4ce8..3baba94 100644 --- a/src/vulkan/PipelineLayout.zig +++ b/src/vulkan/PipelineLayout.zig @@ -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); } diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index 670023d..6a0fded 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -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 = .{ diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index 5540102..794a667 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -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 {