Triangle rendering

This commit is contained in:
Robin Voetter
2020-07-04 17:18:28 +02:00
parent fab23126e9
commit 40b74caee5
2 changed files with 49 additions and 78 deletions

View File

@@ -50,11 +50,7 @@ const DeviceDispatch = struct {
vkDestroyCommandPool: vk.PfnDestroyCommandPool, vkDestroyCommandPool: vk.PfnDestroyCommandPool,
vkAllocateCommandBuffers: vk.PfnAllocateCommandBuffers, vkAllocateCommandBuffers: vk.PfnAllocateCommandBuffers,
vkFreeCommandBuffers: vk.PfnFreeCommandBuffers, vkFreeCommandBuffers: vk.PfnFreeCommandBuffers,
vkBeginCommandBuffer: vk.PfnBeginCommandBuffer,
vkCmdClearColorImage: vk.PfnCmdClearColorImage,
vkEndCommandBuffer: vk.PfnEndCommandBuffer,
vkQueueWaitIdle: vk.PfnQueueWaitIdle, vkQueueWaitIdle: vk.PfnQueueWaitIdle,
vkCmdPipelineBarrier: vk.PfnCmdPipelineBarrier,
vkCreateShaderModule: vk.PfnCreateShaderModule, vkCreateShaderModule: vk.PfnCreateShaderModule,
vkDestroyShaderModule: vk.PfnDestroyShaderModule, vkDestroyShaderModule: vk.PfnDestroyShaderModule,
vkCreatePipelineLayout: vk.PfnCreatePipelineLayout, vkCreatePipelineLayout: vk.PfnCreatePipelineLayout,
@@ -65,6 +61,12 @@ const DeviceDispatch = struct {
vkDestroyPipeline: vk.PfnDestroyPipeline, vkDestroyPipeline: vk.PfnDestroyPipeline,
vkCreateFramebuffer: vk.PfnCreateFramebuffer, vkCreateFramebuffer: vk.PfnCreateFramebuffer,
vkDestroyFramebuffer: vk.PfnDestroyFramebuffer, vkDestroyFramebuffer: vk.PfnDestroyFramebuffer,
vkBeginCommandBuffer: vk.PfnBeginCommandBuffer,
vkEndCommandBuffer: vk.PfnEndCommandBuffer,
vkCmdBeginRenderPass: vk.PfnCmdBeginRenderPass,
vkCmdEndRenderPass: vk.PfnCmdEndRenderPass,
vkCmdBindPipeline: vk.PfnCmdBindPipeline,
vkCmdDraw: vk.PfnCmdDraw,
usingnamespace vk.DeviceWrapper(@This()); usingnamespace vk.DeviceWrapper(@This());
}; };

View File

