More wrappers, more cleanup
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
//! A thin wrapper around `@import("vk").CommandBufferProxy` that ziggifies
|
||||
//! arguments by turning pointer-length pairs into slices and integrates with
|
||||
//! different queues from `Engine` struct.
|
||||
//!
|
||||
//! The wrapper retains information about the queue type and whether its
|
||||
//! transient, such that it can submit to the correct queue preallocated in the
|
||||
//! `Engine` struct when calling `CommandBuffer.submit`.
|
||||
|
||||
const CommandBuffer = @This();
|
||||
const std = @import("std");
|
||||
|
||||
const vk = @import("vulkan");
|
||||
@@ -7,6 +16,42 @@ const QueueType = @import("QueueType.zig").QueueType;
|
||||
const Transient = @import("Transient.zig").Transient;
|
||||
const WaitSemaphore = @import("WaitSemaphore.zig");
|
||||
|
||||
proxy: vk.CommandBufferProxy,
|
||||
allocator: std.mem.Allocator,
|
||||
queue_type: QueueType,
|
||||
transient: Transient,
|
||||
|
||||
pub fn init(engine: *Engine, queue_type: QueueType, transient: Transient) !CommandBuffer {
|
||||
const handle = try engine.allocateCommandBuffer(.{
|
||||
.queue_type = queue_type,
|
||||
.transient = transient,
|
||||
.level = .primary,
|
||||
});
|
||||
const proxy: vk.CommandBufferProxy = .init(handle, engine.device.wrapper);
|
||||
const allocator = engine.vk_allocator.allocator;
|
||||
return .{
|
||||
.proxy = proxy,
|
||||
.allocator = allocator,
|
||||
.queue_type = queue_type,
|
||||
.transient = transient,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *CommandBuffer, engine: *Engine) void {
|
||||
engine.freeCommandBuffer(.{
|
||||
.queue_type = self.queue_type,
|
||||
.transient = self.transient,
|
||||
.command_buffer = self.proxy.handle,
|
||||
});
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn submit(self: CommandBuffer, engine: *Engine, submit_info: SubmitInfo) !void {
|
||||
try submitCommandBuffer(engine, self.queue_type, self.proxy.handle, submit_info);
|
||||
}
|
||||
|
||||
// --- VULKAN WRAPPERS ---------------------------------------------------------
|
||||
|
||||
pub const DrawIndexed = struct {
|
||||
index_count: u32,
|
||||
instance_count: u32 = 1,
|
||||
@@ -42,218 +87,152 @@ pub const VertexBufferBinding = struct {
|
||||
offset: usize,
|
||||
};
|
||||
|
||||
pub fn CommandBuffer(comptime queue_type: QueueType, comptime transient: Transient) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
proxy: vk.CommandBufferProxy,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub fn init(engine: *const Engine) !Self {
|
||||
const handle = try allocateCommandBuffer(engine, queue_type, transient);
|
||||
const proxy: vk.CommandBufferProxy = .init(handle, engine.device.wrapper);
|
||||
const allocator = engine.vk_allocator.allocator;
|
||||
return .{ .proxy = proxy, .allocator = allocator };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, engine: *const Engine) void {
|
||||
freeCommandBuffer(engine, queue_type, transient, self.proxy.handle);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn submit(self: Self, engine: *const Engine, submit_info: SubmitInfo) !void {
|
||||
try submitCommandBuffer(engine, queue_type, self.proxy.handle, submit_info);
|
||||
}
|
||||
|
||||
pub const CommandBufferBeginInfo = struct {
|
||||
flags: vk.CommandBufferUsageFlags = .{
|
||||
.one_time_submit_bit = switch (transient) {
|
||||
.persistent => false,
|
||||
.transient => true,
|
||||
},
|
||||
pub fn beginCommandBuffer(self: CommandBuffer) !void {
|
||||
try self.proxy.beginCommandBuffer(&.{
|
||||
.flags = .{
|
||||
.one_time_submit_bit = switch (self.transient) {
|
||||
.persistent => true,
|
||||
.transient => false,
|
||||
},
|
||||
inheritance_info: ?vk.CommandBufferInheritanceInfo = null,
|
||||
};
|
||||
|
||||
pub fn beginCommandBuffer(self: Self, begin_info: CommandBufferBeginInfo) !void {
|
||||
try self.proxy.beginCommandBuffer(&.{
|
||||
.flags = begin_info.flags,
|
||||
.p_inheritance_info = if (begin_info.inheritance_info) |*x| x else null,
|
||||
});
|
||||
}
|
||||
|
||||
pub inline fn beginRenderPass(self: Self, render_pass_begin: RenderPassBeginInfo, contents: vk.SubpassContents) void {
|
||||
self.proxy.beginRenderPass(&.{
|
||||
.render_pass = render_pass_begin.render_pass,
|
||||
.framebuffer = render_pass_begin.framebuffer,
|
||||
.render_area = render_pass_begin.render_area,
|
||||
.clear_value_count = @intCast(render_pass_begin.clear_values.len),
|
||||
.p_clear_values = render_pass_begin.clear_values.ptr,
|
||||
}, contents);
|
||||
}
|
||||
|
||||
pub inline fn bindDescriptorSet(
|
||||
self: Self,
|
||||
pipeline_bind_point: vk.PipelineBindPoint,
|
||||
layout: vk.PipelineLayout,
|
||||
set: u32,
|
||||
descriptor_set: vk.DescriptorSet,
|
||||
dynamic_offset: ?u32,
|
||||
) void {
|
||||
self.bindDescriptorSets(
|
||||
pipeline_bind_point,
|
||||
layout,
|
||||
set,
|
||||
&.{descriptor_set},
|
||||
if (dynamic_offset) |x| &.{x} else &.{},
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn bindDescriptorSets(
|
||||
self: Self,
|
||||
pipeline_bind_point: vk.PipelineBindPoint,
|
||||
layout: vk.PipelineLayout,
|
||||
first_set: u32,
|
||||
descriptor_sets: []const vk.DescriptorSet,
|
||||
dynamic_offsets: []const u32,
|
||||
) void {
|
||||
self.proxy.bindDescriptorSets(
|
||||
pipeline_bind_point,
|
||||
layout,
|
||||
first_set,
|
||||
@intCast(descriptor_sets.len),
|
||||
descriptor_sets.ptr,
|
||||
@intCast(dynamic_offsets.len),
|
||||
dynamic_offsets.ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn bindPipeline(self: Self, pipeline_bind_point: vk.PipelineBindPoint, pipeline: vk.Pipeline) void {
|
||||
self.proxy.bindPipeline(pipeline_bind_point, pipeline);
|
||||
}
|
||||
|
||||
pub inline fn bindIndexBuffer(self: Self, buffer: vk.Buffer, offset: u64, index_type: vk.IndexType) void {
|
||||
self.proxy.bindIndexBuffer(buffer, offset, index_type);
|
||||
}
|
||||
|
||||
pub inline fn bindVertexBuffers(self: Self, first_binding: u32, bindings: []const VertexBufferBinding) !void {
|
||||
var vertex_buffer_bindings = std.MultiArrayList(VertexBufferBinding){};
|
||||
defer vertex_buffer_bindings.deinit(self.allocator);
|
||||
try vertex_buffer_bindings.ensureTotalCapacity(self.allocator, bindings.len);
|
||||
|
||||
for (bindings) |binding| {
|
||||
vertex_buffer_bindings.appendAssumeCapacity(binding);
|
||||
}
|
||||
|
||||
self.proxy.bindVertexBuffers(
|
||||
first_binding,
|
||||
@intCast(vertex_buffer_bindings.len),
|
||||
vertex_buffer_bindings.items(.buffer).ptr,
|
||||
vertex_buffer_bindings.items(.offset).ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn drawIndexed(self: Self, draw_indexed: DrawIndexed) void {
|
||||
self.proxy.drawIndexed(
|
||||
draw_indexed.index_count,
|
||||
draw_indexed.instance_count,
|
||||
draw_indexed.first_index,
|
||||
draw_indexed.vertex_offset,
|
||||
draw_indexed.first_instance,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn endCommandBuffer(self: Self) !void {
|
||||
try self.proxy.endCommandBuffer();
|
||||
}
|
||||
|
||||
pub inline fn endRenderPass(self: Self) void {
|
||||
self.proxy.endRenderPass();
|
||||
}
|
||||
|
||||
pub inline fn copyBuffer(
|
||||
self: Self,
|
||||
src_buffer: vk.Buffer,
|
||||
dst_buffer: vk.Buffer,
|
||||
regions: []const vk.BufferCopy,
|
||||
) void {
|
||||
self.proxy.copyBuffer(src_buffer, dst_buffer, @intCast(regions.len), regions.ptr);
|
||||
}
|
||||
|
||||
pub inline fn copyBufferToImage(
|
||||
self: Self,
|
||||
src_buffer: vk.Buffer,
|
||||
dst_image: vk.Image,
|
||||
dst_image_layout: vk.ImageLayout,
|
||||
regions: []const vk.BufferImageCopy,
|
||||
) void {
|
||||
self.proxy.copyBufferToImage(src_buffer, dst_image, dst_image_layout, @intCast(regions.len), regions.ptr);
|
||||
}
|
||||
|
||||
pub inline fn pipelineBarrier(self: Self, barrier: PipelineBarrier) void {
|
||||
self.proxy.pipelineBarrier(
|
||||
barrier.src_stage_mask,
|
||||
barrier.dst_stage_mask,
|
||||
barrier.dependency_flags,
|
||||
@intCast(barrier.memory_barriers.len),
|
||||
barrier.memory_barriers.ptr,
|
||||
@intCast(barrier.buffer_memory_barriers.len),
|
||||
barrier.buffer_memory_barriers.ptr,
|
||||
@intCast(barrier.image_memory_barriers.len),
|
||||
barrier.image_memory_barriers.ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn setScissor(self: Self, first_scissor: u32, scissors: []const vk.Rect2D) void {
|
||||
self.proxy.setScissor(first_scissor, @intCast(scissors.len), scissors.ptr);
|
||||
}
|
||||
|
||||
pub inline fn setViewport(self: Self, first_viewport: u32, viewports: []const vk.Viewport) void {
|
||||
self.proxy.setViewport(first_viewport, @intCast(viewports.len), viewports.ptr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline fn resolveCommandPool(self: *const Engine, comptime queue_type: QueueType, comptime transient: Transient) vk.CommandPool {
|
||||
return switch (queue_type) {
|
||||
.graphics => switch (transient) {
|
||||
.persistent => self.graphics_command_pool,
|
||||
.transient => self.transient_graphics_command_pool,
|
||||
},
|
||||
.compute => switch (transient) {
|
||||
.persistent => self.compute_command_pool,
|
||||
.transient => self.transient_compute_command_pool,
|
||||
},
|
||||
.transfer => switch (transient) {
|
||||
.persistent => self.transfer_command_pool,
|
||||
.transient => self.transient_transfer_command_pool,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
fn allocateCommandBuffer(engine: *const Engine, comptime queue_type: QueueType, comptime transient: Transient) !vk.CommandBuffer {
|
||||
const command_pool = resolveCommandPool(engine, queue_type, transient);
|
||||
|
||||
var command_buffers: [1]vk.CommandBuffer = undefined;
|
||||
try engine.device.allocateCommandBuffers(&.{
|
||||
.command_pool = command_pool,
|
||||
.level = .primary,
|
||||
.command_buffer_count = command_buffers.len,
|
||||
}, &command_buffers);
|
||||
|
||||
return command_buffers[0];
|
||||
pub fn beginRenderPass(self: CommandBuffer, render_pass_begin: RenderPassBeginInfo, contents: vk.SubpassContents) void {
|
||||
self.proxy.beginRenderPass(&.{
|
||||
.render_pass = render_pass_begin.render_pass,
|
||||
.framebuffer = render_pass_begin.framebuffer,
|
||||
.render_area = render_pass_begin.render_area,
|
||||
.clear_value_count = @intCast(render_pass_begin.clear_values.len),
|
||||
.p_clear_values = render_pass_begin.clear_values.ptr,
|
||||
}, contents);
|
||||
}
|
||||
|
||||
fn freeCommandBuffer(engine: *const Engine, comptime queue_type: QueueType, comptime transient: Transient, command_buffer: vk.CommandBuffer) void {
|
||||
const command_pool = resolveCommandPool(engine, queue_type, transient);
|
||||
const command_buffers = [_]vk.CommandBuffer{command_buffer};
|
||||
|
||||
engine.device.freeCommandBuffers(command_pool, command_buffers.len, &command_buffers);
|
||||
pub fn bindDescriptorSet(
|
||||
self: CommandBuffer,
|
||||
pipeline_bind_point: vk.PipelineBindPoint,
|
||||
layout: vk.PipelineLayout,
|
||||
set: u32,
|
||||
descriptor_set: vk.DescriptorSet,
|
||||
dynamic_offset: ?u32,
|
||||
) void {
|
||||
self.bindDescriptorSets(
|
||||
pipeline_bind_point,
|
||||
layout,
|
||||
set,
|
||||
&.{descriptor_set},
|
||||
if (dynamic_offset) |x| &.{x} else &.{},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn bindDescriptorSets(
|
||||
self: CommandBuffer,
|
||||
pipeline_bind_point: vk.PipelineBindPoint,
|
||||
layout: vk.PipelineLayout,
|
||||
first_set: u32,
|
||||
descriptor_sets: []const vk.DescriptorSet,
|
||||
dynamic_offsets: []const u32,
|
||||
) void {
|
||||
self.proxy.bindDescriptorSets(
|
||||
pipeline_bind_point,
|
||||
layout,
|
||||
first_set,
|
||||
@intCast(descriptor_sets.len),
|
||||
descriptor_sets.ptr,
|
||||
@intCast(dynamic_offsets.len),
|
||||
dynamic_offsets.ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn bindPipeline(self: CommandBuffer, pipeline_bind_point: vk.PipelineBindPoint, pipeline: vk.Pipeline) void {
|
||||
self.proxy.bindPipeline(pipeline_bind_point, pipeline);
|
||||
}
|
||||
|
||||
pub fn bindIndexBuffer(self: CommandBuffer, buffer: vk.Buffer, offset: u64, index_type: vk.IndexType) void {
|
||||
self.proxy.bindIndexBuffer(buffer, offset, index_type);
|
||||
}
|
||||
|
||||
pub fn bindVertexBuffers(self: CommandBuffer, first_binding: u32, bindings: []const VertexBufferBinding) !void {
|
||||
var vertex_buffer_bindings = std.MultiArrayList(VertexBufferBinding){};
|
||||
defer vertex_buffer_bindings.deinit(self.allocator);
|
||||
try vertex_buffer_bindings.ensureTotalCapacity(self.allocator, bindings.len);
|
||||
|
||||
for (bindings) |binding| {
|
||||
vertex_buffer_bindings.appendAssumeCapacity(binding);
|
||||
}
|
||||
|
||||
self.proxy.bindVertexBuffers(
|
||||
first_binding,
|
||||
@intCast(vertex_buffer_bindings.len),
|
||||
vertex_buffer_bindings.items(.buffer).ptr,
|
||||
vertex_buffer_bindings.items(.offset).ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn drawIndexed(self: CommandBuffer, draw_indexed: DrawIndexed) void {
|
||||
self.proxy.drawIndexed(
|
||||
draw_indexed.index_count,
|
||||
draw_indexed.instance_count,
|
||||
draw_indexed.first_index,
|
||||
draw_indexed.vertex_offset,
|
||||
draw_indexed.first_instance,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn endCommandBuffer(self: CommandBuffer) !void {
|
||||
try self.proxy.endCommandBuffer();
|
||||
}
|
||||
|
||||
pub fn endRenderPass(self: CommandBuffer) void {
|
||||
self.proxy.endRenderPass();
|
||||
}
|
||||
|
||||
pub fn copyBuffer(
|
||||
self: CommandBuffer,
|
||||
src_buffer: vk.Buffer,
|
||||
dst_buffer: vk.Buffer,
|
||||
regions: []const vk.BufferCopy,
|
||||
) void {
|
||||
self.proxy.copyBuffer(src_buffer, dst_buffer, @intCast(regions.len), regions.ptr);
|
||||
}
|
||||
|
||||
pub fn copyBufferToImage(
|
||||
self: CommandBuffer,
|
||||
src_buffer: vk.Buffer,
|
||||
dst_image: vk.Image,
|
||||
dst_image_layout: vk.ImageLayout,
|
||||
regions: []const vk.BufferImageCopy,
|
||||
) void {
|
||||
self.proxy.copyBufferToImage(src_buffer, dst_image, dst_image_layout, @intCast(regions.len), regions.ptr);
|
||||
}
|
||||
|
||||
pub fn pipelineBarrier(self: CommandBuffer, barrier: PipelineBarrier) void {
|
||||
self.proxy.pipelineBarrier(
|
||||
barrier.src_stage_mask,
|
||||
barrier.dst_stage_mask,
|
||||
barrier.dependency_flags,
|
||||
@intCast(barrier.memory_barriers.len),
|
||||
barrier.memory_barriers.ptr,
|
||||
@intCast(barrier.buffer_memory_barriers.len),
|
||||
barrier.buffer_memory_barriers.ptr,
|
||||
@intCast(barrier.image_memory_barriers.len),
|
||||
barrier.image_memory_barriers.ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn setScissor(self: CommandBuffer, first_scissor: u32, scissors: []const vk.Rect2D) void {
|
||||
self.proxy.setScissor(first_scissor, @intCast(scissors.len), scissors.ptr);
|
||||
}
|
||||
|
||||
pub fn setViewport(self: CommandBuffer, first_viewport: u32, viewports: []const vk.Viewport) void {
|
||||
self.proxy.setViewport(first_viewport, @intCast(viewports.len), viewports.ptr);
|
||||
}
|
||||
|
||||
// --- HELPER FUNCTIONS --------------------------------------------------------
|
||||
|
||||
fn submitCommandBuffer(
|
||||
engine: *const Engine,
|
||||
comptime queue_type: QueueType,
|
||||
engine: *Engine,
|
||||
queue_type: QueueType,
|
||||
command_buffer: vk.CommandBuffer,
|
||||
submit_info: SubmitInfo,
|
||||
) !void {
|
||||
|
||||
@@ -7,6 +7,7 @@ const vk = @import("vulkan");
|
||||
|
||||
const Queue = @import("Queue.zig");
|
||||
const QueueType = @import("QueueType.zig").QueueType;
|
||||
const Transient = @import("Transient.zig").Transient;
|
||||
const VkAllocator = @import("VkAllocator.zig");
|
||||
|
||||
pub const Mode = union(enum) {
|
||||
@@ -347,10 +348,34 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
||||
}, &vk_allocator.interface);
|
||||
errdefer device.destroyCommandPool(transient_transfer_command_pool, &vk_allocator.interface);
|
||||
|
||||
const graphics_queue: Queue = .initAllocation(device, queue_allocations.graphics_queue);
|
||||
const compute_queue: Queue = .initAllocation(device, queue_allocations.compute_queue);
|
||||
const transfer_queue: Queue = .initAllocation(device, queue_allocations.transfer_queue);
|
||||
const presentation_queue: Queue = if (maybe_window != null) .initAllocation(device, queue_allocations.presentation_queue) else undefined;
|
||||
const graphics_queue: Queue = .init(
|
||||
device.getDeviceQueue(
|
||||
queue_allocations.graphics_queue.family,
|
||||
queue_allocations.graphics_queue.index,
|
||||
),
|
||||
queue_allocations.graphics_queue,
|
||||
);
|
||||
const compute_queue: Queue = .init(
|
||||
device.getDeviceQueue(
|
||||
queue_allocations.compute_queue.family,
|
||||
queue_allocations.compute_queue.index,
|
||||
),
|
||||
queue_allocations.compute_queue,
|
||||
);
|
||||
const transfer_queue: Queue = .init(
|
||||
device.getDeviceQueue(
|
||||
queue_allocations.transfer_queue.family,
|
||||
queue_allocations.transfer_queue.index,
|
||||
),
|
||||
queue_allocations.transfer_queue,
|
||||
);
|
||||
const presentation_queue: Queue = if (maybe_window != null) .init(
|
||||
device.getDeviceQueue(
|
||||
queue_allocations.presentation_queue.family,
|
||||
queue_allocations.presentation_queue.index,
|
||||
),
|
||||
queue_allocations.presentation_queue,
|
||||
) else undefined;
|
||||
|
||||
// --- CREATE AND SEED RNG -------------------------------------------------
|
||||
|
||||
@@ -613,6 +638,23 @@ fn findPresentationQueueFamily(queue_families_properties: []const vk.QueueFamily
|
||||
return null;
|
||||
}
|
||||
|
||||
fn resolveCommandPool(self: *const Engine, queue_type: QueueType, transient: Transient) vk.CommandPool {
|
||||
return switch (queue_type) {
|
||||
.graphics => switch (transient) {
|
||||
.persistent => self.graphics_command_pool,
|
||||
.transient => self.transient_graphics_command_pool,
|
||||
},
|
||||
.compute => switch (transient) {
|
||||
.persistent => self.compute_command_pool,
|
||||
.transient => self.transient_compute_command_pool,
|
||||
},
|
||||
.transfer => switch (transient) {
|
||||
.persistent => self.transfer_command_pool,
|
||||
.transient => self.transient_transfer_command_pool,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// --- VULKAN WRAPPERS ---------------------------------------------------------
|
||||
|
||||
pub const BufferCreateInfo = struct {
|
||||
@@ -622,6 +664,18 @@ pub const BufferCreateInfo = struct {
|
||||
queue_family_indices: []const u32 = &.{},
|
||||
};
|
||||
|
||||
pub const CommandBufferAllocateInfo = struct {
|
||||
queue_type: QueueType,
|
||||
transient: Transient,
|
||||
level: vk.CommandBufferLevel,
|
||||
};
|
||||
|
||||
pub const CommandBufferFreeInfo = struct {
|
||||
queue_type: QueueType,
|
||||
transient: Transient,
|
||||
command_buffer: vk.CommandBuffer,
|
||||
};
|
||||
|
||||
pub const DescriptorPoolCreateInfo = struct {
|
||||
flags: vk.DescriptorPoolCreateFlags = .{},
|
||||
max_sets: u32,
|
||||
@@ -798,6 +852,17 @@ pub fn createBuffer(self: *Engine, create_info: BufferCreateInfo) !vk.Buffer {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
pub fn allocateCommandBuffer(self: *Engine, allocate_info: CommandBufferAllocateInfo) !vk.CommandBuffer {
|
||||
const command_pool = self.resolveCommandPool(allocate_info.queue_type, allocate_info.transient);
|
||||
var command_buffers: [1]vk.CommandBuffer = undefined;
|
||||
try self.device.allocateCommandBuffers(&.{
|
||||
.command_pool = command_pool,
|
||||
.level = allocate_info.level,
|
||||
.command_buffer_count = command_buffers.len,
|
||||
}, &command_buffers);
|
||||
return command_buffers[0];
|
||||
}
|
||||
|
||||
pub fn allocateDescriptorSet(self: *Engine, allocate_info: DescriptorSetAllocateInfo) !vk.DescriptorSet {
|
||||
var descriptor_sets: [1]vk.DescriptorSet = undefined;
|
||||
try self.allocateDescriptorSets(.{
|
||||
@@ -831,6 +896,14 @@ pub fn allocateDescriptorSets(self: *Engine, allocate_info: DescriptorSetsAlloca
|
||||
}, descriptor_sets.ptr);
|
||||
}
|
||||
|
||||
pub fn bindBufferMemory(self: *Engine, buffer: vk.Buffer, memory: vk.DeviceMemory, memory_offset: vk.DeviceSize) !void {
|
||||
try self.device.bindBufferMemory(buffer, memory, memory_offset);
|
||||
}
|
||||
|
||||
pub fn bindImageMemory(self: *Engine, image: vk.Image, memory: vk.DeviceMemory, memory_offset: vk.DeviceSize) !void {
|
||||
try self.device.bindImageMemory(image, memory, memory_offset);
|
||||
}
|
||||
|
||||
pub fn createDescriptorSetLayout(self: *Engine, create_info: DescriptorSetLayoutCreateInfo) !vk.DescriptorSetLayout {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
@@ -1106,6 +1179,16 @@ pub fn destroyShaderModule(self: *Engine, shader_module: vk.ShaderModule) void {
|
||||
self.device.destroyShaderModule(shader_module, &self.vk_allocator.interface);
|
||||
}
|
||||
|
||||
pub fn deviceWaitIdle(self: *Engine) !void {
|
||||
try self.device.deviceWaitIdle();
|
||||
}
|
||||
|
||||
pub fn freeCommandBuffer(self: *Engine, free_info: CommandBufferFreeInfo) void {
|
||||
const command_pool = self.resolveCommandPool(free_info.queue_type, free_info.transient);
|
||||
const command_buffers = [_]vk.CommandBuffer{free_info.command_buffer};
|
||||
self.device.freeCommandBuffers(command_pool, command_buffers.len, &command_buffers);
|
||||
}
|
||||
|
||||
pub fn freeDescriptorSet(self: *Engine, descriptor_pool: vk.DescriptorPool, descriptor_set: vk.DescriptorSet) void {
|
||||
const descriptor_sets = [_]vk.DescriptorSet{descriptor_set};
|
||||
self.device.freeDescriptorSets(descriptor_pool, descriptor_sets.len, &descriptor_sets) catch unreachable;
|
||||
@@ -1115,10 +1198,27 @@ pub fn freeMemory(self: *Engine, device_memory: vk.DeviceMemory) void {
|
||||
self.device.freeMemory(device_memory, &self.vk_allocator.interface);
|
||||
}
|
||||
|
||||
pub fn getBufferMemoryRequirements(self: *Engine, buffer: vk.Buffer) vk.MemoryRequirements {
|
||||
return self.device.getBufferMemoryRequirements(buffer);
|
||||
}
|
||||
|
||||
pub fn getImageMemoryRequirements(self: *Engine, image: vk.Image) vk.MemoryRequirements {
|
||||
return self.device.getImageMemoryRequirements(image);
|
||||
}
|
||||
|
||||
pub fn mapMemory(self: *Engine, memory: vk.DeviceMemory, offset: vk.DeviceSize, size: vk.DeviceSize, flags: vk.MemoryMapFlags) ![]u8 {
|
||||
const mapped_memory = try self.device.mapMemory(memory, offset, size, flags);
|
||||
return @as([*]u8, @ptrCast(mapped_memory))[0..size];
|
||||
}
|
||||
|
||||
pub fn resetFence(self: *Engine, fence: vk.Fence) !void {
|
||||
try self.device.resetFences(1, @ptrCast(&fence));
|
||||
}
|
||||
|
||||
pub fn unmapMemory(self: *Engine, memory: vk.DeviceMemory) void {
|
||||
self.device.unmapMemory(memory);
|
||||
}
|
||||
|
||||
pub fn updateDescriptorSets(self: *Engine, update_info: DescriptorSetsUpdateInfo) !void {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
@@ -2,7 +2,7 @@ const std = @import("std");
|
||||
|
||||
const vk = @import("vulkan");
|
||||
|
||||
const CommandBuffer = @import("CommandBuffer.zig").CommandBuffer;
|
||||
const CommandBuffer = @import("CommandBuffer.zig");
|
||||
const Engine = @import("Engine.zig");
|
||||
const StagingBuffer = @import("StagingBuffer.zig");
|
||||
const TargetQueue = @import("TargetQueue.zig").TargetQueue;
|
||||
@@ -71,14 +71,14 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
|
||||
engine.setObjectName(buffer, "B {s} [{s}, {s}]", .{ name, @typeName(Header), @typeName(Element) });
|
||||
}
|
||||
|
||||
const memory_requirements = engine.device.getBufferMemoryRequirements(buffer);
|
||||
const memory_requirements = engine.getBufferMemoryRequirements(buffer);
|
||||
const device_memory = try engine.allocate(memory_requirements, .{ .device_local_bit = true });
|
||||
errdefer engine.freeMemory(device_memory);
|
||||
if (init_info.name) |name| {
|
||||
engine.setObjectName(device_memory, "DM {s} [{s}, {s}]", .{ name, @typeName(Header), @typeName(Element) });
|
||||
}
|
||||
|
||||
try engine.device.bindBufferMemory(buffer, device_memory, 0);
|
||||
try engine.bindBufferMemory(buffer, device_memory, 0);
|
||||
|
||||
return .{
|
||||
.buffer = buffer,
|
||||
@@ -154,10 +154,10 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
|
||||
@memcpy(staging_memory[array_write_offset..write_size], std.mem.sliceAsBytes(write_info.elements));
|
||||
staging_buffer.unmap(engine);
|
||||
|
||||
var command_buffer: CommandBuffer(.transfer, .transient) = try .init(engine);
|
||||
var command_buffer: CommandBuffer = try .init(engine, .transfer, .transient);
|
||||
defer command_buffer.deinit(engine);
|
||||
|
||||
try command_buffer.beginCommandBuffer(.{});
|
||||
try command_buffer.beginCommandBuffer();
|
||||
command_buffer.copyBuffer(staging_buffer.buffer, self.buffer, regions.items);
|
||||
try command_buffer.endCommandBuffer();
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ pub const Allocation = struct {
|
||||
handle: vk.Queue,
|
||||
allocation: Allocation,
|
||||
|
||||
pub fn initAllocation(device: vk.DeviceProxy, allocation: Allocation) Queue {
|
||||
pub fn init(handle: vk.Queue, allocation: Allocation) Queue {
|
||||
return .{
|
||||
.handle = device.getDeviceQueue(allocation.family, allocation.index),
|
||||
.handle = handle,
|
||||
.allocation = allocation,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ pub fn init(engine: *Engine, init_info: InitInfo) !StagingBuffer {
|
||||
});
|
||||
errdefer engine.destroyBuffer(buffer);
|
||||
|
||||
const memory_requirements = engine.device.getBufferMemoryRequirements(buffer);
|
||||
const memory_requirements = engine.getBufferMemoryRequirements(buffer);
|
||||
const device_memory = try engine.allocate(
|
||||
memory_requirements,
|
||||
.{
|
||||
@@ -41,7 +41,7 @@ pub fn init(engine: *Engine, init_info: InitInfo) !StagingBuffer {
|
||||
);
|
||||
errdefer engine.freeMemory(device_memory);
|
||||
|
||||
try engine.device.bindBufferMemory(buffer, device_memory, 0);
|
||||
try engine.bindBufferMemory(buffer, device_memory, 0);
|
||||
|
||||
return .{
|
||||
.buffer = buffer,
|
||||
@@ -65,10 +65,10 @@ pub fn map(self: StagingBuffer, engine: *Engine) ![]u8 {
|
||||
}
|
||||
|
||||
pub fn mapPartial(self: StagingBuffer, engine: *Engine, offset: u32, len: u32) ![]u8 {
|
||||
const mapped_memory = try engine.device.mapMemory(self.device_memory, offset, len, .{});
|
||||
return @as([*]u8, @ptrCast(mapped_memory))[0..len];
|
||||
const mapped_memory = try engine.mapMemory(self.device_memory, offset, len, .{});
|
||||
return mapped_memory;
|
||||
}
|
||||
|
||||
pub fn unmap(self: StagingBuffer, engine: *Engine) void {
|
||||
engine.device.unmapMemory(self.device_memory);
|
||||
engine.unmapMemory(self.device_memory);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ const std = @import("std");
|
||||
|
||||
const vk = @import("vulkan");
|
||||
|
||||
const CommandBuffer = @import("CommandBuffer.zig").CommandBuffer;
|
||||
const CommandBuffer = @import("CommandBuffer.zig");
|
||||
const Engine = @import("Engine.zig");
|
||||
const QSM = @import("QueueSharingMode.zig");
|
||||
const Texture = @import("Texture.zig");
|
||||
@@ -271,7 +271,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
}
|
||||
|
||||
pub const PresentInfo = struct {
|
||||
command_buffer: CommandBuffer(.graphics, .transient),
|
||||
command_buffer: CommandBuffer,
|
||||
wait_semaphores: []const WaitSemaphore = &.{},
|
||||
};
|
||||
|
||||
@@ -411,7 +411,7 @@ const SwapchainImage = struct {
|
||||
semaphore_render_finished: vk.Semaphore,
|
||||
fence: vk.Fence,
|
||||
framebuffer: vk.Framebuffer,
|
||||
command_buffer: ?CommandBuffer(.graphics, .transient),
|
||||
command_buffer: ?CommandBuffer,
|
||||
|
||||
const InitProps = struct {
|
||||
image: vk.Image,
|
||||
|
||||
@@ -3,7 +3,7 @@ const std = @import("std");
|
||||
|
||||
const vk = @import("vulkan");
|
||||
|
||||
const CommandBuffer = @import("CommandBuffer.zig").CommandBuffer;
|
||||
const CommandBuffer = @import("CommandBuffer.zig");
|
||||
const Engine = @import("Engine.zig");
|
||||
const StagingBuffer = @import("StagingBuffer.zig");
|
||||
const TargetQueue = @import("TargetQueue.zig").TargetQueue;
|
||||
@@ -116,14 +116,14 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture {
|
||||
engine.setObjectName(image, "I {s} [{s}]", .{ name, @tagName(init_info.usage) });
|
||||
}
|
||||
|
||||
const memory_requirements = engine.device.getImageMemoryRequirements(image);
|
||||
const memory_requirements = engine.getImageMemoryRequirements(image);
|
||||
const device_memory = try engine.allocate(memory_requirements, .{ .device_local_bit = true });
|
||||
errdefer engine.freeMemory(device_memory);
|
||||
if (init_info.name) |name| {
|
||||
engine.setObjectName(device_memory, "DM {s} [{s}]", .{ name, @tagName(init_info.usage) });
|
||||
}
|
||||
|
||||
try engine.device.bindImageMemory(image, device_memory, 0);
|
||||
try engine.bindImageMemory(image, device_memory, 0);
|
||||
|
||||
const image_view = try engine.createImageView(.{
|
||||
.image = image,
|
||||
@@ -205,10 +205,10 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
|
||||
|
||||
// --- TRANSITION TO TRANSFER_DST_OPTIMAL AND COPY -----------------
|
||||
|
||||
var transfer_command_buffer: CommandBuffer(.transfer, .transient) = try .init(engine);
|
||||
var transfer_command_buffer: CommandBuffer = try .init(engine, .transfer, .transient);
|
||||
defer transfer_command_buffer.deinit(engine);
|
||||
|
||||
try transfer_command_buffer.beginCommandBuffer(.{});
|
||||
try transfer_command_buffer.beginCommandBuffer();
|
||||
|
||||
transfer_command_buffer.pipelineBarrier(.{
|
||||
.src_stage_mask = .{ .top_of_pipe_bit = true },
|
||||
@@ -265,10 +265,10 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
|
||||
|
||||
// --- TRANSITION TO SHADER_READ_ONLY_OPTIMAL ----------------------
|
||||
|
||||
var graphics_command_buffer: CommandBuffer(.graphics, .transient) = try .init(engine);
|
||||
var graphics_command_buffer: CommandBuffer = try .init(engine, .graphics, .transient);
|
||||
defer graphics_command_buffer.deinit(engine);
|
||||
|
||||
try graphics_command_buffer.beginCommandBuffer(.{});
|
||||
try graphics_command_buffer.beginCommandBuffer();
|
||||
|
||||
graphics_command_buffer.pipelineBarrier(.{
|
||||
.src_stage_mask = .{ .transfer_bit = true },
|
||||
|
||||
Reference in New Issue
Block a user