Complete all Vulkan wrappers. Maybe worth it.
This commit is contained in:
@@ -9,6 +9,7 @@ const Queue = @import("Queue.zig");
|
||||
const QueueType = @import("QueueType.zig").QueueType;
|
||||
const Transient = @import("Transient.zig").Transient;
|
||||
const VkAllocator = @import("VkAllocator.zig");
|
||||
const WaitSemaphore = @import("WaitSemaphore.zig");
|
||||
|
||||
pub const Mode = union(enum) {
|
||||
headless: void,
|
||||
@@ -531,6 +532,69 @@ pub fn setObjectName(self: *const Engine, handle: anytype, comptime fmt: []const
|
||||
}
|
||||
}
|
||||
|
||||
pub const SubmitInfo = struct {
|
||||
wait_semaphores: []const WaitSemaphore = &.{},
|
||||
signal_semaphores: []const vk.Semaphore = &.{},
|
||||
fence: vk.Fence = .null_handle,
|
||||
};
|
||||
|
||||
pub fn queueSubmit(
|
||||
self: *const Engine,
|
||||
queue_type: QueueType,
|
||||
command_buffer: vk.CommandBuffer,
|
||||
submit_info: SubmitInfo,
|
||||
) !void {
|
||||
const queue = switch (queue_type) {
|
||||
.graphics => self.graphics_queue.handle,
|
||||
.compute => self.compute_queue.handle,
|
||||
.transfer => self.transfer_queue.handle,
|
||||
};
|
||||
|
||||
const command_buffers = [_]vk.CommandBuffer{command_buffer};
|
||||
|
||||
var wait_semaphores = std.MultiArrayList(WaitSemaphore){};
|
||||
defer wait_semaphores.deinit(self.vk_allocator.allocator);
|
||||
try wait_semaphores.ensureTotalCapacity(self.vk_allocator.allocator, submit_info.wait_semaphores.len);
|
||||
|
||||
for (submit_info.wait_semaphores) |wait_semaphore| {
|
||||
wait_semaphores.appendAssumeCapacity(wait_semaphore);
|
||||
}
|
||||
|
||||
const submits = [_]vk.SubmitInfo{
|
||||
.{
|
||||
.wait_semaphore_count = @intCast(wait_semaphores.len),
|
||||
.p_wait_semaphores = wait_semaphores.items(.semaphore).ptr,
|
||||
.p_wait_dst_stage_mask = wait_semaphores.items(.stage_flags).ptr,
|
||||
.command_buffer_count = command_buffers.len,
|
||||
.p_command_buffers = &command_buffers,
|
||||
.signal_semaphore_count = @intCast(submit_info.signal_semaphores.len),
|
||||
.p_signal_semaphores = submit_info.signal_semaphores.ptr,
|
||||
},
|
||||
};
|
||||
|
||||
try self.device.queueSubmit(queue, submits.len, &submits, submit_info.fence);
|
||||
}
|
||||
|
||||
pub const PresentInfo = struct {
|
||||
wait_semaphores: []const vk.Semaphore = &.{},
|
||||
image_index: u32,
|
||||
swapchain: vk.SwapchainKHR,
|
||||
};
|
||||
|
||||
pub fn queuePresent(self: *Engine, present_info: PresentInfo) !vk.Result {
|
||||
const swapchains = [_]vk.SwapchainKHR{present_info.swapchain};
|
||||
const image_indices = [_]u32{present_info.image_index};
|
||||
|
||||
const res = try self.device.queuePresentKHR(self.mode.surface.presentation_queue.handle, &.{
|
||||
.wait_semaphore_count = @intCast(present_info.wait_semaphores.len),
|
||||
.p_wait_semaphores = present_info.wait_semaphores.ptr,
|
||||
.swapchain_count = swapchains.len,
|
||||
.p_swapchains = &swapchains,
|
||||
.p_image_indices = &image_indices,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
fn debugUtilsMessengerCallback(
|
||||
severity: vk.DebugUtilsMessageSeverityFlagsEXT,
|
||||
message_type: vk.DebugUtilsMessageTypeFlagsEXT,
|
||||
@@ -657,6 +721,12 @@ fn resolveCommandPool(self: *const Engine, queue_type: QueueType, transient: Tra
|
||||
|
||||
// --- VULKAN WRAPPERS ---------------------------------------------------------
|
||||
|
||||
pub const AcquireInfo = struct {
|
||||
timeout: u64 = std.math.maxInt(u64),
|
||||
semaphore: vk.Semaphore = .null_handle,
|
||||
fence: vk.Fence = .null_handle,
|
||||
};
|
||||
|
||||
pub const BufferCreateInfo = struct {
|
||||
flags: vk.BufferCreateFlags = .{},
|
||||
size: vk.DeviceSize,
|
||||
@@ -807,6 +877,13 @@ pub const PipelineViewportStateCreateInfo = struct {
|
||||
scissors: []const vk.Rect2D = &.{},
|
||||
};
|
||||
|
||||
pub const RenderPassCreateInfo = struct {
|
||||
flags: vk.RenderPassCreateFlags = .{},
|
||||
attachments: []const vk.AttachmentDescription = &.{},
|
||||
subpasses: []const SubpassDescription,
|
||||
dependencies: []const vk.SubpassDependency = &.{},
|
||||
};
|
||||
|
||||
pub const ShaderModuleCreateInfo = struct {
|
||||
flags: vk.ShaderModuleCreateFlags = .{},
|
||||
code: []align(@alignOf(u32)) const u8,
|
||||
@@ -817,6 +894,33 @@ pub const SpecializationInfo = struct {
|
||||
data: []const u8 = &.{},
|
||||
};
|
||||
|
||||
pub const SubpassDescription = struct {
|
||||
flags: vk.SubpassDescriptionFlags = .{},
|
||||
pipeline_bind_point: vk.PipelineBindPoint,
|
||||
input_attachments: []const vk.AttachmentReference = &.{},
|
||||
color_attachments: []const vk.AttachmentReference = &.{},
|
||||
resolve_attachments: ?[]const vk.AttachmentReference = null,
|
||||
depth_stencil_attachment: ?vk.AttachmentReference = null,
|
||||
preserve_attachments: []const u32 = &.{},
|
||||
};
|
||||
|
||||
pub const SwapchainCreateInfo = struct {
|
||||
flags: vk.SwapchainCreateFlagsKHR = .{},
|
||||
surface: vk.SurfaceKHR,
|
||||
min_image_count: u32,
|
||||
image_format: vk.Format,
|
||||
image_color_space: vk.ColorSpaceKHR,
|
||||
image_extent: vk.Extent2D,
|
||||
image_array_layers: u32,
|
||||
image_usage: vk.ImageUsageFlags,
|
||||
queue_family_indices: []const u32 = &.{},
|
||||
pre_transform: vk.SurfaceTransformFlagsKHR,
|
||||
composite_alpha: vk.CompositeAlphaFlagsKHR,
|
||||
present_mode: vk.PresentModeKHR,
|
||||
clipped: vk.Bool32,
|
||||
old_swapchain: vk.SwapchainKHR = .null_handle,
|
||||
};
|
||||
|
||||
pub const WriteDescriptorSet = struct {
|
||||
dst_set: vk.DescriptorSet,
|
||||
dst_binding: u32,
|
||||
@@ -829,27 +933,14 @@ pub const WriteDescriptorSet = struct {
|
||||
},
|
||||
};
|
||||
|
||||
pub fn createBuffer(self: *Engine, create_info: BufferCreateInfo) !vk.Buffer {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var queue_family_indices_set: std.AutoArrayHashMapUnmanaged(u32, void) = .{};
|
||||
for (create_info.queue_family_indices) |queue_family_index| {
|
||||
try queue_family_indices_set.put(allocator, queue_family_index, {});
|
||||
}
|
||||
|
||||
const queue_family_indices = queue_family_indices_set.keys();
|
||||
|
||||
const buffer = self.device.createBuffer(&.{
|
||||
.flags = create_info.flags,
|
||||
.size = create_info.size,
|
||||
.usage = create_info.usage,
|
||||
.sharing_mode = if (queue_family_indices.len > 1) .concurrent else .exclusive,
|
||||
.queue_family_index_count = if (queue_family_indices.len > 1) @intCast(queue_family_indices.len) else 0,
|
||||
.p_queue_family_indices = if (queue_family_indices.len > 1) queue_family_indices.ptr else null,
|
||||
}, &self.vk_allocator.interface);
|
||||
return buffer;
|
||||
pub fn acquireNextImage(self: *Engine, swapchain: vk.SwapchainKHR, acquire_info: AcquireInfo) !vk.DeviceProxy.AcquireNextImageKHRResult {
|
||||
const res = try self.device.acquireNextImageKHR(
|
||||
swapchain,
|
||||
acquire_info.timeout,
|
||||
acquire_info.semaphore,
|
||||
acquire_info.fence,
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
pub fn allocateCommandBuffer(self: *Engine, allocate_info: CommandBufferAllocateInfo) !vk.CommandBuffer {
|
||||
@@ -904,6 +995,29 @@ pub fn bindImageMemory(self: *Engine, image: vk.Image, memory: vk.DeviceMemory,
|
||||
try self.device.bindImageMemory(image, memory, memory_offset);
|
||||
}
|
||||
|
||||
pub fn createBuffer(self: *Engine, create_info: BufferCreateInfo) !vk.Buffer {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var queue_family_indices_set: std.AutoArrayHashMapUnmanaged(u32, void) = .{};
|
||||
for (create_info.queue_family_indices) |queue_family_index| {
|
||||
try queue_family_indices_set.put(allocator, queue_family_index, {});
|
||||
}
|
||||
|
||||
const queue_family_indices = queue_family_indices_set.keys();
|
||||
|
||||
const buffer = self.device.createBuffer(&.{
|
||||
.flags = create_info.flags,
|
||||
.size = create_info.size,
|
||||
.usage = create_info.usage,
|
||||
.sharing_mode = if (queue_family_indices.len > 1) .concurrent else .exclusive,
|
||||
.queue_family_index_count = if (queue_family_indices.len > 1) @intCast(queue_family_indices.len) else 0,
|
||||
.p_queue_family_indices = if (queue_family_indices.len > 1) queue_family_indices.ptr else null,
|
||||
}, &self.vk_allocator.interface);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
pub fn createDescriptorSetLayout(self: *Engine, create_info: DescriptorSetLayoutCreateInfo) !vk.DescriptorSetLayout {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
@@ -986,7 +1100,7 @@ pub fn createGraphicsPipeline(self: *Engine, create_info: GraphicsPipelineCreate
|
||||
const allocator = arena.allocator();
|
||||
|
||||
const stages = try allocator.alloc(vk.PipelineShaderStageCreateInfo, create_info.stages.len);
|
||||
for (stages, create_info.stages) |*x, *stage| {
|
||||
for (stages, create_info.stages) |*x, stage| {
|
||||
x.* = .{
|
||||
.flags = stage.flags,
|
||||
.stage = stage.stage,
|
||||
@@ -1112,6 +1226,39 @@ pub fn createPipelineLayout(self: *Engine, create_info: PipelineLayoutCreateInfo
|
||||
return pipeline_layout;
|
||||
}
|
||||
|
||||
pub fn createRenderPass(self: *Engine, create_info: RenderPassCreateInfo) !vk.RenderPass {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
const subpasses = try allocator.alloc(vk.SubpassDescription, create_info.subpasses.len);
|
||||
for (subpasses, create_info.subpasses) |*x, *subpass| {
|
||||
x.* = .{
|
||||
.flags = subpass.flags,
|
||||
.pipeline_bind_point = subpass.pipeline_bind_point,
|
||||
.input_attachment_count = @intCast(subpass.input_attachments.len),
|
||||
.p_input_attachments = subpass.input_attachments.ptr,
|
||||
.color_attachment_count = @intCast(subpass.color_attachments.len),
|
||||
.p_color_attachments = subpass.color_attachments.ptr,
|
||||
.p_resolve_attachments = if (subpass.resolve_attachments) |resolve_attachments| resolve_attachments.ptr else null,
|
||||
.p_depth_stencil_attachment = if (subpass.depth_stencil_attachment) |*y| y else null,
|
||||
.preserve_attachment_count = @intCast(subpass.preserve_attachments.len),
|
||||
.p_preserve_attachments = subpass.preserve_attachments.ptr,
|
||||
};
|
||||
}
|
||||
|
||||
const render_pass = try self.device.createRenderPass(&.{
|
||||
.flags = create_info.flags,
|
||||
.attachment_count = @intCast(create_info.attachments.len),
|
||||
.p_attachments = create_info.attachments.ptr,
|
||||
.subpass_count = @intCast(subpasses.len),
|
||||
.p_subpasses = subpasses.ptr,
|
||||
.dependency_count = @intCast(create_info.dependencies.len),
|
||||
.p_dependencies = create_info.dependencies.ptr,
|
||||
}, &self.vk_allocator.interface);
|
||||
return render_pass;
|
||||
}
|
||||
|
||||
pub fn createSampler(self: *Engine, create_info: vk.SamplerCreateInfo) !vk.Sampler {
|
||||
const sampler = try self.device.createSampler(&create_info, &self.vk_allocator.interface);
|
||||
return sampler;
|
||||
@@ -1131,6 +1278,39 @@ pub fn createShaderModule(self: *Engine, create_info: ShaderModuleCreateInfo) !v
|
||||
return shader_module;
|
||||
}
|
||||
|
||||
pub fn createSwapchain(self: *Engine, create_info: SwapchainCreateInfo) !vk.SwapchainKHR {
|
||||
var arena: std.heap.ArenaAllocator = .init(self.vk_allocator.allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var queue_family_indices_set: std.AutoArrayHashMapUnmanaged(u32, void) = .{};
|
||||
for (create_info.queue_family_indices) |queue_family_index| {
|
||||
try queue_family_indices_set.put(allocator, queue_family_index, {});
|
||||
}
|
||||
|
||||
const queue_family_indices = queue_family_indices_set.keys();
|
||||
|
||||
const swapchain = try self.device.createSwapchainKHR(&.{
|
||||
.flags = create_info.flags,
|
||||
.surface = create_info.surface,
|
||||
.min_image_count = create_info.min_image_count,
|
||||
.image_format = create_info.image_format,
|
||||
.image_color_space = create_info.image_color_space,
|
||||
.image_extent = create_info.image_extent,
|
||||
.image_array_layers = create_info.image_array_layers,
|
||||
.image_usage = create_info.image_usage,
|
||||
.image_sharing_mode = if (queue_family_indices.len > 1) .concurrent else .exclusive,
|
||||
.queue_family_index_count = if (queue_family_indices.len > 1) @intCast(queue_family_indices.len) else 0,
|
||||
.p_queue_family_indices = if (queue_family_indices.len > 1) queue_family_indices.ptr else null,
|
||||
.pre_transform = create_info.pre_transform,
|
||||
.composite_alpha = create_info.composite_alpha,
|
||||
.present_mode = create_info.present_mode,
|
||||
.clipped = create_info.clipped,
|
||||
.old_swapchain = create_info.old_swapchain,
|
||||
}, &self.vk_allocator.interface);
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
pub fn destroyBuffer(self: *Engine, buffer: vk.Buffer) void {
|
||||
self.device.destroyBuffer(buffer, &self.vk_allocator.interface);
|
||||
}
|
||||
@@ -1167,6 +1347,10 @@ pub fn destroyPipelineLayout(self: *Engine, pipeline_layout: vk.PipelineLayout)
|
||||
self.device.destroyPipelineLayout(pipeline_layout, &self.vk_allocator.interface);
|
||||
}
|
||||
|
||||
pub fn destroyRenderPass(self: *Engine, render_pass: vk.RenderPass) void {
|
||||
self.device.destroyRenderPass(render_pass, &self.vk_allocator.interface);
|
||||
}
|
||||
|
||||
pub fn destroySampler(self: *Engine, sampler: vk.Sampler) void {
|
||||
self.device.destroySampler(sampler, &self.vk_allocator.interface);
|
||||
}
|
||||
@@ -1179,6 +1363,10 @@ pub fn destroyShaderModule(self: *Engine, shader_module: vk.ShaderModule) void {
|
||||
self.device.destroyShaderModule(shader_module, &self.vk_allocator.interface);
|
||||
}
|
||||
|
||||
pub fn destroySwapchain(self: *Engine, swapchain: vk.SwapchainKHR) void {
|
||||
self.device.destroySwapchainKHR(swapchain, &self.vk_allocator.interface);
|
||||
}
|
||||
|
||||
pub fn deviceWaitIdle(self: *Engine) !void {
|
||||
try self.device.deviceWaitIdle();
|
||||
}
|
||||
@@ -1206,6 +1394,21 @@ pub fn getImageMemoryRequirements(self: *Engine, image: vk.Image) vk.MemoryRequi
|
||||
return self.device.getImageMemoryRequirements(image);
|
||||
}
|
||||
|
||||
pub fn getPhysicalDeviceSurfaceCapabilities(self: *Engine) !vk.SurfaceCapabilitiesKHR {
|
||||
const surface_capabilities = try self.instance.getPhysicalDeviceSurfaceCapabilitiesKHR(self.physical_device, self.mode.surface.surface);
|
||||
return surface_capabilities;
|
||||
}
|
||||
|
||||
pub fn getPhysicalDeviceSurfaceFormatsAlloc(self: *Engine, allocator: std.mem.Allocator) ![]vk.SurfaceFormatKHR {
|
||||
const surface_formats = try self.instance.getPhysicalDeviceSurfaceFormatsAllocKHR(self.physical_device, self.mode.surface.surface, allocator);
|
||||
return surface_formats;
|
||||
}
|
||||
|
||||
pub fn getSwapchainImagesAlloc(self: *Engine, swapchain: vk.SwapchainKHR, allocator: std.mem.Allocator) ![]vk.Image {
|
||||
const images = try self.device.getSwapchainImagesAllocKHR(swapchain, allocator);
|
||||
return images;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
Reference in New Issue
Block a user