@@ -46,7 +46,7 @@ pub fn main() !void {
const render_pass = try createRenderPass(&gc, swapchain); const render_pass = try createRenderPass(&gc, swapchain);
defer gc.vkd.destroyRenderPass(gc.dev, render_pass, null); defer gc.vkd.destroyRenderPass(gc.dev, render_pass, null);
const pipeline = try createPipeline(&gc, extent, pipeline_layout, render_pass); var pipeline = try createPipeline(&gc, extent, pipeline_layout, render_pass);
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null); defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain); var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
@@ -58,7 +58,15 @@ pub fn main() !void {
}, null); }, null);
defer gc.vkd.destroyCommandPool(gc.dev, pool, null); defer gc.vkd.destroyCommandPool(gc.dev, pool, null);
var cmdbufs = try createCommandBuffers(&gc, pool, allocator, swapchain); var cmdbufs = try createCommandBuffers(
&gc,
pool,
allocator,
swapchain.extent,
render_pass,
pipeline,
framebuffers
);
defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs); defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) { while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) {
@@ -77,11 +85,22 @@ pub fn main() !void {
extent.height = @intCast(u32, h); extent.height = @intCast(u32, h);
try swapchain.recreate(extent); try swapchain.recreate(extent);
gc.vkd.destroyPipeline(gc.dev, pipeline, null);
pipeline = try createPipeline(&gc, extent, pipeline_layout, render_pass);
destroyFramebuffers(&gc, allocator, framebuffers); destroyFramebuffers(&gc, allocator, framebuffers);
framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain); framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
destroyCommandBuffers(&gc, pool, allocator, cmdbufs); destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
cmdbufs = try createCommandBuffers(&gc, pool, allocator, swapchain); cmdbufs = try createCommandBuffers(
&gc,
pool,
allocator,
swapchain.extent,
render_pass,
pipeline,
framebuffers
);
} }
c.glfwSwapBuffers(window); c.glfwSwapBuffers(window);
@@ -95,9 +114,12 @@ fn createCommandBuffers(
gc: *const GraphicsContext, gc: *const GraphicsContext,
pool: vk.CommandPool, pool: vk.CommandPool,
allocator: *Allocator, allocator: *Allocator,
swapchain: Swapchain, extent: vk.Extent2D,
render_pass: vk.RenderPass,
pipeline: vk.Pipeline,
framebuffers: []vk.Framebuffer,
) ![]vk.CommandBuffer { ) ![]vk.CommandBuffer {
const cmdbufs = try allocator.alloc(vk.CommandBuffer, swapchain.swap_images.len); const cmdbufs = try allocator.alloc(vk.CommandBuffer, framebuffers.len);
errdefer allocator.free(cmdbufs); errdefer allocator.free(cmdbufs);
try gc.vkd.allocateCommandBuffers(gc.dev, .{ try gc.vkd.allocateCommandBuffers(gc.dev, .{
@@ -107,51 +129,31 @@ fn createCommandBuffers(
}, cmdbufs.ptr); }, cmdbufs.ptr);
errdefer gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(u32, cmdbufs.len), cmdbufs.ptr); errdefer gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(u32, cmdbufs.len), cmdbufs.ptr);
const subresource_range = vk.ImageSubresourceRange{ const clear = vk.ClearValue{
.aspect_mask = .{.color_bit = true}, .color = .{.float_32 = .{0, 0, 0, 1}},
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
}; };
const color = vk.ClearColorValue{.float_32 = .{1, 0, 1, 1}};
for (cmdbufs) |cmdbuf, i| { for (cmdbufs) |cmdbuf, i| {
const image = swapchain.swap_images[i].image;
try gc.vkd.beginCommandBuffer(cmdbuf, .{ try gc.vkd.beginCommandBuffer(cmdbuf, .{
.flags = .{}, .flags = .{},
.p_inheritance_info = null, .p_inheritance_info = null,
}); });
imageTransition( gc.vkd.cmdBeginRenderPass(cmdbuf, .{
gc, .render_pass = render_pass,
cmdbuf, .framebuffer = framebuffers[i],
image, .render_area = .{
subresource_range, .offset = .{.x = 0, .y = 0},
.{.layout = .@"undefined", .stage = .{.top_of_pipe_bit = true}}, .extent = extent,
.{.layout = .general, .stage = .{.top_of_pipe_bit = true}}, },
); .clear_value_count = 1,
.p_clear_values = @ptrCast([*]const vk.ClearValue, &clear),
}, .@"inline");
gc.vkd.cmdClearColorImage( gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline);
cmdbuf, gc.vkd.cmdDraw(cmdbuf, 3, 1, 0, 0);
image,
.general,
color,
1,
@ptrCast([*]const vk.ImageSubresourceRange, &subresource_range),
);
imageTransition(
gc,
cmdbuf,
image,
subresource_range,
.{.layout = .general, .stage = .{.top_of_pipe_bit = true}},
.{.layout = .present_src_khr, .stage = .{.bottom_of_pipe_bit = true}},
);
gc.vkd.cmdEndRenderPass(cmdbuf);
try gc.vkd.endCommandBuffer(cmdbuf); try gc.vkd.endCommandBuffer(cmdbuf);
} }
@@ -374,7 +376,7 @@ fn createPipeline(
.p_multisample_state = &pmsci, .p_multisample_state = &pmsci,
.p_depth_stencil_state = null, .p_depth_stencil_state = null,
.p_color_blend_state = &pcbsci, .p_color_blend_state = &pcbsci,
.p_dynamic_state = &pdsci, .p_dynamic_state = null, //&pdsci,
.layout = layout, .layout = layout,
.render_pass = render_pass, .render_pass = render_pass,
.subpass = 0, .subpass = 0,
@@ -392,36 +394,3 @@ fn createPipeline(
); );
return pipeline; return pipeline;
} }
const ImageState = struct {
layout: vk.ImageLayout,
stage: vk.PipelineStageFlags,
access_mask: vk.AccessFlags = .{},
};
fn imageTransition(
gc: *const GraphicsContext,
cmdbuf: vk.CommandBuffer,
image: vk.Image,
subresource_range: vk.ImageSubresourceRange,
src: ImageState,
dst: ImageState
) void {
const barrier = vk.ImageMemoryBarrier{
.src_access_mask = src.access_mask,
.dst_access_mask = dst.access_mask,
.old_layout = src.layout,
.new_layout = dst.layout,
.src_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.dst_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.image = image,
.subresource_range = subresource_range,
};
gc.vkd.cmdPipelineBarrier(
cmdbuf, src.stage, dst.stage, .{},
0, undefined,
0, undefined,
1, @ptrCast([*]const vk.ImageMemoryBarrier, &barrier)
);
}