diff --git a/README.md b/README.md index b6a2058..294eb2f 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ vkCmdSetStencilCompareMask | ✅ Implemented vkCmdSetStencilReference | ✅ Implemented vkCmdSetStencilWriteMask | ✅ Implemented vkCmdSetViewport | ✅ Implemented -vkCmdUpdateBuffer | ⚙️ WIP +vkCmdUpdateBuffer | ✅ Implemented vkCmdWaitEvents | ✅ Implemented vkCmdWriteTimestamp | ⚙️ WIP vkCreateBuffer | ✅ Implemented diff --git a/src/soft/SoftBinarySemaphore.zig b/src/soft/SoftBinarySemaphore.zig index 880d694..7fe5aca 100644 --- a/src/soft/SoftBinarySemaphore.zig +++ b/src/soft/SoftBinarySemaphore.zig @@ -9,6 +9,9 @@ const Self = @This(); pub const Interface = base.BinarySemaphore; interface: Interface, +mutex: std.Io.Mutex, +condition: std.Io.Condition, +is_signaled: bool, pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.SemaphoreCreateInfo) VkError!*Self { const self = allocator.create(Self) catch return VkError.OutOfHostMemory; @@ -18,10 +21,15 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v interface.vtable = &.{ .destroy = destroy, + .signal = signal, + .wait = wait, }; self.* = .{ .interface = interface, + .mutex = .init, + .condition = .init, + .is_signaled = false, }; return self; } @@ -30,3 +38,27 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); allocator.destroy(self); } + +pub fn signal(interface: *Interface) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + const io = interface.owner.io(); + + self.mutex.lock(io) catch return VkError.DeviceLost; + defer self.mutex.unlock(io); + + self.is_signaled = true; + self.condition.broadcast(io); +} + +pub fn wait(interface: *Interface) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + const io = interface.owner.io(); + + self.mutex.lock(io) catch return VkError.DeviceLost; + defer self.mutex.unlock(io); + + while (!self.is_signaled) { + self.condition.wait(io, &self.mutex) catch return VkError.DeviceLost; + } + self.is_signaled = false; +} diff --git a/src/soft/SoftBuffer.zig b/src/soft/SoftBuffer.zig index 4f8cb06..aa85bd1 100644 --- a/src/soft/SoftBuffer.zig +++ b/src/soft/SoftBuffer.zig @@ -57,10 +57,10 @@ pub fn copyBuffer(self: *const Self, dst: *Self, regions: []const vk.BufferCopy) } pub fn fillBuffer(self: *Self, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void { - const memory = if (self.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv; - var bytes = if (size == vk.WHOLE_SIZE) memory.size - offset else size; + if (self.interface.memory == null) return VkError.InvalidDeviceMemoryDrv; + var bytes = if (size == vk.WHOLE_SIZE) self.interface.size - offset else size; - const map = try self.mapAsSliceWithOffset(u32, offset, @divFloor(bytes, @sizeOf(u32)) * @sizeOf(u32)); + const map = try self.mapAsSliceWithAddedOffset(u32, offset, @divFloor(bytes, @sizeOf(u32)) * @sizeOf(u32)); var i: usize = 0; while (bytes >= 4) : ({ diff --git a/src/soft/SoftCommandBuffer.zig b/src/soft/SoftCommandBuffer.zig index 87456e3..934f392 100644 --- a/src/soft/SoftCommandBuffer.zig +++ b/src/soft/SoftCommandBuffer.zig @@ -85,6 +85,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v .setStencilReference = setStencilReference, .setStencilWriteMask = setStencilWriteMask, .setViewport = setViewport, + .updateBuffer = updateBuffer, .waitEvent = waitEvent, }; @@ -819,7 +820,7 @@ pub fn dispatchIndirect(interface: *Interface, buffer: *base.Buffer, offset: vk. pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void { const impl: *Impl = @ptrCast(@alignCast(context)); - const command = try impl.buffer.mapAsWithOffset(vk.DispatchIndirectCommand, impl.offset); + const command = try impl.buffer.mapToWithAddedOffset(vk.DispatchIndirectCommand, impl.offset); try device.compute.dispatch(command.x, command.y, command.z); } }; @@ -908,7 +909,7 @@ pub fn drawIndexedIndirect(interface: *Interface, buffer: *base.Buffer, offset: pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void { const impl: *Impl = @ptrCast(@alignCast(context)); for (0..impl.count) |index| { - const command = try impl.buffer.mapAsWithOffset(vk.DrawIndexedIndirectCommand, impl.offset + index * impl.stride); + const command = try impl.buffer.mapToWithAddedOffset(vk.DrawIndexedIndirectCommand, impl.offset + index * impl.stride); try device.renderer.drawIndexed(command.index_count, command.instance_count, command.first_index, command.first_instance, command.vertex_offset); } } @@ -940,7 +941,7 @@ pub fn drawIndirect(interface: *Interface, buffer: *base.Buffer, offset: usize, pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void { const impl: *Impl = @ptrCast(@alignCast(context)); for (0..impl.count) |index| { - const command = try impl.buffer.mapAsWithOffset(vk.DrawIndirectCommand, impl.offset + index * impl.stride); + const command = try impl.buffer.mapToWithAddedOffset(vk.DrawIndirectCommand, impl.offset + index * impl.stride); try device.renderer.draw(command.vertex_count, command.instance_count, command.first_vertex, command.first_instance); } } @@ -1028,6 +1029,36 @@ pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.Device self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory; } +pub fn updateBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize, data: []const u8) VkError!void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + const allocator = self.command_allocator.allocator(); + + const CommandImpl = struct { + const Impl = @This(); + + buffer: *SoftBuffer, + offset: vk.DeviceSize, + data: []const u8, + + pub fn execute(context: *anyopaque, _: *ExecutionDevice) VkError!void { + const impl: *Impl = @ptrCast(@alignCast(context)); + const map = try impl.buffer.mapAsSliceWithAddedOffset(u8, impl.offset, impl.data.len); + @memcpy(map, impl.data); + } + }; + + const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory; + errdefer allocator.destroy(cmd); + + const data_copy = allocator.dupe(u8, data) catch return VkError.OutOfHostMemory; + cmd.* = .{ + .buffer = @alignCast(@fieldParentPtr("interface", buffer)), + .offset = offset, + .data = data_copy, + }; + self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory; +} + pub fn nextSubpass(interface: *Interface, _: vk.SubpassContents) VkError!void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); const allocator = self.command_allocator.allocator(); diff --git a/src/soft/SoftQueue.zig b/src/soft/SoftQueue.zig index 6d27283..1a60687 100644 --- a/src/soft/SoftQueue.zig +++ b/src/soft/SoftQueue.zig @@ -2,8 +2,6 @@ const std = @import("std"); const vk = @import("vulkan"); const base = @import("base"); -const RefCounter = base.RefCounter; - const ExecutionDevice = @import("device/Device.zig"); const Dispatchable = base.Dispatchable; @@ -18,6 +16,18 @@ pub const Interface = base.Queue; interface: Interface, group: std.Io.Group, +mutex: std.Io.Mutex, +condition: std.Io.Condition, +next_sequence: usize, +executing_sequence: usize, + +const TaskData = struct { + queue: *Self, + soft_device: *SoftDevice, + sequence: usize, + infos: std.ArrayList(Interface.SubmitInfo), + fence: ?*base.Fence, +}; pub fn create(allocator: std.mem.Allocator, device: *base.Device, index: u32, family_index: u32, flags: vk.DeviceQueueCreateFlags) VkError!*Interface { const self = allocator.create(Self) catch return VkError.OutOfHostMemory; @@ -34,6 +44,10 @@ pub fn create(allocator: std.mem.Allocator, device: *base.Device, index: u32, fa self.* = .{ .interface = interface, .group = .init, + .mutex = .init, + .condition = .init, + .next_sequence = 0, + .executing_sequence = 0, }; return &self.interface; } @@ -54,22 +68,34 @@ pub fn bindSparse(interface: *Interface, info: []const vk.BindSparseInfo, fence: pub fn submit(interface: *Interface, infos: []Interface.SubmitInfo, p_fence: ?*base.Fence) VkError!void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); const soft_device: *SoftDevice = @alignCast(@fieldParentPtr("interface", interface.owner)); - const allocator = soft_device.device_allocator.allocator(); - const io = soft_device.interface.io(); + const io = interface.owner.io(); - const runners_counter = allocator.create(RefCounter) catch return VkError.OutOfDeviceMemory; - errdefer allocator.destroy(runners_counter); - runners_counter.* = .init; - runners_counter.setRef(infos.len); + const task_data = allocator.create(TaskData) catch return VkError.OutOfDeviceMemory; + errdefer allocator.destroy(task_data); - for (infos) |info| { - // Cloning info to keep them alive until command execution ends - const cloned_info: Interface.SubmitInfo = .{ - .command_buffers = info.command_buffers.clone(allocator) catch return VkError.OutOfDeviceMemory, - }; - self.group.async(io, Self.taskRunner, .{ self, cloned_info, p_fence, runners_counter }); - } + var cloned_infos = try cloneSubmitInfos(allocator, infos); + errdefer deinitSubmitInfos(allocator, &cloned_infos); + + const sequence = blk: { + self.mutex.lock(io) catch return VkError.DeviceLost; + defer self.mutex.unlock(io); + + const seq = self.next_sequence; + self.next_sequence += 1; + + break :blk seq; + }; + + task_data.* = .{ + .queue = self, + .soft_device = soft_device, + .sequence = sequence, + .infos = cloned_infos, + .fence = p_fence, + }; + + self.group.async(io, Self.taskRunner, .{task_data}); } pub fn waitIdle(interface: *Interface) VkError!void { @@ -78,20 +104,9 @@ pub fn waitIdle(interface: *Interface) VkError!void { self.group.await(io) catch return VkError.DeviceLost; } -fn taskRunner(self: *Self, info: Interface.SubmitInfo, p_fence: ?*base.Fence, runners_counter: *RefCounter) void { - defer { - runners_counter.unref(); - if (!runners_counter.hasRefs()) { - const soft_device: *SoftDevice = @alignCast(@fieldParentPtr("interface", self.interface.owner)); - const allocator = soft_device.device_allocator.allocator(); - allocator.destroy(runners_counter); - } - } - - var soft_device: *SoftDevice = @alignCast(@fieldParentPtr("interface", self.interface.owner)); - defer { - var command_buffers = info.command_buffers; - command_buffers.deinit(soft_device.device_allocator.allocator()); +fn executeSubmitInfo(soft_device: *SoftDevice, info: Interface.SubmitInfo) VkError!void { + for (info.wait_semaphores.items) |semaphore| { + try semaphore.wait(); } var execution_device: ExecutionDevice = undefined; @@ -103,9 +118,81 @@ fn taskRunner(self: *Self, info: Interface.SubmitInfo, p_fence: ?*base.Fence, ru soft_command_buffer.execute(&execution_device); } - if (p_fence) |fence| { - if (runners_counter.getRefsCount() == 1) { - fence.signal() catch {}; - } + for (info.signal_semaphores.items) |semaphore| { + try semaphore.signal(); } } + +fn taskRunner(data: *TaskData) void { + const io = data.queue.interface.owner.io(); + const allocator = data.soft_device.device_allocator.allocator(); + defer { + deinitSubmitInfos(allocator, &data.infos); + allocator.destroy(data); + } + + { + data.queue.mutex.lock(io) catch return; + defer data.queue.mutex.unlock(io); + + while (data.sequence != data.queue.executing_sequence) { + data.queue.condition.wait(io, &data.queue.mutex) catch return; + } + } + + var submit_err: ?VkError = null; + for (data.infos.items) |info| { + executeSubmitInfo(data.soft_device, info) catch |err| { + submit_err = err; + break; + }; + } + + if (submit_err) |err| { + std.log.scoped(.SoftQueue).err("Queue submit failed with '{s}'", .{@errorName(err)}); + } + + if (data.fence) |fence| { + fence.signal() catch |err| { + std.log.scoped(.SoftQueue).err("Queue submit fence signal failed with '{s}'", .{@errorName(err)}); + }; + } + + data.queue.mutex.lock(io) catch return; + data.queue.executing_sequence += 1; + data.queue.condition.broadcast(io); + data.queue.mutex.unlock(io); +} + +fn cloneSubmitInfos(allocator: std.mem.Allocator, infos: []Interface.SubmitInfo) VkError!std.ArrayList(Interface.SubmitInfo) { + var cloned_infos = std.ArrayList(Interface.SubmitInfo).initCapacity(allocator, infos.len) catch return VkError.OutOfDeviceMemory; + errdefer deinitSubmitInfos(allocator, &cloned_infos); + + for (infos) |info| { + var wait_semaphores = info.wait_semaphores.clone(allocator) catch return VkError.OutOfDeviceMemory; + errdefer wait_semaphores.deinit(allocator); + + var command_buffers = info.command_buffers.clone(allocator) catch return VkError.OutOfDeviceMemory; + errdefer command_buffers.deinit(allocator); + + var signal_semaphores = info.signal_semaphores.clone(allocator) catch return VkError.OutOfDeviceMemory; + errdefer signal_semaphores.deinit(allocator); + + cloned_infos.append(allocator, .{ + .wait_semaphores = wait_semaphores, + .command_buffers = command_buffers, + .signal_semaphores = signal_semaphores, + }) catch return VkError.OutOfDeviceMemory; + } + + return cloned_infos; +} + +fn deinitSubmitInfos(allocator: std.mem.Allocator, infos: *std.ArrayList(Interface.SubmitInfo)) void { + for (infos.items) |*info| { + info.wait_semaphores.deinit(allocator); + info.command_buffers.deinit(allocator); + info.signal_semaphores.deinit(allocator); + } + infos.deinit(allocator); +} diff --git a/src/soft/device/ComputeDispatcher.zig b/src/soft/device/ComputeDispatcher.zig index 9c46e9b..abf6354 100644 --- a/src/soft/device/ComputeDispatcher.zig +++ b/src/soft/device/ComputeDispatcher.zig @@ -47,7 +47,8 @@ pub fn init(device: *SoftDevice, state: *PipelineState) Self { } pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count_z: u32) VkError!void { - const group_count: usize = @intCast(group_count_x * group_count_y * group_count_z); + const group_count_xy = std.math.mul(usize, group_count_x, group_count_y) catch return VkError.ValidationFailed; + const group_count = std.math.mul(usize, group_count_xy, group_count_z) catch return VkError.ValidationFailed; const pipeline = self.state.pipeline orelse return VkError.InvalidPipelineDrv; const shader = pipeline.stages.getPtr(.compute) orelse return VkError.InvalidPipelineDrv; diff --git a/src/vulkan/BinarySemaphore.zig b/src/vulkan/BinarySemaphore.zig index 4a913bc..173f813 100644 --- a/src/vulkan/BinarySemaphore.zig +++ b/src/vulkan/BinarySemaphore.zig @@ -16,6 +16,8 @@ vtable: *const VTable, pub const VTable = struct { destroy: *const fn (*Self, std.mem.Allocator) void, + signal: *const fn (*Self) VkError!void, + wait: *const fn (*Self) VkError!void, }; pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.SemaphoreCreateInfo) VkError!Self { @@ -30,3 +32,11 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Semap pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { self.vtable.destroy(self, allocator); } + +pub inline fn signal(self: *Self) VkError!void { + try self.vtable.signal(self); +} + +pub inline fn wait(self: *Self) VkError!void { + try self.vtable.wait(self); +} diff --git a/src/vulkan/CommandBuffer.zig b/src/vulkan/CommandBuffer.zig index 43db33b..d9b1449 100644 --- a/src/vulkan/CommandBuffer.zig +++ b/src/vulkan/CommandBuffer.zig @@ -80,6 +80,7 @@ pub const DispatchTable = struct { setStencilReference: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void, setStencilWriteMask: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void, setViewport: *const fn (*Self, u32, []const vk.Viewport) VkError!void, + updateBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, []const u8) VkError!void, waitEvent: *const fn (*Self, *Event, vk.PipelineStageFlags, vk.PipelineStageFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void, }; @@ -245,6 +246,10 @@ pub inline fn dispatchIndirect(self: *Self, buffer: *Buffer, offset: vk.DeviceSi try self.dispatch_table.dispatchIndirect(self, buffer, offset); } +pub inline fn updateBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, data: []const u8) VkError!void { + try self.dispatch_table.updateBuffer(self, buffer, offset, data); +} + pub inline fn draw(self: *Self, vertex_count: usize, instance_count: usize, first_vertex: usize, first_instance: usize) VkError!void { try self.dispatch_table.draw(self, vertex_count, instance_count, first_vertex, first_instance); } diff --git a/src/vulkan/Queue.zig b/src/vulkan/Queue.zig index 0da0517..11621f0 100644 --- a/src/vulkan/Queue.zig +++ b/src/vulkan/Queue.zig @@ -34,23 +34,43 @@ pub const DispatchTable = struct { }; pub const SubmitInfo = struct { + wait_semaphores: std.ArrayList(*BinarySemaphore), command_buffers: std.ArrayList(*CommandBuffer), + signal_semaphores: std.ArrayList(*BinarySemaphore), // TODO: complete fn initBlob(allocator: std.mem.Allocator, infos: []const vk.SubmitInfo) VkError!std.ArrayList(SubmitInfo) { var self = std.ArrayList(SubmitInfo).initCapacity(allocator, infos.len) catch return VkError.OutOfHostMemory; - errdefer self.deinit(allocator); + errdefer deinitBlob(allocator, &self); loop: for (infos) |info| { - if (info.command_buffer_count == 0) continue :loop; - if (info.p_command_buffers == null) continue :loop; + if (info.wait_semaphore_count == 0 and info.command_buffer_count == 0 and info.signal_semaphore_count == 0) continue :loop; var submit_info: SubmitInfo = .{ + .wait_semaphores = std.ArrayList(*BinarySemaphore).initCapacity(allocator, info.wait_semaphore_count) catch return VkError.OutOfHostMemory, .command_buffers = std.ArrayList(*CommandBuffer).initCapacity(allocator, info.command_buffer_count) catch return VkError.OutOfHostMemory, + .signal_semaphores = std.ArrayList(*BinarySemaphore).initCapacity(allocator, info.signal_semaphore_count) catch return VkError.OutOfHostMemory, }; + errdefer submit_info.wait_semaphores.deinit(allocator); + errdefer submit_info.command_buffers.deinit(allocator); + errdefer submit_info.signal_semaphores.deinit(allocator); - for (info.p_command_buffers.?[0..info.command_buffer_count]) |vk_command_buffer| { - submit_info.command_buffers.append(allocator, try Dispatchable(CommandBuffer).fromHandleObject(vk_command_buffer)) catch return VkError.OutOfHostMemory; + if (info.p_wait_semaphores) |p_wait_semaphores| { + for (p_wait_semaphores[0..info.wait_semaphore_count]) |p_semaphore| { + submit_info.wait_semaphores.append(allocator, try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore)) catch return VkError.OutOfHostMemory; + } + } + + if (info.p_command_buffers) |p_command_buffers| { + for (p_command_buffers[0..info.command_buffer_count]) |vk_command_buffer| { + submit_info.command_buffers.append(allocator, try Dispatchable(CommandBuffer).fromHandleObject(vk_command_buffer)) catch return VkError.OutOfHostMemory; + } + } + + if (info.p_signal_semaphores) |p_signal_semaphores| { + for (p_signal_semaphores[0..info.signal_semaphore_count]) |p_semaphore| { + submit_info.signal_semaphores.append(allocator, try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore)) catch return VkError.OutOfHostMemory; + } } self.append(allocator, submit_info) catch return VkError.OutOfHostMemory; @@ -60,7 +80,9 @@ pub const SubmitInfo = struct { fn deinitBlob(allocator: std.mem.Allocator, self: *std.ArrayList(SubmitInfo)) void { for (self.items) |*submit_info| { + submit_info.wait_semaphores.deinit(allocator); submit_info.command_buffers.deinit(allocator); + submit_info.signal_semaphores.deinit(allocator); } self.deinit(allocator); } @@ -95,15 +117,21 @@ pub fn submit(self: *Self, infos: []const vk.SubmitInfo, p_fence: ?*Fence) VkErr var submit_infos = try SubmitInfo.initBlob(allocator, infos); defer SubmitInfo.deinitBlob(allocator, &submit_infos); + if (submit_infos.items.len == 0) { + if (p_fence) |fence| { + try fence.signal(); + } + return; + } + try self.dispatch_table.submit(self, submit_infos.items, p_fence); } pub fn presentKHR(_: *Self, info: *const vk.PresentInfoKHR) VkError!void { if (info.p_wait_semaphores) |p_wait_semaphores| { - for (p_wait_semaphores[0..], 0..info.wait_semaphore_count) |p_semaphore, _| { + for (p_wait_semaphores[0..info.wait_semaphore_count]) |p_semaphore| { const semaphore = try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore); - // TODO: handle semaphores - _ = semaphore; + try semaphore.wait(); } } diff --git a/src/vulkan/lib.zig b/src/vulkan/lib.zig index 12bee5f..384188a 100644 --- a/src/vulkan/lib.zig +++ b/src/vulkan/lib.zig @@ -52,7 +52,7 @@ pub const ShaderModule = @import("ShaderModule.zig"); pub const SurfaceKHR = @import("wsi/SurfaceKHR.zig"); pub const SwapchainKHR = @import("wsi/SwapchainKHR.zig"); -pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1; +pub const VULKAN_VENDOR_ID = 0x10008; /// Default driver name pub const DRIVER_NAME = "Unnamed Ape Driver"; @@ -60,10 +60,10 @@ pub const DRIVER_NAME = "Unnamed Ape Driver"; pub const VULKAN_VERSION = vk.makeApiVersion(0, 1, 0, 0); /// Maximum number of descriptor sets per pipeline -pub const VULKAN_MAX_DESCRIPTOR_SETS = 4; +pub const VULKAN_MAX_DESCRIPTOR_SETS = 8; /// The number of push constant ranges is effectively bounded -/// by the number of possible shader stages. Not the number of stages that can +/// 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 @@ -73,15 +73,7 @@ pub const VULKAN_MAX_DESCRIPTOR_SETS = 4; /// - 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 VULKAN_MAX_PUSH_CONSTANT_RANGES = 6; pub const std_options: std.Options = .{ .log_level = .debug, diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index d879dce..795134a 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -2069,15 +2069,9 @@ pub export fn apeCmdUpdateBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, o defer entryPointEndLogTrace(); const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err); - const buffer = Dispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err); - - notImplementedWarning(); - - _ = cmd; - _ = buffer; - _ = offset; - _ = size; - _ = data; + const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err); + const data_bytes: [*]const u8 = @ptrCast(data); + cmd.updateBuffer(buffer, offset, data_bytes[0..size]) catch |err| return errorLogger(err); } pub export fn apeCmdWaitEvents(