adding secondary command buffers
This commit is contained in:
@@ -49,6 +49,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.dispatch = dispatch,
|
.dispatch = dispatch,
|
||||||
.dispatchIndirect = dispatchIndirect,
|
.dispatchIndirect = dispatchIndirect,
|
||||||
.end = end,
|
.end = end,
|
||||||
|
.executeCommands = executeCommands,
|
||||||
.fillBuffer = fillBuffer,
|
.fillBuffer = fillBuffer,
|
||||||
.pipelineBarrier = pipelineBarrier,
|
.pipelineBarrier = pipelineBarrier,
|
||||||
.reset = reset,
|
.reset = reset,
|
||||||
@@ -69,6 +70,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
allocator.destroy(self);
|
allocator.destroy(self);
|
||||||
|
_ = self.command_allocator.reset(.free_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(self: *Self, device: *ExecutionDevice) void {
|
pub fn execute(self: *Self, device: *ExecutionDevice) void {
|
||||||
@@ -98,8 +100,7 @@ pub fn end(interface: *Interface) VkError!void {
|
|||||||
|
|
||||||
pub fn reset(interface: *Interface, _: vk.CommandBufferResetFlags) VkError!void {
|
pub fn reset(interface: *Interface, _: vk.CommandBufferResetFlags) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
const allocator = self.command_allocator.allocator();
|
self.commands.clearAndFree(self.command_allocator.allocator());
|
||||||
self.commands.clearAndFree(allocator);
|
|
||||||
_ = self.command_allocator.reset(.free_all);
|
_ = self.command_allocator.reset(.free_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,9 +346,6 @@ pub fn dispatchIndirect(interface: *Interface, buffer: *base.Buffer, offset: vk.
|
|||||||
const size = 3 * @sizeOf(u32);
|
const size = 3 * @sizeOf(u32);
|
||||||
const memory = if (impl.buffer.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
const memory = if (impl.buffer.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
||||||
const map: []u32 = @as([*]u32, @ptrCast(@alignCast(try memory.map(impl.offset, size))))[0..3];
|
const map: []u32 = @as([*]u32, @ptrCast(@alignCast(try memory.map(impl.offset, size))))[0..3];
|
||||||
|
|
||||||
std.debug.print("{any}\n", .{map});
|
|
||||||
|
|
||||||
try device.compute_routines.dispatch(map[0], map[1], map[2]);
|
try device.compute_routines.dispatch(map[0], map[1], map[2]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -361,6 +359,28 @@ pub fn dispatchIndirect(interface: *Interface, buffer: *base.Buffer, offset: vk.
|
|||||||
self.commands.append(allocator, Command.from(cmd)) catch return VkError.OutOfHostMemory;
|
self.commands.append(allocator, Command.from(cmd)) catch return VkError.OutOfHostMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn executeCommands(interface: *Interface, commands: *Interface) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|
||||||
|
const CommandImpl = struct {
|
||||||
|
const Impl = @This();
|
||||||
|
|
||||||
|
cmd: *Self,
|
||||||
|
|
||||||
|
pub fn execute(impl: *const Impl, device: *ExecutionDevice) VkError!void {
|
||||||
|
impl.cmd.execute(device);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(cmd);
|
||||||
|
cmd.* = .{
|
||||||
|
.cmd = @alignCast(@fieldParentPtr("interface", commands)),
|
||||||
|
};
|
||||||
|
self.commands.append(allocator, Command.from(cmd)) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
const allocator = self.command_allocator.allocator();
|
const allocator = self.command_allocator.allocator();
|
||||||
@@ -397,7 +417,7 @@ pub fn pipelineBarrier(interface: *Interface, src_stage: vk.PipelineStageFlags,
|
|||||||
const Impl = @This();
|
const Impl = @This();
|
||||||
|
|
||||||
pub fn execute(_: *const Impl, _: *ExecutionDevice) VkError!void {
|
pub fn execute(_: *const Impl, _: *ExecutionDevice) VkError!void {
|
||||||
// TODO: implement synchronization for rasterizations stages
|
// TODO: implement synchronization for rasterization stages
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ pub const DispatchTable = struct {
|
|||||||
dispatch: *const fn (*Self, u32, u32, u32) VkError!void,
|
dispatch: *const fn (*Self, u32, u32, u32) VkError!void,
|
||||||
dispatchIndirect: *const fn (*Self, *Buffer, vk.DeviceSize) VkError!void,
|
dispatchIndirect: *const fn (*Self, *Buffer, vk.DeviceSize) VkError!void,
|
||||||
end: *const fn (*Self) VkError!void,
|
end: *const fn (*Self) VkError!void,
|
||||||
|
executeCommands: *const fn (*Self, *Self) VkError!void,
|
||||||
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
|
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
|
||||||
pipelineBarrier: *const fn (*Self, vk.PipelineStageFlags, vk.PipelineStageFlags, vk.DependencyFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
|
pipelineBarrier: *const fn (*Self, vk.PipelineStageFlags, vk.PipelineStageFlags, vk.DependencyFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
|
||||||
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
|
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
|
||||||
@@ -99,6 +100,7 @@ pub inline fn begin(self: *Self, info: *const vk.CommandBufferBeginInfo) VkError
|
|||||||
pub inline fn end(self: *Self) VkError!void {
|
pub inline fn end(self: *Self) VkError!void {
|
||||||
self.transitionState(.Executable, &.{.Recording}) catch return VkError.ValidationFailed;
|
self.transitionState(.Executable, &.{.Recording}) catch return VkError.ValidationFailed;
|
||||||
try self.dispatch_table.end(self);
|
try self.dispatch_table.end(self);
|
||||||
|
self.begin_info = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn reset(self: *Self, flags: vk.CommandBufferResetFlags) VkError!void {
|
pub inline fn reset(self: *Self, flags: vk.CommandBufferResetFlags) VkError!void {
|
||||||
@@ -133,6 +135,7 @@ pub inline fn finish(self: *Self) VkError!void {
|
|||||||
// Commands ====================================================================================================
|
// Commands ====================================================================================================
|
||||||
|
|
||||||
pub inline fn bindDescriptorSets(self: *Self, bind_point: vk.PipelineBindPoint, first_set: u32, sets: []const vk.DescriptorSet, dynamic_offsets: []const u32) VkError!void {
|
pub inline fn bindDescriptorSets(self: *Self, bind_point: vk.PipelineBindPoint, first_set: u32, sets: []const vk.DescriptorSet, dynamic_offsets: []const u32) VkError!void {
|
||||||
|
std.debug.assert(sets.len < lib.VULKAN_MAX_DESCRIPTOR_SETS);
|
||||||
var inner_sets = [_]?*DescriptorSet{null} ** lib.VULKAN_MAX_DESCRIPTOR_SETS;
|
var inner_sets = [_]?*DescriptorSet{null} ** lib.VULKAN_MAX_DESCRIPTOR_SETS;
|
||||||
for (sets, inner_sets[0..sets.len]) |set, *inner_set| {
|
for (sets, inner_sets[0..sets.len]) |set, *inner_set| {
|
||||||
inner_set.* = try NonDispatchable(DescriptorSet).fromHandleObject(set);
|
inner_set.* = try NonDispatchable(DescriptorSet).fromHandleObject(set);
|
||||||
@@ -174,6 +177,10 @@ pub inline fn dispatchIndirect(self: *Self, buffer: *Buffer, offset: vk.DeviceSi
|
|||||||
try self.dispatch_table.dispatchIndirect(self, buffer, offset);
|
try self.dispatch_table.dispatchIndirect(self, buffer, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn executeCommands(self: *Self, commands: *Self) VkError!void {
|
||||||
|
try self.dispatch_table.executeCommands(self, commands);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
||||||
try self.dispatch_table.fillBuffer(self, buffer, offset, size, data);
|
try self.dispatch_table.fillBuffer(self, buffer, offset, size, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,9 +72,8 @@ pub fn freeCommandBuffers(self: *Self, cmds: []*Dispatchable(CommandBuffer)) VkE
|
|||||||
// Ugly method but it works well
|
// Ugly method but it works well
|
||||||
var len: usize = 0;
|
var len: usize = 0;
|
||||||
for (cmds) |cmd| {
|
for (cmds) |cmd| {
|
||||||
if (std.mem.indexOf(*Dispatchable(CommandBuffer), self.buffers.items, &[_]*Dispatchable(CommandBuffer){cmd})) |i| {
|
if (std.mem.indexOfScalar(*Dispatchable(CommandBuffer), self.buffers.items, cmd)) |i| {
|
||||||
const save = self.buffers.orderedRemove(i);
|
const save = self.buffers.orderedRemove(i);
|
||||||
// Append the now free command buffer at the end of the pool
|
|
||||||
self.buffers.appendAssumeCapacity(save);
|
self.buffers.appendAssumeCapacity(save);
|
||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
@@ -82,8 +81,6 @@ pub fn freeCommandBuffers(self: *Self, cmds: []*Dispatchable(CommandBuffer)) VkE
|
|||||||
const new_first_free_buffer_index, const has_overflown = @subWithOverflow(self.first_free_buffer_index, len);
|
const new_first_free_buffer_index, const has_overflown = @subWithOverflow(self.first_free_buffer_index, len);
|
||||||
if (has_overflown == 0) {
|
if (has_overflown == 0) {
|
||||||
self.first_free_buffer_index = new_first_free_buffer_index;
|
self.first_free_buffer_index = new_first_free_buffer_index;
|
||||||
} else {
|
|
||||||
std.log.scoped(.CommandPool).warn("Avoided an underflow. This should not happen, please fill an issue.", .{});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,8 @@ pub const SubmitInfo = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deinitBlob(allocator: std.mem.Allocator, self: *std.ArrayList(SubmitInfo)) void {
|
fn deinitBlob(allocator: std.mem.Allocator, self: *std.ArrayList(SubmitInfo)) void {
|
||||||
for (self.items) |submit_info| {
|
for (self.items) |*submit_info| {
|
||||||
const command_buffers = &submit_info.command_buffers;
|
submit_info.command_buffers.deinit(allocator);
|
||||||
@constCast(command_buffers).deinit(allocator);
|
|
||||||
}
|
}
|
||||||
self.deinit(allocator);
|
self.deinit(allocator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ pub const VkError = error{
|
|||||||
IncompatibleShaderBinaryExt,
|
IncompatibleShaderBinaryExt,
|
||||||
PipelineBinaryMissingKhr,
|
PipelineBinaryMissingKhr,
|
||||||
NotEnoughSpaceKhr,
|
NotEnoughSpaceKhr,
|
||||||
// ====== Internal errors
|
// == Set of internal errors for better debugging. They map to VK_UNKNOWN_ERROR
|
||||||
InvalidHandleDrv,
|
InvalidHandleDrv,
|
||||||
InvalidPipelineDrv,
|
InvalidPipelineDrv,
|
||||||
InvalidDeviceMemoryDrv,
|
InvalidDeviceMemoryDrv,
|
||||||
|
|||||||
@@ -1957,12 +1957,10 @@ pub export fn strollCmdExecuteCommands(p_cmd: vk.CommandBuffer, count: u32, p_cm
|
|||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
for (p_cmds, 0..count) |p_sec_cmd, _| {
|
||||||
notImplementedWarning();
|
const sec_cmd = Dispatchable(CommandBuffer).fromHandleObject(p_sec_cmd) catch |err| return errorLogger(err);
|
||||||
|
cmd.executeCommands(sec_cmd) catch |err| return errorLogger(err);
|
||||||
_ = cmd;
|
}
|
||||||
_ = count;
|
|
||||||
_ = p_cmds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn strollCmdFillBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) callconv(vk.vulkan_call_conv) void {
|
pub export fn strollCmdFillBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
|
|||||||
Reference in New Issue
Block a user