Create command buffers
This commit is contained in:
parent
f008f67921
commit
6a85e4ce51
1 changed files with 118 additions and 0 deletions
|
@ -29,6 +29,7 @@ const DeviceDispatch = vk.DeviceWrapper(apis);
|
|||
const Instance = vk.InstanceProxy(apis);
|
||||
const Device = vk.DeviceProxy(apis);
|
||||
const Queue = vk.QueueProxy(apis);
|
||||
const CommandBuffer = vk.CommandBufferProxy(apis);
|
||||
|
||||
pub const VulkanRenderer = struct {
|
||||
const Self = @This();
|
||||
|
@ -47,13 +48,19 @@ pub const VulkanRenderer = struct {
|
|||
presentation_queue: Queue,
|
||||
surface: vk.SurfaceKHR,
|
||||
swapchain: vk.SwapchainKHR,
|
||||
|
||||
swapchain_images: []SwapchainImage,
|
||||
swapchain_framebuffers: []vk.Framebuffer,
|
||||
command_buffers: []CommandBuffer,
|
||||
|
||||
// Pipeline
|
||||
graphics_pipeline: vk.Pipeline,
|
||||
pipeline_layout: vk.PipelineLayout,
|
||||
render_pass: vk.RenderPass,
|
||||
|
||||
// Pools
|
||||
graphics_command_pool: vk.CommandPool,
|
||||
|
||||
// Utilities
|
||||
swapchain_image_format: vk.Format,
|
||||
extent: vk.Extent2D,
|
||||
|
@ -79,6 +86,9 @@ pub const VulkanRenderer = struct {
|
|||
try self.createSwapchain();
|
||||
try self.createRenderPass();
|
||||
try self.createGraphicsPipeline();
|
||||
try self.createFramebuffers();
|
||||
try self.createCommandPool();
|
||||
try self.createCommandBuffers();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -487,6 +497,105 @@ pub const VulkanRenderer = struct {
|
|||
);
|
||||
}
|
||||
|
||||
fn createFramebuffers(self: *Self) !void {
|
||||
self.swapchain_framebuffers = try self.allocator.alloc(vk.Framebuffer, self.swapchain_images.len);
|
||||
|
||||
// Create a frammebuffer for each swapchain image
|
||||
for (self.swapchain_images, 0..) |swapchain_image, i| {
|
||||
const attachments = [_]vk.ImageView{swapchain_image.image_view};
|
||||
|
||||
const framebuffer_create_info: vk.FramebufferCreateInfo = .{
|
||||
.render_pass = self.render_pass, // Render pass layout the frambuffer will be used with
|
||||
.attachment_count = @intCast(attachments.len),
|
||||
.p_attachments = &attachments, // List of attachments (1:1 with render pass)
|
||||
.width = self.extent.width, // Framebuffer width
|
||||
.height = self.extent.height, // Framebuffer height
|
||||
.layers = 1, // Framebuffer layers
|
||||
};
|
||||
|
||||
self.swapchain_framebuffers[i] = try self.device.createFramebuffer(&framebuffer_create_info, null);
|
||||
}
|
||||
}
|
||||
|
||||
fn createCommandPool(self: *Self) !void {
|
||||
// Get indices of queue families from device
|
||||
const queue_family_indices = try self.getQueueFamilies(self.physical_device);
|
||||
|
||||
const pool_create_info: vk.CommandPoolCreateInfo = .{
|
||||
// Queue family type that buffers from this command pool will use
|
||||
.queue_family_index = queue_family_indices.graphics_family.?,
|
||||
};
|
||||
|
||||
// Create a graphics queue family command pool
|
||||
self.graphics_command_pool = try self.device.createCommandPool(&pool_create_info, null);
|
||||
}
|
||||
|
||||
fn createCommandBuffers(self: *Self) !void {
|
||||
// Allocate one command buffer for each framebuffer
|
||||
const command_buffer_handles = try self.allocator.alloc(vk.CommandBuffer, self.swapchain_framebuffers.len);
|
||||
defer self.allocator.free(command_buffer_handles);
|
||||
self.command_buffers = try self.allocator.alloc(CommandBuffer, command_buffer_handles.len);
|
||||
|
||||
const command_buffer_allocate_info: vk.CommandBufferAllocateInfo = .{
|
||||
.command_pool = self.graphics_command_pool,
|
||||
.level = .primary, // primary: buffer you submit directly to queue. Can't be called by other buffers
|
||||
.command_buffer_count = @intCast(command_buffer_handles.len),
|
||||
};
|
||||
|
||||
// Allocate command buffers and place handles in array of buffers
|
||||
try self.device.allocateCommandBuffers(&command_buffer_allocate_info, command_buffer_handles.ptr);
|
||||
for (command_buffer_handles, 0..) |command_buffer_handle, i| {
|
||||
self.command_buffers[i] = CommandBuffer.init(command_buffer_handle, self.device.wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
fn recordCommands(self: *Self) !void {
|
||||
// Information about how to begin each command
|
||||
const buffer_begin_info: vk.CommandBufferBeginInfo = .{
|
||||
// Buffer can be resubmitted when it has already been submitted and is awaiting execution
|
||||
.flags = .{ .simultaneous_use_bit = true },
|
||||
};
|
||||
|
||||
const clear_values = [_]vk.ClearValue{
|
||||
.{ .color = .{ .float_32 = [4]f32{ 0.6, 0.65, 0.4, 1.0 } } },
|
||||
};
|
||||
|
||||
// Information about how to begin a render pass (only needed for graphical application)
|
||||
var render_pass_begin_info: vk.RenderPassBeginInfo = .{
|
||||
.render_pass = self.render_pass, // Render pass to begin
|
||||
.render_area = .{
|
||||
.offset = .{ .x = 0, .y = 0 }, // Start point of render pass in pixels
|
||||
.extent = self.extent, // Size of region to run render pass on (starting at offset)
|
||||
},
|
||||
.p_clear_values = &clear_values, // List of clear values (TODO: Depth attachment clear value)
|
||||
.clear_value_count = 1,
|
||||
};
|
||||
|
||||
for (self.command_buffers, 0..) |command_buffer, i| {
|
||||
render_pass_begin_info.framebuffer = self.swapchain_framebuffers[i];
|
||||
|
||||
// Start recording commands to command buffer
|
||||
try command_buffer.beginCommandBuffer(&buffer_begin_info);
|
||||
|
||||
{
|
||||
// Begin render pass
|
||||
command_buffer.beginRenderPass(&render_pass_begin_info, vk.SubpassContents.@"inline");
|
||||
|
||||
// Bind pipeline to be used in render pass
|
||||
command_buffer.bindPipeline(.graphics, self.graphics_pipeline);
|
||||
|
||||
// Execute a pipeline
|
||||
command_buffer.draw(3, 1, 0, 0);
|
||||
|
||||
// End render pass
|
||||
command_buffer.endRenderPass();
|
||||
}
|
||||
|
||||
// Stop recording to command buffer
|
||||
try command_buffer.endCommandBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
fn getPhysicalDevice(self: *Self) !void {
|
||||
var pdev_count: u32 = 0;
|
||||
_ = try self.instance.enumeratePhysicalDevices(&pdev_count, null);
|
||||
|
@ -703,6 +812,15 @@ pub const VulkanRenderer = struct {
|
|||
self.instance.destroyDebugUtilsMessengerEXT(self.debug_utils.?, null);
|
||||
}
|
||||
|
||||
self.allocator.free(self.command_buffers);
|
||||
self.device.destroyCommandPool(self.graphics_command_pool, null);
|
||||
|
||||
for (self.swapchain_framebuffers) |framebuffer| {
|
||||
self.device.destroyFramebuffer(framebuffer, null);
|
||||
}
|
||||
|
||||
self.allocator.free(self.swapchain_framebuffers);
|
||||
|
||||
self.device.destroyPipeline(self.graphics_pipeline, null);
|
||||
self.device.destroyPipelineLayout(self.pipeline_layout, null);
|
||||
self.device.destroyRenderPass(self.render_pass, null);
|
||||
|
|
Loading…
Reference in a new issue