Pipeline(Layout) & render pass creation

This commit is contained in:
Robin Voetter
2020-07-04 16:46:38 +02:00
parent 0be71d1614
commit e217cbab77
7 changed files with 271 additions and 24 deletions

View File

@@ -12,12 +12,12 @@ pub fn main() !void {
if (c.glfwInit() != c.GLFW_TRUE) return error.GlfwInitFailed;
defer c.glfwTerminate();
const extent = vk.Extent2D{.width = 800, .height = 600};
var extent = vk.Extent2D{.width = 800, .height = 600};
c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API);
const window = c.glfwCreateWindow(
extent.width,
extent.height,
@intCast(c_int, extent.width),
@intCast(c_int, extent.height),
app_name,
null,
null
@@ -34,6 +34,21 @@ pub fn main() !void {
var swapchain = try Swapchain.init(&gc, allocator, extent);
defer swapchain.deinit();
const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, .{
.flags = .{},
.set_layout_count = 0,
.p_set_layouts = undefined,
.push_constant_range_count = 0,
.p_push_constant_ranges = undefined,
}, null);
defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null);
const render_pass = try createRenderPass(&gc, &swapchain);
defer gc.vkd.destroyRenderPass(gc.dev, render_pass, null);
const pipeline = try createPipeline(&gc, extent, pipeline_layout, render_pass);
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
const pool = try gc.vkd.createCommandPool(gc.dev, .{
.flags = .{},
.queue_family_index = gc.graphics_queue.family,
@@ -55,8 +70,9 @@ pub fn main() !void {
var w: c_int = undefined;
var h: c_int = undefined;
c.glfwGetWindowSize(window, &w, &h);
try swapchain.recreate(.{.width = @intCast(u32, w), .height = @intCast(u32, h)});
extent.width = @intCast(u32, w);
extent.height = @intCast(u32, h);
try swapchain.recreate(extent);
destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
cmdbufs = try createCommandBuffers(&gc, pool, allocator, swapchain);
@@ -141,6 +157,203 @@ fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, alloc
allocator.free(cmdbufs);
}
fn createRenderPass(gc: *const GraphicsContext, swapchain: *const Swapchain) !vk.RenderPass {
const color_attachment = vk.AttachmentDescription{
.flags = .{},
.format = swapchain.surface_format.format,
.samples = .{.@"1_bit" = true},
.load_op = .clear,
.store_op = .store,
.stencil_load_op = .dont_care,
.stencil_store_op = .dont_care,
.initial_layout = .@"undefined",
.final_layout = .present_src_khr,
};
const color_attachment_ref = vk.AttachmentReference{
.attachment = 0,
.layout = .color_attachment_optimal,
};
const subpass = vk.SubpassDescription{
.flags = .{},
.pipeline_bind_point = .graphics,
.input_attachment_count = 0,
.p_input_attachments = undefined,
.color_attachment_count = 1,
.p_color_attachments = @ptrCast([*]const vk.AttachmentReference, &color_attachment_ref),
.p_resolve_attachments = null,
.p_depth_stencil_attachment = null,
.preserve_attachment_count = 0,
.p_preserve_attachments = undefined,
};
return try gc.vkd.createRenderPass(gc.dev, .{
.flags = .{},
.attachment_count = 1,
.p_attachments = @ptrCast([*]const vk.AttachmentDescription, &color_attachment),
.subpass_count = 1,
.p_subpasses = @ptrCast([*]const vk.SubpassDescription, &subpass),
.dependency_count = 0,
.p_dependencies = undefined,
}, null);
}
fn createPipeline(
gc: *const GraphicsContext,
extent: vk.Extent2D,
layout: vk.PipelineLayout,
render_pass: vk.RenderPass,
) !vk.Pipeline {
const vert = try gc.vkd.createShaderModule(gc.dev, .{
.flags = .{},
.code_size = resources.triangle_vert.len,
.p_code = @ptrCast([*]const u32, resources.triangle_vert),
}, null);
defer gc.vkd.destroyShaderModule(gc.dev, vert, null);
const frag = try gc.vkd.createShaderModule(gc.dev, .{
.flags = .{},
.code_size = resources.triangle_frag.len,
.p_code = @ptrCast([*]const u32, resources.triangle_frag),
}, null);
defer gc.vkd.destroyShaderModule(gc.dev, frag, null);
const pssci = [_]vk.PipelineShaderStageCreateInfo{
.{
.flags = .{},
.stage = .{.vertex_bit = true},
.module = vert,
.p_name = "main",
.p_specialization_info = null,
},
.{
.flags = .{},
.stage = .{.fragment_bit = true},
.module = frag,
.p_name = "main",
.p_specialization_info = null,
},
};
const pvisci = vk.PipelineVertexInputStateCreateInfo{
.flags = .{},
.vertex_binding_description_count = 0,
.p_vertex_binding_descriptions = undefined,
.vertex_attribute_description_count = 0,
.p_vertex_attribute_descriptions = undefined,
};
const piasci = vk.PipelineInputAssemblyStateCreateInfo{
.flags = .{},
.topology = .triangle_list,
.primitive_restart_enable = vk.FALSE,
};
const viewport = vk.Viewport{
.x = 0,
.y = 0,
.width = @intToFloat(f32, extent.width),
.height = @intToFloat(f32, extent.height),
.min_depth = 0,
.max_depth = 1,
};
const scissor = vk.Rect2D{
.offset = .{.x = 0, .y = 0},
.extent = extent,
};
const pvsci = vk.PipelineViewportStateCreateInfo{
.flags = .{},
.viewport_count = 1,
.p_viewports = @ptrCast([*]const vk.Viewport, &viewport),
.scissor_count = 1,
.p_scissors = @ptrCast([*]const vk.Rect2D, &scissor),
};
const prsci = vk.PipelineRasterizationStateCreateInfo{
.flags = .{},
.depth_clamp_enable = vk.FALSE,
.rasterizer_discard_enable = vk.FALSE,
.polygon_mode = .fill,
.cull_mode = .{.back_bit = true},
.front_face = .clockwise,
.depth_bias_enable = vk.FALSE,
.depth_bias_constant_factor = 0,
.depth_bias_clamp = 0,
.depth_bias_slope_factor = 0,
.line_width = 1,
};
const pmsci = vk.PipelineMultisampleStateCreateInfo{
.flags = .{},
.rasterization_samples = .{.@"1_bit" = true},
.sample_shading_enable = vk.FALSE,
.min_sample_shading = 1,
.p_sample_mask = null,
.alpha_to_coverage_enable = vk.FALSE,
.alpha_to_one_enable = vk.FALSE,
};
const pcbas = vk.PipelineColorBlendAttachmentState{
.blend_enable = vk.FALSE,
.src_color_blend_factor = .one,
.dst_color_blend_factor = .zero,
.color_blend_op = .add,
.src_alpha_blend_factor = .one,
.dst_alpha_blend_factor = .zero,
.alpha_blend_op = .add,
.color_write_mask = .{.r_bit = true, .g_bit = true, .b_bit = true, .a_bit = true},
};
const pcbsci = vk.PipelineColorBlendStateCreateInfo{
.flags = .{},
.logic_op_enable = vk.FALSE,
.logic_op = .copy,
.attachment_count = 1,
.p_attachments = @ptrCast([*]const vk.PipelineColorBlendAttachmentState, &pcbas),
.blend_constants = [_]f32{0, 0, 0, 0},
};
const dynstate = vk.DynamicState.viewport;
const pdsci = vk.PipelineDynamicStateCreateInfo{
.flags = .{},
.dynamic_state_count = 1,
.p_dynamic_states = @ptrCast([*]const vk.DynamicState, &dynstate),
};
const gpci = vk.GraphicsPipelineCreateInfo{
.flags = .{},
.stage_count = 2,
.p_stages = &pssci,
.p_vertex_input_state = &pvisci,
.p_input_assembly_state = &piasci,
.p_tessellation_state = null,
.p_viewport_state = &pvsci,
.p_rasterization_state = &prsci,
.p_multisample_state = &pmsci,
.p_depth_stencil_state = null,
.p_color_blend_state = &pcbsci,
.p_dynamic_state = &pdsci,
.layout = layout,
.render_pass = render_pass,
.subpass = 0,
.base_pipeline_handle = .null_handle,
.base_pipeline_index = -1,
};
var pipeline: vk.Pipeline = undefined;
_ = try gc.vkd.createGraphicsPipelines(
gc.dev,
.null_handle,
1, @ptrCast([*]const vk.GraphicsPipelineCreateInfo, &gpci),
null,
@ptrCast([*]vk.Pipeline, &pipeline),
);
return pipeline;
}
const ImageState = struct {
layout: vk.ImageLayout,
stage: vk.PipelineStageFlags,