comment command buffers + swapchain stuff. going to follow vulkan-tutorial instead
This commit is contained in:
59
src/dsa.zig
59
src/dsa.zig
@@ -1,59 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
/// Slices must be sorted. Checks if `a` includes all elements of `b`.
|
||||
pub fn includes(comptime T: type, a: []const T, b: []const T) bool {
|
||||
var ia: usize = 0;
|
||||
var ib: usize = 0;
|
||||
|
||||
while (ib != b.len) {
|
||||
if (ia == a.len) return false;
|
||||
if (b[ib] < a[ia]) return false;
|
||||
if (!(a[ia] < b[ib])) ib += 1;
|
||||
ia += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
test includes {
|
||||
try std.testing.expect(includes(
|
||||
usize,
|
||||
&.{},
|
||||
&.{},
|
||||
));
|
||||
try std.testing.expect(includes(
|
||||
usize,
|
||||
&.{ 1, 2, 3, 4, 5 },
|
||||
&.{},
|
||||
));
|
||||
try std.testing.expect(includes(
|
||||
usize,
|
||||
&.{ 1, 2, 3, 4, 5 },
|
||||
&.{ 1, 2, 3, 4, 5 },
|
||||
));
|
||||
try std.testing.expect(!includes(
|
||||
usize,
|
||||
&.{},
|
||||
&.{ 1, 2, 3, 4, 5 },
|
||||
));
|
||||
|
||||
try std.testing.expect(includes(
|
||||
usize,
|
||||
&.{ 1, 2, 2, 4 },
|
||||
&.{ 2, 2 },
|
||||
));
|
||||
try std.testing.expect(includes(
|
||||
usize,
|
||||
&.{ 1, 2, 2, 4 },
|
||||
&.{ 1, 2, 2, 4 },
|
||||
));
|
||||
try std.testing.expect(!includes(
|
||||
usize,
|
||||
&.{ 1, 2, 2, 4 },
|
||||
&.{ 2, 2, 2 },
|
||||
));
|
||||
try std.testing.expect(!includes(
|
||||
usize,
|
||||
&.{ 1, 2, 2, 4 },
|
||||
&.{ 2, 2, 3 },
|
||||
));
|
||||
}
|
646
src/main.zig
646
src/main.zig
@@ -2,8 +2,6 @@ const std = @import("std");
|
||||
const vk = @import("vk");
|
||||
const c = @import("c.zig");
|
||||
const shaders = @import("shaders");
|
||||
const Swapchain = @import("swapchain.zig").Swapchain;
|
||||
const Context = @import("swapchain.zig").Context;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const gfx = @import("gfx.zig");
|
||||
@@ -298,80 +296,82 @@ pub fn main() !void {
|
||||
try create_device(ally, instance, surface, vki);
|
||||
defer vkd.destroyDevice(dev, null);
|
||||
|
||||
const queue = vkd.getDeviceQueue(dev, family, 0);
|
||||
|
||||
const preferred_format: vk.SurfaceFormatKHR = .{
|
||||
.format = .b8g8r8a8_srgb,
|
||||
.color_space = .srgb_nonlinear_khr,
|
||||
};
|
||||
const format = try find_surface_format(pdev, surface, preferred_format, vki);
|
||||
|
||||
const queue = vkd.getDeviceQueue(dev, family, 0);
|
||||
_ = &extent;
|
||||
|
||||
const gc: Context = .{
|
||||
.vki = vki,
|
||||
.vkd = vkd,
|
||||
.pdev = pdev,
|
||||
.dev = dev,
|
||||
.surface = surface,
|
||||
.queue = queue,
|
||||
.family = family,
|
||||
};
|
||||
// const gc: Context = .{
|
||||
// .vki = vki,
|
||||
// .vkd = vkd,
|
||||
// .pdev = pdev,
|
||||
// .dev = dev,
|
||||
// .surface = surface,
|
||||
// .queue = queue,
|
||||
// .family = family,
|
||||
// };
|
||||
//
|
||||
// var swapchain = try Swapchain.init(&gc, ally, extent, format);
|
||||
// defer swapchain.deinit();
|
||||
|
||||
var swapchain = try Swapchain.init(&gc, ally, extent, format);
|
||||
defer swapchain.deinit();
|
||||
|
||||
const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{
|
||||
const pipeline_layout = try vkd.createPipelineLayout(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);
|
||||
defer vkd.destroyPipelineLayout(dev, pipeline_layout, null);
|
||||
|
||||
const pipeline = try createPipeline(&gc, pipeline_layout, format);
|
||||
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
|
||||
const pipeline = try createPipeline(dev, pipeline_layout, format, vkd);
|
||||
defer vkd.destroyPipeline(dev, pipeline, null);
|
||||
|
||||
const pool = try gc.vkd.createCommandPool(gc.dev, &.{
|
||||
const pool = try vkd.createCommandPool(dev, &.{
|
||||
.queue_family_index = family,
|
||||
}, null);
|
||||
defer gc.vkd.destroyCommandPool(gc.dev, pool, null);
|
||||
defer vkd.destroyCommandPool(dev, pool, null);
|
||||
|
||||
const vertex_buffer = try gc.vkd.createBuffer(gc.dev, &.{
|
||||
const vertex_buffer = try vkd.createBuffer(dev, &.{
|
||||
.size = @sizeOf(@TypeOf(vertices)),
|
||||
.usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true },
|
||||
.sharing_mode = .exclusive,
|
||||
}, null);
|
||||
defer gc.vkd.destroyBuffer(gc.dev, vertex_buffer, null);
|
||||
const vertex_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, vertex_buffer);
|
||||
const vertex_memory = try gc.allocate(vertex_mem_reqs, .{ .device_local_bit = true });
|
||||
defer gc.vkd.freeMemory(gc.dev, vertex_memory, null);
|
||||
try gc.vkd.bindBufferMemory(gc.dev, vertex_buffer, vertex_memory, 0);
|
||||
defer vkd.destroyBuffer(dev, vertex_buffer, null);
|
||||
const vertex_mem_reqs = vkd.getBufferMemoryRequirements(dev, vertex_buffer);
|
||||
const vertex_memory = try allocate(pdev, vki, dev, vkd, vertex_mem_reqs, .{ .device_local_bit = true });
|
||||
defer vkd.freeMemory(dev, vertex_memory, null);
|
||||
try vkd.bindBufferMemory(dev, vertex_buffer, vertex_memory, 0);
|
||||
|
||||
try uploadData(Vertex, &gc, pool, vertex_buffer, &vertices);
|
||||
try uploadData(Vertex, pdev, vki, dev, vkd, queue, pool, vertex_buffer, &vertices);
|
||||
|
||||
const index_buffer = try gc.vkd.createBuffer(gc.dev, &.{
|
||||
const index_buffer = try vkd.createBuffer(dev, &.{
|
||||
.size = @sizeOf(@TypeOf(indices)),
|
||||
.usage = .{ .transfer_dst_bit = true, .index_buffer_bit = true },
|
||||
.sharing_mode = .exclusive,
|
||||
}, null);
|
||||
defer gc.vkd.destroyBuffer(gc.dev, index_buffer, null);
|
||||
const index_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, index_buffer);
|
||||
const index_memory = try gc.allocate(index_mem_reqs, .{ .device_local_bit = true });
|
||||
defer gc.vkd.freeMemory(gc.dev, index_memory, null);
|
||||
try gc.vkd.bindBufferMemory(gc.dev, index_buffer, index_memory, 0);
|
||||
defer vkd.destroyBuffer(dev, index_buffer, null);
|
||||
const index_mem_reqs = vkd.getBufferMemoryRequirements(dev, index_buffer);
|
||||
const index_memory = try allocate(pdev, vki, dev, vkd, index_mem_reqs, .{ .device_local_bit = true });
|
||||
defer vkd.freeMemory(dev, index_memory, null);
|
||||
try vkd.bindBufferMemory(dev, index_buffer, index_memory, 0);
|
||||
|
||||
try uploadData(Index, &gc, pool, index_buffer, &indices);
|
||||
try uploadData(Index, pdev, vki, dev, vkd, queue, pool, index_buffer, &indices);
|
||||
|
||||
var cmdbufs = try createCommandBuffers(
|
||||
&gc,
|
||||
pool,
|
||||
ally,
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
pipeline,
|
||||
swapchain,
|
||||
);
|
||||
defer destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||
// var cmdbufs = try createCommandBuffers(
|
||||
// &gc,
|
||||
// pool,
|
||||
// ally,
|
||||
// vertex_buffer,
|
||||
// index_buffer,
|
||||
// pipeline,
|
||||
// swapchain,
|
||||
// );
|
||||
// defer destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||
|
||||
while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) {
|
||||
var w: c_int = undefined;
|
||||
@@ -384,80 +384,98 @@ pub fn main() !void {
|
||||
continue;
|
||||
}
|
||||
|
||||
const cmdbuf = cmdbufs[swapchain.image_index];
|
||||
// const cmdbuf = cmdbufs[swapchain.image_index];
|
||||
|
||||
const state = swapchain.present(cmdbuf) catch |err| switch (err) {
|
||||
error.OutOfDateKHR => Swapchain.PresentState.suboptimal,
|
||||
else => |narrow| return narrow,
|
||||
};
|
||||
// const state = swapchain.present(cmdbuf) catch |err| switch (err) {
|
||||
// error.OutOfDateKHR => Swapchain.PresentState.suboptimal,
|
||||
// else => |narrow| return narrow,
|
||||
// };
|
||||
|
||||
if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) {
|
||||
extent.width = @intCast(w);
|
||||
extent.height = @intCast(h);
|
||||
try swapchain.recreate(extent, format);
|
||||
|
||||
destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||
|
||||
cmdbufs = try createCommandBuffers(
|
||||
&gc,
|
||||
pool,
|
||||
ally,
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
pipeline,
|
||||
swapchain,
|
||||
);
|
||||
}
|
||||
// if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) {
|
||||
// extent.width = @intCast(w);
|
||||
// extent.height = @intCast(h);
|
||||
// try swapchain.recreate(extent, format);
|
||||
//
|
||||
// destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||
//
|
||||
// cmdbufs = try createCommandBuffers(
|
||||
// &gc,
|
||||
// pool,
|
||||
// ally,
|
||||
// vertex_buffer,
|
||||
// index_buffer,
|
||||
// pipeline,
|
||||
// swapchain,
|
||||
// );
|
||||
// }
|
||||
|
||||
c.glfwPollEvents();
|
||||
}
|
||||
|
||||
try swapchain.waitForAllFences();
|
||||
try gc.vkd.deviceWaitIdle(gc.dev);
|
||||
// try swapchain.waitForAllFences();
|
||||
try vkd.deviceWaitIdle(dev);
|
||||
}
|
||||
|
||||
fn uploadData(comptime T: type, gc: *const Context, pool: vk.CommandPool, buffer: vk.Buffer, source: []const T) !void {
|
||||
fn uploadData(
|
||||
comptime T: type,
|
||||
pdev: vk.PhysicalDevice,
|
||||
vki: gfx.InstanceDispatch,
|
||||
dev: vk.Device,
|
||||
vkd: gfx.DeviceDispatch,
|
||||
queue: vk.Queue,
|
||||
pool: vk.CommandPool,
|
||||
buffer: vk.Buffer,
|
||||
source: []const T,
|
||||
) !void {
|
||||
// if (@typeInfo(T) == .Struct and @typeInfo(T).Struct.layout == .auto) @compileError("Requires defined T layout");
|
||||
|
||||
const size = @sizeOf(T) * source.len;
|
||||
|
||||
const staging_buffer = try gc.vkd.createBuffer(gc.dev, &.{
|
||||
const staging_buffer = try vkd.createBuffer(dev, &.{
|
||||
.size = size,
|
||||
.usage = .{ .transfer_src_bit = true },
|
||||
.sharing_mode = .exclusive,
|
||||
}, null);
|
||||
defer gc.vkd.destroyBuffer(gc.dev, staging_buffer, null);
|
||||
defer vkd.destroyBuffer(dev, staging_buffer, null);
|
||||
|
||||
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, staging_buffer);
|
||||
const staging_memory = try gc.allocate(mem_reqs, .{
|
||||
const mem_reqs = vkd.getBufferMemoryRequirements(dev, staging_buffer);
|
||||
const staging_memory = try allocate(pdev, vki, dev, vkd, mem_reqs, .{
|
||||
.host_visible_bit = true,
|
||||
.host_coherent_bit = true,
|
||||
});
|
||||
defer gc.vkd.freeMemory(gc.dev, staging_memory, null);
|
||||
defer vkd.freeMemory(dev, staging_memory, null);
|
||||
|
||||
try gc.vkd.bindBufferMemory(gc.dev, staging_buffer, staging_memory, 0);
|
||||
try vkd.bindBufferMemory(dev, staging_buffer, staging_memory, 0);
|
||||
|
||||
{
|
||||
const data = try gc.vkd.mapMemory(gc.dev, staging_memory, 0, vk.WHOLE_SIZE, .{});
|
||||
defer gc.vkd.unmapMemory(gc.dev, staging_memory);
|
||||
const data = try vkd.mapMemory(dev, staging_memory, 0, vk.WHOLE_SIZE, .{});
|
||||
defer vkd.unmapMemory(dev, staging_memory);
|
||||
|
||||
const dest: [*]T = @ptrCast(@alignCast(data));
|
||||
@memcpy(dest, source);
|
||||
}
|
||||
|
||||
try copyBuffer(gc, pool, buffer, staging_buffer, size);
|
||||
try copyBuffer(dev, queue, pool, buffer, staging_buffer, size, vkd);
|
||||
}
|
||||
|
||||
fn copyBuffer(gc: *const Context, pool: vk.CommandPool, dst: vk.Buffer, src: vk.Buffer, size: vk.DeviceSize) !void {
|
||||
fn copyBuffer(
|
||||
dev: vk.Device,
|
||||
queue: vk.Queue,
|
||||
pool: vk.CommandPool,
|
||||
dst: vk.Buffer,
|
||||
src: vk.Buffer,
|
||||
size: vk.DeviceSize,
|
||||
vkd: gfx.DeviceDispatch,
|
||||
) !void {
|
||||
var cmdbuf: vk.CommandBuffer = undefined;
|
||||
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
|
||||
try vkd.allocateCommandBuffers(dev, &.{
|
||||
.command_pool = pool,
|
||||
.level = .primary,
|
||||
.command_buffer_count = 1,
|
||||
}, @ptrCast(&cmdbuf));
|
||||
defer gc.vkd.freeCommandBuffers(gc.dev, pool, 1, @ptrCast(&cmdbuf));
|
||||
defer vkd.freeCommandBuffers(dev, pool, 1, @ptrCast(&cmdbuf));
|
||||
|
||||
try gc.vkd.beginCommandBuffer(cmdbuf, &.{
|
||||
try vkd.beginCommandBuffer(cmdbuf, &.{
|
||||
.flags = .{ .one_time_submit_bit = true },
|
||||
});
|
||||
|
||||
@@ -466,9 +484,9 @@ fn copyBuffer(gc: *const Context, pool: vk.CommandPool, dst: vk.Buffer, src: vk.
|
||||
.dst_offset = 0,
|
||||
.size = size,
|
||||
};
|
||||
gc.vkd.cmdCopyBuffer(cmdbuf, src, dst, 1, @ptrCast(®ion));
|
||||
vkd.cmdCopyBuffer(cmdbuf, src, dst, 1, @ptrCast(®ion));
|
||||
|
||||
try gc.vkd.endCommandBuffer(cmdbuf);
|
||||
try vkd.endCommandBuffer(cmdbuf);
|
||||
|
||||
const si = vk.SubmitInfo{
|
||||
.command_buffer_count = 1,
|
||||
@@ -480,165 +498,162 @@ fn copyBuffer(gc: *const Context, pool: vk.CommandPool, dst: vk.Buffer, src: vk.
|
||||
// see https://stackoverflow.com/a/62183243
|
||||
//
|
||||
// this may be a misunderstanding on how submission works...
|
||||
try gc.vkd.queueSubmit(gc.queue, 1, @ptrCast(&si), .null_handle);
|
||||
try gc.vkd.queueWaitIdle(gc.queue);
|
||||
try vkd.queueSubmit(queue, 1, @ptrCast(&si), .null_handle);
|
||||
try vkd.queueWaitIdle(queue);
|
||||
}
|
||||
|
||||
fn createCommandBuffers(
|
||||
gc: *const Context,
|
||||
pool: vk.CommandPool,
|
||||
allocator: Allocator,
|
||||
vertex_buffer: vk.Buffer,
|
||||
index_buffer: vk.Buffer,
|
||||
pipeline: vk.Pipeline,
|
||||
swapchain: Swapchain,
|
||||
) ![]vk.CommandBuffer {
|
||||
const extent = swapchain.extent;
|
||||
// fn createCommandBuffers(
|
||||
// pool: vk.CommandPool,
|
||||
// allocator: Allocator,
|
||||
// vertex_buffer: vk.Buffer,
|
||||
// index_buffer: vk.Buffer,
|
||||
// pipeline: vk.Pipeline,
|
||||
// extent: vk.Extent2D,
|
||||
// ) ![]vk.CommandBuffer {
|
||||
// const cmdbufs = try allocator.alloc(vk.CommandBuffer, swapchain.swap_images.len);
|
||||
// errdefer allocator.free(cmdbufs);
|
||||
//
|
||||
// try vkd.allocateCommandBuffers(dev, &.{
|
||||
// .command_pool = pool,
|
||||
// .level = .primary,
|
||||
// .command_buffer_count = @as(u32, @truncate(cmdbufs.len)),
|
||||
// }, cmdbufs.ptr);
|
||||
// errdefer vkd.freeCommandBuffers(dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
||||
//
|
||||
// const clear = vk.ClearValue{
|
||||
// .color = .{ .float_32 = .{ 0, 0, 0, 1 } },
|
||||
// };
|
||||
//
|
||||
// const viewport = vk.Viewport{
|
||||
// .x = 0,
|
||||
// .y = 0,
|
||||
// .width = @as(f32, @floatFromInt(extent.width)),
|
||||
// .height = @as(f32, @floatFromInt(extent.height)),
|
||||
// .min_depth = 0,
|
||||
// .max_depth = 1,
|
||||
// };
|
||||
//
|
||||
// const scissor = vk.Rect2D{
|
||||
// .offset = .{ .x = 0, .y = 0 },
|
||||
// .extent = extent,
|
||||
// };
|
||||
//
|
||||
// for (cmdbufs, swapchain.swap_images) |cmdbuf, image| {
|
||||
// try vkd.beginCommandBuffer(cmdbuf, &.{});
|
||||
//
|
||||
// vkd.cmdPipelineBarrier(
|
||||
// cmdbuf,
|
||||
// .{ .top_of_pipe_bit = true },
|
||||
// .{ .color_attachment_output_bit = true },
|
||||
// .{},
|
||||
// 0,
|
||||
// null,
|
||||
// 0,
|
||||
// null,
|
||||
// 1,
|
||||
// @ptrCast(&vk.ImageMemoryBarrier{
|
||||
// .src_access_mask = .{},
|
||||
// .dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||
// .old_layout = .undefined,
|
||||
// .new_layout = .color_attachment_optimal,
|
||||
// .src_queue_family_index = 0,
|
||||
// .dst_queue_family_index = 0,
|
||||
// .image = image.image,
|
||||
// .subresource_range = .{
|
||||
// .aspect_mask = .{ .color_bit = true },
|
||||
// .base_mip_level = 0,
|
||||
// .level_count = 1,
|
||||
// .base_array_layer = 0,
|
||||
// .layer_count = 1,
|
||||
// },
|
||||
// }),
|
||||
// );
|
||||
//
|
||||
// vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
|
||||
// vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
|
||||
//
|
||||
// const color_attachments = [_]vk.RenderingAttachmentInfoKHR{
|
||||
// .{
|
||||
// .image_view = image.view,
|
||||
// .image_layout = .color_attachment_optimal,
|
||||
// .resolve_mode = .{},
|
||||
// .resolve_image_view = .null_handle,
|
||||
// .resolve_image_layout = .undefined,
|
||||
// .load_op = .clear,
|
||||
// .store_op = .store,
|
||||
// .clear_value = clear,
|
||||
// },
|
||||
// };
|
||||
//
|
||||
// const render_info = vk.RenderingInfoKHR{
|
||||
// .render_area = scissor, // since we always do full-frame changes
|
||||
// .layer_count = 1,
|
||||
// .view_mask = 0,
|
||||
// .color_attachment_count = color_attachments.len,
|
||||
// .p_color_attachments = &color_attachments,
|
||||
// };
|
||||
//
|
||||
// vkd.cmdBeginRenderingKHR(cmdbuf, &render_info);
|
||||
//
|
||||
// vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline);
|
||||
// const offset = [_]vk.DeviceSize{0};
|
||||
// vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&vertex_buffer), &offset);
|
||||
// vkd.cmdBindIndexBuffer(cmdbuf, index_buffer, 0, .uint16);
|
||||
// vkd.cmdDrawIndexed(cmdbuf, indices.len, 1, 0, 0, 0);
|
||||
//
|
||||
// vkd.cmdEndRenderingKHR(cmdbuf);
|
||||
//
|
||||
// vkd.cmdPipelineBarrier(
|
||||
// cmdbuf,
|
||||
// .{ .color_attachment_output_bit = true },
|
||||
// .{ .bottom_of_pipe_bit = true },
|
||||
// .{},
|
||||
// 0,
|
||||
// null,
|
||||
// 0,
|
||||
// null,
|
||||
// 1,
|
||||
// @ptrCast(&vk.ImageMemoryBarrier{
|
||||
// .src_access_mask = .{ .color_attachment_write_bit = true },
|
||||
// .dst_access_mask = .{},
|
||||
// .old_layout = .color_attachment_optimal,
|
||||
// .new_layout = .present_src_khr,
|
||||
// .src_queue_family_index = 0,
|
||||
// .dst_queue_family_index = 0,
|
||||
// .image = image.image,
|
||||
// .subresource_range = .{
|
||||
// .aspect_mask = .{ .color_bit = true },
|
||||
// .base_mip_level = 0,
|
||||
// .level_count = 1,
|
||||
// .base_array_layer = 0,
|
||||
// .layer_count = 1,
|
||||
// },
|
||||
// }),
|
||||
// );
|
||||
//
|
||||
// try vkd.endCommandBuffer(cmdbuf);
|
||||
// }
|
||||
//
|
||||
// return cmdbufs;
|
||||
// }
|
||||
|
||||
const cmdbufs = try allocator.alloc(vk.CommandBuffer, swapchain.swap_images.len);
|
||||
errdefer allocator.free(cmdbufs);
|
||||
// fn destroyCommandBuffers(gc: *const Context, pool: vk.CommandPool, allocator: Allocator, cmdbufs: []vk.CommandBuffer) void {
|
||||
// vkd.freeCommandBuffers(dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
||||
// allocator.free(cmdbufs);
|
||||
// }
|
||||
|
||||
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
|
||||
.command_pool = pool,
|
||||
.level = .primary,
|
||||
.command_buffer_count = @as(u32, @truncate(cmdbufs.len)),
|
||||
}, cmdbufs.ptr);
|
||||
errdefer gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
||||
|
||||
const clear = vk.ClearValue{
|
||||
.color = .{ .float_32 = .{ 0, 0, 0, 1 } },
|
||||
};
|
||||
|
||||
const viewport = vk.Viewport{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = @as(f32, @floatFromInt(extent.width)),
|
||||
.height = @as(f32, @floatFromInt(extent.height)),
|
||||
.min_depth = 0,
|
||||
.max_depth = 1,
|
||||
};
|
||||
|
||||
const scissor = vk.Rect2D{
|
||||
.offset = .{ .x = 0, .y = 0 },
|
||||
.extent = extent,
|
||||
};
|
||||
|
||||
for (cmdbufs, swapchain.swap_images) |cmdbuf, image| {
|
||||
try gc.vkd.beginCommandBuffer(cmdbuf, &.{});
|
||||
|
||||
gc.vkd.cmdPipelineBarrier(
|
||||
cmdbuf,
|
||||
.{ .top_of_pipe_bit = true },
|
||||
.{ .color_attachment_output_bit = true },
|
||||
.{},
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
@ptrCast(&vk.ImageMemoryBarrier{
|
||||
.src_access_mask = .{},
|
||||
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||
.old_layout = .undefined,
|
||||
.new_layout = .color_attachment_optimal,
|
||||
.src_queue_family_index = 0,
|
||||
.dst_queue_family_index = 0,
|
||||
.image = image.image,
|
||||
.subresource_range = .{
|
||||
.aspect_mask = .{ .color_bit = true },
|
||||
.base_mip_level = 0,
|
||||
.level_count = 1,
|
||||
.base_array_layer = 0,
|
||||
.layer_count = 1,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
|
||||
gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
|
||||
|
||||
const color_attachments = [_]vk.RenderingAttachmentInfoKHR{
|
||||
.{
|
||||
.image_view = image.view,
|
||||
.image_layout = .color_attachment_optimal,
|
||||
.resolve_mode = .{},
|
||||
.resolve_image_view = .null_handle,
|
||||
.resolve_image_layout = .undefined,
|
||||
.load_op = .clear,
|
||||
.store_op = .store,
|
||||
.clear_value = clear,
|
||||
},
|
||||
};
|
||||
|
||||
const render_info = vk.RenderingInfoKHR{
|
||||
.render_area = scissor, // since we always do full-frame changes
|
||||
.layer_count = 1,
|
||||
.view_mask = 0,
|
||||
.color_attachment_count = color_attachments.len,
|
||||
.p_color_attachments = &color_attachments,
|
||||
};
|
||||
|
||||
gc.vkd.cmdBeginRenderingKHR(cmdbuf, &render_info);
|
||||
|
||||
gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline);
|
||||
const offset = [_]vk.DeviceSize{0};
|
||||
gc.vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&vertex_buffer), &offset);
|
||||
gc.vkd.cmdBindIndexBuffer(cmdbuf, index_buffer, 0, .uint16);
|
||||
gc.vkd.cmdDrawIndexed(cmdbuf, indices.len, 1, 0, 0, 0);
|
||||
|
||||
gc.vkd.cmdEndRenderingKHR(cmdbuf);
|
||||
|
||||
gc.vkd.cmdPipelineBarrier(
|
||||
cmdbuf,
|
||||
.{ .color_attachment_output_bit = true },
|
||||
.{ .bottom_of_pipe_bit = true },
|
||||
.{},
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
@ptrCast(&vk.ImageMemoryBarrier{
|
||||
.src_access_mask = .{ .color_attachment_write_bit = true },
|
||||
.dst_access_mask = .{},
|
||||
.old_layout = .color_attachment_optimal,
|
||||
.new_layout = .present_src_khr,
|
||||
.src_queue_family_index = 0,
|
||||
.dst_queue_family_index = 0,
|
||||
.image = image.image,
|
||||
.subresource_range = .{
|
||||
.aspect_mask = .{ .color_bit = true },
|
||||
.base_mip_level = 0,
|
||||
.level_count = 1,
|
||||
.base_array_layer = 0,
|
||||
.layer_count = 1,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
try gc.vkd.endCommandBuffer(cmdbuf);
|
||||
}
|
||||
|
||||
return cmdbufs;
|
||||
}
|
||||
|
||||
fn destroyCommandBuffers(gc: *const Context, pool: vk.CommandPool, allocator: Allocator, cmdbufs: []vk.CommandBuffer) void {
|
||||
gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
||||
allocator.free(cmdbufs);
|
||||
}
|
||||
|
||||
fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, format: vk.SurfaceFormatKHR) !vk.Pipeline {
|
||||
const vert = try gc.vkd.createShaderModule(gc.dev, &.{
|
||||
fn createPipeline(dev: vk.Device, layout: vk.PipelineLayout, format: vk.SurfaceFormatKHR, vkd: gfx.DeviceDispatch) !vk.Pipeline {
|
||||
const vert = try vkd.createShaderModule(dev, &.{
|
||||
.code_size = shaders.triangle_vert.len,
|
||||
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),
|
||||
}, null);
|
||||
defer gc.vkd.destroyShaderModule(gc.dev, vert, null);
|
||||
defer vkd.destroyShaderModule(dev, vert, null);
|
||||
|
||||
const frag = try gc.vkd.createShaderModule(gc.dev, &.{
|
||||
const frag = try vkd.createShaderModule(dev, &.{
|
||||
.code_size = shaders.triangle_frag.len,
|
||||
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_frag)),
|
||||
}, null);
|
||||
defer gc.vkd.destroyShaderModule(gc.dev, frag, null);
|
||||
defer vkd.destroyShaderModule(dev, frag, null);
|
||||
|
||||
const pssci = [_]vk.PipelineShaderStageCreateInfo{
|
||||
.{
|
||||
@@ -653,46 +668,6 @@ fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, format: vk.Surf
|
||||
},
|
||||
};
|
||||
|
||||
const pvisci = vk.PipelineVertexInputStateCreateInfo{
|
||||
.vertex_binding_description_count = 1,
|
||||
.p_vertex_binding_descriptions = @ptrCast(&Vertex.binding_description),
|
||||
.vertex_attribute_description_count = Vertex.attribute_description.len,
|
||||
.p_vertex_attribute_descriptions = &Vertex.attribute_description,
|
||||
};
|
||||
|
||||
const piasci = vk.PipelineInputAssemblyStateCreateInfo{
|
||||
.topology = .triangle_list,
|
||||
.primitive_restart_enable = vk.FALSE,
|
||||
};
|
||||
|
||||
const pvsci = vk.PipelineViewportStateCreateInfo{
|
||||
.viewport_count = 1,
|
||||
.p_viewports = undefined, // set in createCommandBuffers with cmdSetViewport
|
||||
.scissor_count = 1,
|
||||
.p_scissors = undefined, // set in createCommandBuffers with cmdSetScissor
|
||||
};
|
||||
|
||||
const prsci = vk.PipelineRasterizationStateCreateInfo{
|
||||
.depth_clamp_enable = vk.FALSE,
|
||||
.rasterizer_discard_enable = vk.FALSE,
|
||||
.polygon_mode = .fill,
|
||||
.cull_mode = .{ .back_bit = true },
|
||||
.front_face = .counter_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{
|
||||
.rasterization_samples = .{ .@"1_bit" = true },
|
||||
.sample_shading_enable = vk.FALSE,
|
||||
.min_sample_shading = 1,
|
||||
.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,
|
||||
@@ -704,58 +679,107 @@ fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, format: vk.Surf
|
||||
.color_write_mask = .{ .r_bit = true, .g_bit = true, .b_bit = true, .a_bit = true },
|
||||
};
|
||||
|
||||
const pcbsci = vk.PipelineColorBlendStateCreateInfo{
|
||||
.logic_op_enable = vk.FALSE,
|
||||
.logic_op = .copy,
|
||||
.attachment_count = 1,
|
||||
.p_attachments = @ptrCast(&pcbas),
|
||||
.blend_constants = [_]f32{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
const dynstate = [_]vk.DynamicState{ .viewport, .scissor };
|
||||
const pdsci = vk.PipelineDynamicStateCreateInfo{
|
||||
.flags = .{},
|
||||
.dynamic_state_count = dynstate.len,
|
||||
.p_dynamic_states = &dynstate,
|
||||
};
|
||||
|
||||
const prci = vk.PipelineRenderingCreateInfoKHR{
|
||||
.color_attachment_count = 1,
|
||||
.p_color_attachment_formats = @ptrCast(&format),
|
||||
.depth_attachment_format = .undefined,
|
||||
.stencil_attachment_format = .undefined,
|
||||
.view_mask = 0,
|
||||
};
|
||||
|
||||
const gpci = vk.GraphicsPipelineCreateInfo{
|
||||
.flags = .{},
|
||||
.stage_count = 2,
|
||||
.stage_count = @intCast(pssci.len),
|
||||
.p_stages = &pssci,
|
||||
.p_vertex_input_state = &pvisci,
|
||||
.p_input_assembly_state = &piasci,
|
||||
.p_vertex_input_state = &vk.PipelineVertexInputStateCreateInfo{
|
||||
.vertex_binding_description_count = 1,
|
||||
.p_vertex_binding_descriptions = @ptrCast(&Vertex.binding_description),
|
||||
.vertex_attribute_description_count = Vertex.attribute_description.len,
|
||||
.p_vertex_attribute_descriptions = &Vertex.attribute_description,
|
||||
},
|
||||
.p_input_assembly_state = &vk.PipelineInputAssemblyStateCreateInfo{
|
||||
.topology = .triangle_list,
|
||||
.primitive_restart_enable = vk.FALSE,
|
||||
},
|
||||
.p_tessellation_state = null,
|
||||
.p_viewport_state = &pvsci,
|
||||
.p_rasterization_state = &prsci,
|
||||
.p_multisample_state = &pmsci,
|
||||
.p_viewport_state = &vk.PipelineViewportStateCreateInfo{
|
||||
.viewport_count = 1,
|
||||
.p_viewports = undefined, // set in createCommandBuffers with cmdSetViewport
|
||||
.scissor_count = 1,
|
||||
.p_scissors = undefined, // set in createCommandBuffers with cmdSetScissor
|
||||
},
|
||||
.p_rasterization_state = &vk.PipelineRasterizationStateCreateInfo{
|
||||
.depth_clamp_enable = vk.FALSE,
|
||||
.rasterizer_discard_enable = vk.FALSE,
|
||||
.polygon_mode = .fill,
|
||||
.cull_mode = .{ .back_bit = true },
|
||||
.front_face = .counter_clockwise,
|
||||
.depth_bias_enable = vk.FALSE,
|
||||
.depth_bias_constant_factor = 0,
|
||||
.depth_bias_clamp = 0,
|
||||
.depth_bias_slope_factor = 0,
|
||||
.line_width = 1,
|
||||
},
|
||||
.p_multisample_state = &vk.PipelineMultisampleStateCreateInfo{
|
||||
.rasterization_samples = .{ .@"1_bit" = true },
|
||||
.sample_shading_enable = vk.FALSE,
|
||||
.min_sample_shading = 1,
|
||||
.alpha_to_coverage_enable = vk.FALSE,
|
||||
.alpha_to_one_enable = vk.FALSE,
|
||||
},
|
||||
.p_depth_stencil_state = null,
|
||||
.p_color_blend_state = &pcbsci,
|
||||
.p_dynamic_state = &pdsci,
|
||||
.p_color_blend_state = &vk.PipelineColorBlendStateCreateInfo{
|
||||
.logic_op_enable = vk.FALSE,
|
||||
.logic_op = .copy,
|
||||
.attachment_count = 1,
|
||||
.p_attachments = @ptrCast(&pcbas),
|
||||
.blend_constants = [_]f32{ 0, 0, 0, 0 },
|
||||
},
|
||||
.p_dynamic_state = &vk.PipelineDynamicStateCreateInfo{
|
||||
.flags = .{},
|
||||
.dynamic_state_count = dynstate.len,
|
||||
.p_dynamic_states = &dynstate,
|
||||
},
|
||||
.layout = layout,
|
||||
.render_pass = .null_handle,
|
||||
.subpass = 0,
|
||||
.base_pipeline_handle = .null_handle,
|
||||
.base_pipeline_index = -1,
|
||||
.p_next = &prci,
|
||||
.p_next = &vk.PipelineRenderingCreateInfoKHR{
|
||||
.color_attachment_count = 1,
|
||||
.p_color_attachment_formats = @ptrCast(&format),
|
||||
.depth_attachment_format = .undefined,
|
||||
.stencil_attachment_format = .undefined,
|
||||
.view_mask = 0,
|
||||
},
|
||||
};
|
||||
|
||||
var pipeline: vk.Pipeline = undefined;
|
||||
_ = try gc.vkd.createGraphicsPipelines(
|
||||
gc.dev,
|
||||
.null_handle,
|
||||
1,
|
||||
@ptrCast(&gpci),
|
||||
null,
|
||||
@ptrCast(&pipeline),
|
||||
);
|
||||
_ = try vkd.createGraphicsPipelines(dev, .null_handle, 1, @ptrCast(&gpci), null, @ptrCast(&pipeline));
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
pub fn findMemoryTypeIndex(
|
||||
pdev: vk.PhysicalDevice,
|
||||
memory_type_bits: u32,
|
||||
flags: vk.MemoryPropertyFlags,
|
||||
vki: gfx.InstanceDispatch,
|
||||
) !u32 {
|
||||
const mem_props = vki.getPhysicalDeviceMemoryProperties(pdev);
|
||||
|
||||
for (mem_props.memory_types[0..mem_props.memory_type_count], 0..) |mem_type, i| {
|
||||
if (memory_type_bits & (@as(u32, 1) << @truncate(i)) != 0 and mem_type.property_flags.contains(flags)) {
|
||||
return @truncate(i);
|
||||
}
|
||||
}
|
||||
|
||||
return error.NoSuitableMemoryType;
|
||||
}
|
||||
|
||||
pub fn allocate(
|
||||
pdev: vk.PhysicalDevice,
|
||||
vki: gfx.InstanceDispatch,
|
||||
dev: vk.Device,
|
||||
vkd: gfx.DeviceDispatch,
|
||||
requirements: vk.MemoryRequirements,
|
||||
flags: vk.MemoryPropertyFlags,
|
||||
) !vk.DeviceMemory {
|
||||
return try vkd.allocateMemory(dev, &.{
|
||||
.allocation_size = requirements.size,
|
||||
.memory_type_index = try findMemoryTypeIndex(pdev, requirements.memory_type_bits, flags, vki),
|
||||
}, null);
|
||||
}
|
||||
|
@@ -14,33 +14,6 @@ pub const Context = struct {
|
||||
|
||||
queue: vk.Queue,
|
||||
family: u32,
|
||||
|
||||
pub fn findMemoryTypeIndex(
|
||||
self: @This(),
|
||||
memory_type_bits: u32,
|
||||
flags: vk.MemoryPropertyFlags,
|
||||
) !u32 {
|
||||
const mem_props = self.vki.getPhysicalDeviceMemoryProperties(self.pdev);
|
||||
|
||||
for (mem_props.memory_types[0..mem_props.memory_type_count], 0..) |mem_type, i| {
|
||||
if (memory_type_bits & (@as(u32, 1) << @truncate(i)) != 0 and mem_type.property_flags.contains(flags)) {
|
||||
return @truncate(i);
|
||||
}
|
||||
}
|
||||
|
||||
return error.NoSuitableMemoryType;
|
||||
}
|
||||
|
||||
pub fn allocate(
|
||||
self: @This(),
|
||||
requirements: vk.MemoryRequirements,
|
||||
flags: vk.MemoryPropertyFlags,
|
||||
) !vk.DeviceMemory {
|
||||
return try self.vkd.allocateMemory(self.dev, &.{
|
||||
.allocation_size = requirements.size,
|
||||
.memory_type_index = try self.findMemoryTypeIndex(requirements.memory_type_bits, flags),
|
||||
}, null);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Swapchain = struct {
|
||||
|
Reference in New Issue
Block a user