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 vk = @import("vk");
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
const shaders = @import("shaders");
|
const shaders = @import("shaders");
|
||||||
const Swapchain = @import("swapchain.zig").Swapchain;
|
|
||||||
const Context = @import("swapchain.zig").Context;
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const gfx = @import("gfx.zig");
|
const gfx = @import("gfx.zig");
|
||||||
@@ -298,80 +296,82 @@ pub fn main() !void {
|
|||||||
try create_device(ally, instance, surface, vki);
|
try create_device(ally, instance, surface, vki);
|
||||||
defer vkd.destroyDevice(dev, null);
|
defer vkd.destroyDevice(dev, null);
|
||||||
|
|
||||||
|
const queue = vkd.getDeviceQueue(dev, family, 0);
|
||||||
|
|
||||||
const preferred_format: vk.SurfaceFormatKHR = .{
|
const preferred_format: vk.SurfaceFormatKHR = .{
|
||||||
.format = .b8g8r8a8_srgb,
|
.format = .b8g8r8a8_srgb,
|
||||||
.color_space = .srgb_nonlinear_khr,
|
.color_space = .srgb_nonlinear_khr,
|
||||||
};
|
};
|
||||||
const format = try find_surface_format(pdev, surface, preferred_format, vki);
|
const format = try find_surface_format(pdev, surface, preferred_format, vki);
|
||||||
|
|
||||||
const queue = vkd.getDeviceQueue(dev, family, 0);
|
_ = &extent;
|
||||||
|
|
||||||
const gc: Context = .{
|
// const gc: Context = .{
|
||||||
.vki = vki,
|
// .vki = vki,
|
||||||
.vkd = vkd,
|
// .vkd = vkd,
|
||||||
.pdev = pdev,
|
// .pdev = pdev,
|
||||||
.dev = dev,
|
// .dev = dev,
|
||||||
.surface = surface,
|
// .surface = surface,
|
||||||
.queue = queue,
|
// .queue = queue,
|
||||||
.family = family,
|
// .family = family,
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
|
// var swapchain = try Swapchain.init(&gc, ally, extent, format);
|
||||||
|
// defer swapchain.deinit();
|
||||||
|
|
||||||
var swapchain = try Swapchain.init(&gc, ally, extent, format);
|
const pipeline_layout = try vkd.createPipelineLayout(dev, &.{
|
||||||
defer swapchain.deinit();
|
|
||||||
|
|
||||||
const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{
|
|
||||||
.flags = .{},
|
.flags = .{},
|
||||||
.set_layout_count = 0,
|
.set_layout_count = 0,
|
||||||
.p_set_layouts = undefined,
|
.p_set_layouts = undefined,
|
||||||
.push_constant_range_count = 0,
|
.push_constant_range_count = 0,
|
||||||
.p_push_constant_ranges = undefined,
|
.p_push_constant_ranges = undefined,
|
||||||
}, null);
|
}, 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);
|
const pipeline = try createPipeline(dev, pipeline_layout, format, vkd);
|
||||||
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
|
defer vkd.destroyPipeline(dev, pipeline, null);
|
||||||
|
|
||||||
const pool = try gc.vkd.createCommandPool(gc.dev, &.{
|
const pool = try vkd.createCommandPool(dev, &.{
|
||||||
.queue_family_index = family,
|
.queue_family_index = family,
|
||||||
}, null);
|
}, 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)),
|
.size = @sizeOf(@TypeOf(vertices)),
|
||||||
.usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true },
|
.usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true },
|
||||||
.sharing_mode = .exclusive,
|
.sharing_mode = .exclusive,
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyBuffer(gc.dev, vertex_buffer, null);
|
defer vkd.destroyBuffer(dev, vertex_buffer, null);
|
||||||
const vertex_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, vertex_buffer);
|
const vertex_mem_reqs = vkd.getBufferMemoryRequirements(dev, vertex_buffer);
|
||||||
const vertex_memory = try gc.allocate(vertex_mem_reqs, .{ .device_local_bit = true });
|
const vertex_memory = try allocate(pdev, vki, dev, vkd, vertex_mem_reqs, .{ .device_local_bit = true });
|
||||||
defer gc.vkd.freeMemory(gc.dev, vertex_memory, null);
|
defer vkd.freeMemory(dev, vertex_memory, null);
|
||||||
try gc.vkd.bindBufferMemory(gc.dev, vertex_buffer, vertex_memory, 0);
|
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)),
|
.size = @sizeOf(@TypeOf(indices)),
|
||||||
.usage = .{ .transfer_dst_bit = true, .index_buffer_bit = true },
|
.usage = .{ .transfer_dst_bit = true, .index_buffer_bit = true },
|
||||||
.sharing_mode = .exclusive,
|
.sharing_mode = .exclusive,
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyBuffer(gc.dev, index_buffer, null);
|
defer vkd.destroyBuffer(dev, index_buffer, null);
|
||||||
const index_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, index_buffer);
|
const index_mem_reqs = vkd.getBufferMemoryRequirements(dev, index_buffer);
|
||||||
const index_memory = try gc.allocate(index_mem_reqs, .{ .device_local_bit = true });
|
const index_memory = try allocate(pdev, vki, dev, vkd, index_mem_reqs, .{ .device_local_bit = true });
|
||||||
defer gc.vkd.freeMemory(gc.dev, index_memory, null);
|
defer vkd.freeMemory(dev, index_memory, null);
|
||||||
try gc.vkd.bindBufferMemory(gc.dev, index_buffer, index_memory, 0);
|
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(
|
// var cmdbufs = try createCommandBuffers(
|
||||||
&gc,
|
// &gc,
|
||||||
pool,
|
// pool,
|
||||||
ally,
|
// ally,
|
||||||
vertex_buffer,
|
// vertex_buffer,
|
||||||
index_buffer,
|
// index_buffer,
|
||||||
pipeline,
|
// pipeline,
|
||||||
swapchain,
|
// swapchain,
|
||||||
);
|
// );
|
||||||
defer destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
// defer destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||||
|
|
||||||
while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) {
|
while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) {
|
||||||
var w: c_int = undefined;
|
var w: c_int = undefined;
|
||||||
@@ -384,80 +384,98 @@ pub fn main() !void {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmdbuf = cmdbufs[swapchain.image_index];
|
// const cmdbuf = cmdbufs[swapchain.image_index];
|
||||||
|
|
||||||
const state = swapchain.present(cmdbuf) catch |err| switch (err) {
|
// const state = swapchain.present(cmdbuf) catch |err| switch (err) {
|
||||||
error.OutOfDateKHR => Swapchain.PresentState.suboptimal,
|
// error.OutOfDateKHR => Swapchain.PresentState.suboptimal,
|
||||||
else => |narrow| return narrow,
|
// else => |narrow| return narrow,
|
||||||
};
|
// };
|
||||||
|
|
||||||
if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) {
|
// if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) {
|
||||||
extent.width = @intCast(w);
|
// extent.width = @intCast(w);
|
||||||
extent.height = @intCast(h);
|
// extent.height = @intCast(h);
|
||||||
try swapchain.recreate(extent, format);
|
// try swapchain.recreate(extent, format);
|
||||||
|
//
|
||||||
destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
// destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||||
|
//
|
||||||
cmdbufs = try createCommandBuffers(
|
// cmdbufs = try createCommandBuffers(
|
||||||
&gc,
|
// &gc,
|
||||||
pool,
|
// pool,
|
||||||
ally,
|
// ally,
|
||||||
vertex_buffer,
|
// vertex_buffer,
|
||||||
index_buffer,
|
// index_buffer,
|
||||||
pipeline,
|
// pipeline,
|
||||||
swapchain,
|
// swapchain,
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
c.glfwPollEvents();
|
c.glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
try swapchain.waitForAllFences();
|
// try swapchain.waitForAllFences();
|
||||||
try gc.vkd.deviceWaitIdle(gc.dev);
|
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");
|
// if (@typeInfo(T) == .Struct and @typeInfo(T).Struct.layout == .auto) @compileError("Requires defined T layout");
|
||||||
|
|
||||||
const size = @sizeOf(T) * source.len;
|
const size = @sizeOf(T) * source.len;
|
||||||
|
|
||||||
const staging_buffer = try gc.vkd.createBuffer(gc.dev, &.{
|
const staging_buffer = try vkd.createBuffer(dev, &.{
|
||||||
.size = size,
|
.size = size,
|
||||||
.usage = .{ .transfer_src_bit = true },
|
.usage = .{ .transfer_src_bit = true },
|
||||||
.sharing_mode = .exclusive,
|
.sharing_mode = .exclusive,
|
||||||
}, null);
|
}, 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 mem_reqs = vkd.getBufferMemoryRequirements(dev, staging_buffer);
|
||||||
const staging_memory = try gc.allocate(mem_reqs, .{
|
const staging_memory = try allocate(pdev, vki, dev, vkd, mem_reqs, .{
|
||||||
.host_visible_bit = true,
|
.host_visible_bit = true,
|
||||||
.host_coherent_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, .{});
|
const data = try vkd.mapMemory(dev, staging_memory, 0, vk.WHOLE_SIZE, .{});
|
||||||
defer gc.vkd.unmapMemory(gc.dev, staging_memory);
|
defer vkd.unmapMemory(dev, staging_memory);
|
||||||
|
|
||||||
const dest: [*]T = @ptrCast(@alignCast(data));
|
const dest: [*]T = @ptrCast(@alignCast(data));
|
||||||
@memcpy(dest, source);
|
@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;
|
var cmdbuf: vk.CommandBuffer = undefined;
|
||||||
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
|
try vkd.allocateCommandBuffers(dev, &.{
|
||||||
.command_pool = pool,
|
.command_pool = pool,
|
||||||
.level = .primary,
|
.level = .primary,
|
||||||
.command_buffer_count = 1,
|
.command_buffer_count = 1,
|
||||||
}, @ptrCast(&cmdbuf));
|
}, @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 },
|
.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,
|
.dst_offset = 0,
|
||||||
.size = size,
|
.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{
|
const si = vk.SubmitInfo{
|
||||||
.command_buffer_count = 1,
|
.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
|
// see https://stackoverflow.com/a/62183243
|
||||||
//
|
//
|
||||||
// this may be a misunderstanding on how submission works...
|
// this may be a misunderstanding on how submission works...
|
||||||
try gc.vkd.queueSubmit(gc.queue, 1, @ptrCast(&si), .null_handle);
|
try vkd.queueSubmit(queue, 1, @ptrCast(&si), .null_handle);
|
||||||
try gc.vkd.queueWaitIdle(gc.queue);
|
try vkd.queueWaitIdle(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createCommandBuffers(
|
// fn createCommandBuffers(
|
||||||
gc: *const Context,
|
// pool: vk.CommandPool,
|
||||||
pool: vk.CommandPool,
|
// allocator: Allocator,
|
||||||
allocator: Allocator,
|
// vertex_buffer: vk.Buffer,
|
||||||
vertex_buffer: vk.Buffer,
|
// index_buffer: vk.Buffer,
|
||||||
index_buffer: vk.Buffer,
|
// pipeline: vk.Pipeline,
|
||||||
pipeline: vk.Pipeline,
|
// extent: vk.Extent2D,
|
||||||
swapchain: Swapchain,
|
// ) ![]vk.CommandBuffer {
|
||||||
) ![]vk.CommandBuffer {
|
// const cmdbufs = try allocator.alloc(vk.CommandBuffer, swapchain.swap_images.len);
|
||||||
const extent = swapchain.extent;
|
// 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);
|
// fn destroyCommandBuffers(gc: *const Context, pool: vk.CommandPool, allocator: Allocator, cmdbufs: []vk.CommandBuffer) void {
|
||||||
errdefer allocator.free(cmdbufs);
|
// vkd.freeCommandBuffers(dev, pool, @truncate(cmdbufs.len), cmdbufs.ptr);
|
||||||
|
// allocator.free(cmdbufs);
|
||||||
|
// }
|
||||||
|
|
||||||
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
|
fn createPipeline(dev: vk.Device, layout: vk.PipelineLayout, format: vk.SurfaceFormatKHR, vkd: gfx.DeviceDispatch) !vk.Pipeline {
|
||||||
.command_pool = pool,
|
const vert = try vkd.createShaderModule(dev, &.{
|
||||||
.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, &.{
|
|
||||||
.code_size = shaders.triangle_vert.len,
|
.code_size = shaders.triangle_vert.len,
|
||||||
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),
|
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),
|
||||||
}, null);
|
}, 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,
|
.code_size = shaders.triangle_frag.len,
|
||||||
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_frag)),
|
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_frag)),
|
||||||
}, null);
|
}, null);
|
||||||
defer gc.vkd.destroyShaderModule(gc.dev, frag, null);
|
defer vkd.destroyShaderModule(dev, frag, null);
|
||||||
|
|
||||||
const pssci = [_]vk.PipelineShaderStageCreateInfo{
|
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{
|
const pcbas = vk.PipelineColorBlendAttachmentState{
|
||||||
.blend_enable = vk.FALSE,
|
.blend_enable = vk.FALSE,
|
||||||
.src_color_blend_factor = .one,
|
.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 },
|
.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 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{
|
const gpci = vk.GraphicsPipelineCreateInfo{
|
||||||
.flags = .{},
|
.flags = .{},
|
||||||
.stage_count = 2,
|
.stage_count = @intCast(pssci.len),
|
||||||
.p_stages = &pssci,
|
.p_stages = &pssci,
|
||||||
.p_vertex_input_state = &pvisci,
|
.p_vertex_input_state = &vk.PipelineVertexInputStateCreateInfo{
|
||||||
.p_input_assembly_state = &piasci,
|
.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_tessellation_state = null,
|
||||||
.p_viewport_state = &pvsci,
|
.p_viewport_state = &vk.PipelineViewportStateCreateInfo{
|
||||||
.p_rasterization_state = &prsci,
|
.viewport_count = 1,
|
||||||
.p_multisample_state = &pmsci,
|
.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_depth_stencil_state = null,
|
||||||
.p_color_blend_state = &pcbsci,
|
.p_color_blend_state = &vk.PipelineColorBlendStateCreateInfo{
|
||||||
.p_dynamic_state = &pdsci,
|
.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,
|
.layout = layout,
|
||||||
.render_pass = .null_handle,
|
.render_pass = .null_handle,
|
||||||
.subpass = 0,
|
.subpass = 0,
|
||||||
.base_pipeline_handle = .null_handle,
|
.base_pipeline_handle = .null_handle,
|
||||||
.base_pipeline_index = -1,
|
.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;
|
var pipeline: vk.Pipeline = undefined;
|
||||||
_ = try gc.vkd.createGraphicsPipelines(
|
_ = try vkd.createGraphicsPipelines(dev, .null_handle, 1, @ptrCast(&gpci), null, @ptrCast(&pipeline));
|
||||||
gc.dev,
|
|
||||||
.null_handle,
|
|
||||||
1,
|
|
||||||
@ptrCast(&gpci),
|
|
||||||
null,
|
|
||||||
@ptrCast(&pipeline),
|
|
||||||
);
|
|
||||||
return 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,
|
queue: vk.Queue,
|
||||||
family: u32,
|
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 {
|
pub const Swapchain = struct {
|
||||||
|
Reference in New Issue
Block a user