Render first triangle
This commit is contained in:
parent
ed1b9db61e
commit
0e348fe0a0
13
src/main.zig
13
src/main.zig
@ -11,6 +11,7 @@ const framebuffers_mod = @import("vulkan/framebuffers.zig");
|
|||||||
const render_pass_mod = @import("vulkan/render_pass.zig");
|
const render_pass_mod = @import("vulkan/render_pass.zig");
|
||||||
const swapchain_mod = @import("vulkan/swapchain.zig");
|
const swapchain_mod = @import("vulkan/swapchain.zig");
|
||||||
const sync_mod = @import("vulkan/sync.zig");
|
const sync_mod = @import("vulkan/sync.zig");
|
||||||
|
const pipeline_mod = @import("vulkan/pipeline.zig");
|
||||||
|
|
||||||
// The build script compiles these GLSL files to SPIR-V and exposes them as
|
// The build script compiles these GLSL files to SPIR-V and exposes them as
|
||||||
// anonymous imports. They are currently only loaded and printed; the program
|
// anonymous imports. They are currently only loaded and printed; the program
|
||||||
@ -85,6 +86,9 @@ pub fn main() !void {
|
|||||||
var render_pass_context = try render_pass_mod.initRenderPass(ldc, swapchain_context.format.format);
|
var render_pass_context = try render_pass_mod.initRenderPass(ldc, swapchain_context.format.format);
|
||||||
defer render_pass_context.destroy(&ldc);
|
defer render_pass_context.destroy(&ldc);
|
||||||
|
|
||||||
|
var pipeline_context = try pipeline_mod.initPipelineContext(ldc, swapchain_context.extent, render_pass_context.render_pass, square_vert_spv, square_frag_spv, std.heap.page_allocator);
|
||||||
|
defer pipeline_context.destroy(&ldc);
|
||||||
|
|
||||||
var framebuffer_context = try framebuffers_mod.initFramebuffers(
|
var framebuffer_context = try framebuffers_mod.initFramebuffers(
|
||||||
ldc,
|
ldc,
|
||||||
render_pass_context,
|
render_pass_context,
|
||||||
@ -97,6 +101,7 @@ pub fn main() !void {
|
|||||||
ldc,
|
ldc,
|
||||||
render_pass_context,
|
render_pass_context,
|
||||||
framebuffer_context,
|
framebuffer_context,
|
||||||
|
pipeline_context,
|
||||||
swapchain_context,
|
swapchain_context,
|
||||||
std.heap.page_allocator,
|
std.heap.page_allocator,
|
||||||
);
|
);
|
||||||
@ -123,6 +128,7 @@ pub fn main() !void {
|
|||||||
&swapchain_context,
|
&swapchain_context,
|
||||||
&render_pass_context,
|
&render_pass_context,
|
||||||
&framebuffer_context,
|
&framebuffer_context,
|
||||||
|
&pipeline_context,
|
||||||
&command_context,
|
&command_context,
|
||||||
std.heap.page_allocator,
|
std.heap.page_allocator,
|
||||||
);
|
);
|
||||||
@ -140,6 +146,7 @@ fn recreateSwapchain(
|
|||||||
swapchain_context: *swapchain_mod.SwapchainContext,
|
swapchain_context: *swapchain_mod.SwapchainContext,
|
||||||
render_pass_context: *render_pass_mod.RenderPassContext,
|
render_pass_context: *render_pass_mod.RenderPassContext,
|
||||||
framebuffer_context: *framebuffers_mod.FramebufferContext,
|
framebuffer_context: *framebuffers_mod.FramebufferContext,
|
||||||
|
pipeline_context: *pipeline_mod.PipelineContext,
|
||||||
command_context: *commands_mod.CommandContext,
|
command_context: *commands_mod.CommandContext,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
) !void {
|
) !void {
|
||||||
@ -171,6 +178,9 @@ fn recreateSwapchain(
|
|||||||
const new_render_pass_context = try render_pass_mod.initRenderPass(ldc, new_swapchain_context.format.format);
|
const new_render_pass_context = try render_pass_mod.initRenderPass(ldc, new_swapchain_context.format.format);
|
||||||
errdefer new_render_pass_context.destroy(&ldc);
|
errdefer new_render_pass_context.destroy(&ldc);
|
||||||
|
|
||||||
|
const new_pipeline_context = try pipeline_mod.initPipelineContext(ldc, swapchain_context.extent, render_pass_context.render_pass, square_vert_spv, square_frag_spv, std.heap.page_allocator);
|
||||||
|
errdefer pipeline_context.destroy(&ldc);
|
||||||
|
|
||||||
const new_framebuffer_context = try framebuffers_mod.initFramebuffers(
|
const new_framebuffer_context = try framebuffers_mod.initFramebuffers(
|
||||||
ldc,
|
ldc,
|
||||||
new_render_pass_context,
|
new_render_pass_context,
|
||||||
@ -183,6 +193,7 @@ fn recreateSwapchain(
|
|||||||
ldc,
|
ldc,
|
||||||
new_render_pass_context,
|
new_render_pass_context,
|
||||||
new_framebuffer_context,
|
new_framebuffer_context,
|
||||||
|
new_pipeline_context,
|
||||||
new_swapchain_context,
|
new_swapchain_context,
|
||||||
allocator,
|
allocator,
|
||||||
);
|
);
|
||||||
@ -193,11 +204,13 @@ fn recreateSwapchain(
|
|||||||
// swapchain/image views/images.
|
// swapchain/image views/images.
|
||||||
command_context.destroy(&ldc);
|
command_context.destroy(&ldc);
|
||||||
framebuffer_context.destroy(&ldc);
|
framebuffer_context.destroy(&ldc);
|
||||||
|
pipeline_context.destroy(&ldc);
|
||||||
render_pass_context.destroy(&ldc);
|
render_pass_context.destroy(&ldc);
|
||||||
swapchain_context.destroy(&ldc);
|
swapchain_context.destroy(&ldc);
|
||||||
|
|
||||||
swapchain_context.* = new_swapchain_context;
|
swapchain_context.* = new_swapchain_context;
|
||||||
render_pass_context.* = new_render_pass_context;
|
render_pass_context.* = new_render_pass_context;
|
||||||
|
pipeline_context.* = new_pipeline_context;
|
||||||
framebuffer_context.* = new_framebuffer_context;
|
framebuffer_context.* = new_framebuffer_context;
|
||||||
command_context.* = new_command_context;
|
command_context.* = new_command_context;
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ const device = @import("device.zig");
|
|||||||
const framebuffers = @import("framebuffers.zig");
|
const framebuffers = @import("framebuffers.zig");
|
||||||
const render_pass = @import("render_pass.zig");
|
const render_pass = @import("render_pass.zig");
|
||||||
const swapchain = @import("swapchain.zig");
|
const swapchain = @import("swapchain.zig");
|
||||||
|
const pipeline = @import("pipeline.zig");
|
||||||
|
|
||||||
pub const CommandContext = struct {
|
pub const CommandContext = struct {
|
||||||
command_pool: vk.CommandPool,
|
command_pool: vk.CommandPool,
|
||||||
@ -21,6 +22,7 @@ pub fn initCommandBuffers(
|
|||||||
ldc: device.LogicalDeviceContext,
|
ldc: device.LogicalDeviceContext,
|
||||||
render_pass_context: render_pass.RenderPassContext,
|
render_pass_context: render_pass.RenderPassContext,
|
||||||
framebuffer_context: framebuffers.FramebufferContext,
|
framebuffer_context: framebuffers.FramebufferContext,
|
||||||
|
pipeline_context: pipeline.PipelineContext,
|
||||||
swapchain_context: swapchain.SwapchainContext,
|
swapchain_context: swapchain.SwapchainContext,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
) !CommandContext {
|
) !CommandContext {
|
||||||
@ -86,6 +88,14 @@ pub fn initCommandBuffers(
|
|||||||
.@"inline",
|
.@"inline",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ldc.vkd.cmdBindPipeline(
|
||||||
|
command_buffer,
|
||||||
|
.graphics,
|
||||||
|
pipeline_context.graphics_pipeline,
|
||||||
|
);
|
||||||
|
|
||||||
|
ldc.vkd.cmdDraw(command_buffer, 3, 1, 0, 0);
|
||||||
|
|
||||||
ldc.vkd.cmdEndRenderPass(command_buffer);
|
ldc.vkd.cmdEndRenderPass(command_buffer);
|
||||||
|
|
||||||
try ldc.vkd.endCommandBuffer(command_buffer);
|
try ldc.vkd.endCommandBuffer(command_buffer);
|
||||||
|
|||||||
@ -1,14 +1,183 @@
|
|||||||
|
const std = @import("std");
|
||||||
const vk = @import("vulkan");
|
const vk = @import("vulkan");
|
||||||
|
|
||||||
const device = @import("device.zig");
|
const device = @import("device.zig");
|
||||||
|
|
||||||
pub fn createShaderModule(ldc: device.LogicalDeviceContext, spv: []const u8) !vk.ShaderModule {
|
pub const PipelineContext = struct {
|
||||||
|
graphics_pipeline: vk.Pipeline,
|
||||||
|
pipeline_layout: vk.PipelineLayout,
|
||||||
|
|
||||||
|
pub fn destroy(self: *const PipelineContext, ldc: *const device.LogicalDeviceContext) void {
|
||||||
|
ldc.vkd.destroyPipeline(ldc.device, self.graphics_pipeline, null);
|
||||||
|
ldc.vkd.destroyPipelineLayout(ldc.device, self.pipeline_layout, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn createShaderModule(ldc: device.LogicalDeviceContext, allocator: std.mem.Allocator, spv: []const u8) !vk.ShaderModule {
|
||||||
if (spv.len % 4 != 0) return error.InvalidSpirVSize;
|
if (spv.len % 4 != 0) return error.InvalidSpirVSize;
|
||||||
|
|
||||||
|
const words = try allocator.alloc(u32, spv.len / 4);
|
||||||
|
defer allocator.free(words);
|
||||||
|
|
||||||
|
const word_bytes = std.mem.sliceAsBytes(words);
|
||||||
|
std.mem.copyForwards(u8, word_bytes, spv);
|
||||||
|
|
||||||
const create_info = vk.ShaderModuleCreateInfo{
|
const create_info = vk.ShaderModuleCreateInfo{
|
||||||
.code_size = spv.len,
|
.code_size = spv.len,
|
||||||
.p_code = @ptrCast(@alignCast(spv.ptr)),
|
.p_code = words.ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
return try ldc.vkd.createShaderModule(ldc.device, &create_info, null);
|
return try ldc.vkd.createShaderModule(ldc.device, &create_info, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn initPipelineContext(ldc: device.LogicalDeviceContext, extent: vk.Extent2D, render_pass: vk.RenderPass, vert_spv: []const u8, frag_spv: []const u8, allocator: std.mem.Allocator) !PipelineContext {
|
||||||
|
const pipeline_layout_create_info = vk.PipelineLayoutCreateInfo{};
|
||||||
|
|
||||||
|
const pipeline_layout = try ldc.vkd.createPipelineLayout(
|
||||||
|
ldc.device,
|
||||||
|
&pipeline_layout_create_info,
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
errdefer ldc.vkd.destroyPipelineLayout(ldc.device, pipeline_layout, null);
|
||||||
|
|
||||||
|
const vert_shader_module = try createShaderModule(ldc, allocator, vert_spv);
|
||||||
|
defer ldc.vkd.destroyShaderModule(ldc.device, vert_shader_module, null);
|
||||||
|
|
||||||
|
const frag_shader_module = try createShaderModule(ldc, allocator, frag_spv);
|
||||||
|
defer ldc.vkd.destroyShaderModule(ldc.device, frag_shader_module, null);
|
||||||
|
|
||||||
|
const vert_shader_stage_info = vk.PipelineShaderStageCreateInfo{
|
||||||
|
.stage = .{ .vertex_bit = true },
|
||||||
|
.module = vert_shader_module,
|
||||||
|
.p_name = "main",
|
||||||
|
};
|
||||||
|
|
||||||
|
const frag_shader_stage_info = vk.PipelineShaderStageCreateInfo{
|
||||||
|
.stage = .{ .fragment_bit = true },
|
||||||
|
.module = frag_shader_module,
|
||||||
|
.p_name = "main",
|
||||||
|
};
|
||||||
|
|
||||||
|
const shader_stages = [_]vk.PipelineShaderStageCreateInfo{
|
||||||
|
vert_shader_stage_info,
|
||||||
|
frag_shader_stage_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vertex_input_info = vk.PipelineVertexInputStateCreateInfo{
|
||||||
|
.vertex_binding_description_count = 0,
|
||||||
|
.p_vertex_binding_descriptions = null,
|
||||||
|
.vertex_attribute_description_count = 0,
|
||||||
|
.p_vertex_attribute_descriptions = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const input_assembly = vk.PipelineInputAssemblyStateCreateInfo{
|
||||||
|
.topology = .triangle_list,
|
||||||
|
.primitive_restart_enable = .false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const viewport = vk.Viewport{
|
||||||
|
.x = 0.0,
|
||||||
|
.y = 0.0,
|
||||||
|
.width = @floatFromInt(extent.width),
|
||||||
|
.height = @floatFromInt(extent.height),
|
||||||
|
.min_depth = 0.0,
|
||||||
|
.max_depth = 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const scissor = vk.Rect2D{
|
||||||
|
.offset = .{ .x = 0, .y = 0 },
|
||||||
|
.extent = extent,
|
||||||
|
};
|
||||||
|
|
||||||
|
const viewport_state = vk.PipelineViewportStateCreateInfo{
|
||||||
|
.viewport_count = 1,
|
||||||
|
.p_viewports = @ptrCast(&viewport),
|
||||||
|
.scissor_count = 1,
|
||||||
|
.p_scissors = @ptrCast(&scissor),
|
||||||
|
};
|
||||||
|
|
||||||
|
const rasterizer = vk.PipelineRasterizationStateCreateInfo{
|
||||||
|
.depth_clamp_enable = .false,
|
||||||
|
.rasterizer_discard_enable = .false,
|
||||||
|
.polygon_mode = .fill,
|
||||||
|
.line_width = 1.0,
|
||||||
|
.cull_mode = .{
|
||||||
|
.back_bit = true,
|
||||||
|
},
|
||||||
|
.front_face = .clockwise,
|
||||||
|
.depth_bias_enable = .false,
|
||||||
|
.depth_bias_constant_factor = 0.0,
|
||||||
|
.depth_bias_clamp = 0.0,
|
||||||
|
.depth_bias_slope_factor = 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const multisampling = vk.PipelineMultisampleStateCreateInfo{
|
||||||
|
.sample_shading_enable = .false,
|
||||||
|
.rasterization_samples = .{ .@"1_bit" = true },
|
||||||
|
.min_sample_shading = 1.0,
|
||||||
|
.p_sample_mask = null,
|
||||||
|
.alpha_to_coverage_enable = .false,
|
||||||
|
.alpha_to_one_enable = .false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const color_blend_attachment = vk.PipelineColorBlendAttachmentState{
|
||||||
|
.color_write_mask = .{
|
||||||
|
.r_bit = true,
|
||||||
|
.g_bit = true,
|
||||||
|
.b_bit = true,
|
||||||
|
.a_bit = true,
|
||||||
|
},
|
||||||
|
.blend_enable = .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,
|
||||||
|
};
|
||||||
|
|
||||||
|
const color_blending = vk.PipelineColorBlendStateCreateInfo{
|
||||||
|
.logic_op_enable = .false,
|
||||||
|
.attachment_count = 1,
|
||||||
|
.p_attachments = @ptrCast(&color_blend_attachment),
|
||||||
|
.blend_constants = .{ 0.0, 0.0, 0.0, 0.0 },
|
||||||
|
.logic_op = .copy,
|
||||||
|
};
|
||||||
|
|
||||||
|
const pipeline_info = vk.GraphicsPipelineCreateInfo{
|
||||||
|
.stage_count = shader_stages.len,
|
||||||
|
.p_stages = &shader_stages,
|
||||||
|
.p_vertex_input_state = &vertex_input_info,
|
||||||
|
.p_input_assembly_state = &input_assembly,
|
||||||
|
.p_viewport_state = &viewport_state,
|
||||||
|
.p_rasterization_state = &rasterizer,
|
||||||
|
.p_multisample_state = &multisampling,
|
||||||
|
.p_depth_stencil_state = null,
|
||||||
|
.p_color_blend_state = &color_blending,
|
||||||
|
.p_dynamic_state = null,
|
||||||
|
.layout = pipeline_layout,
|
||||||
|
.render_pass = render_pass,
|
||||||
|
.subpass = 0,
|
||||||
|
.base_pipeline_handle = .null_handle,
|
||||||
|
.base_pipeline_index = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const pipeline_infos = [_]vk.GraphicsPipelineCreateInfo{
|
||||||
|
pipeline_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
var pipelines: [1]vk.Pipeline = undefined;
|
||||||
|
|
||||||
|
_ = try ldc.vkd.createGraphicsPipelines(
|
||||||
|
ldc.device,
|
||||||
|
.null_handle,
|
||||||
|
&pipeline_infos,
|
||||||
|
null,
|
||||||
|
&pipelines,
|
||||||
|
);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.graphics_pipeline = pipelines[0],
|
||||||
|
.pipeline_layout = pipeline_layout,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user