Vertical movement, deinit logs, persistent global uniform transfers
This commit is contained in:
180
src/Game.zig
180
src/Game.zig
@@ -10,6 +10,7 @@ const Materials = @import("assets/Materials.zig");
|
|||||||
const Textures = @import("assets/Textures.zig");
|
const Textures = @import("assets/Textures.zig");
|
||||||
const Engine = @import("engine/Engine.zig");
|
const Engine = @import("engine/Engine.zig");
|
||||||
const GenericBuffer = @import("engine/GenericBuffer.zig").GenericBuffer;
|
const GenericBuffer = @import("engine/GenericBuffer.zig").GenericBuffer;
|
||||||
|
const StagingBuffer = @import("engine/StagingBuffer.zig");
|
||||||
const Swapchain = @import("engine/Swapchain.zig");
|
const Swapchain = @import("engine/Swapchain.zig");
|
||||||
const Iterator3 = math.Iterator3;
|
const Iterator3 = math.Iterator3;
|
||||||
const Matrix4x4 = math.Matrix4x4;
|
const Matrix4x4 = math.Matrix4x4;
|
||||||
@@ -113,6 +114,9 @@ vertex_buffer: VertexBuffer,
|
|||||||
index_buffer: IndexBuffer,
|
index_buffer: IndexBuffer,
|
||||||
|
|
||||||
global_uniforms: GlobalUniformsBuffer,
|
global_uniforms: GlobalUniformsBuffer,
|
||||||
|
global_uniforms_staging_buffer: StagingBuffer,
|
||||||
|
global_uniforms_transfer_command_buffer: vk.CommandBuffer,
|
||||||
|
global_uniforms_transfer_semaphore: vk.Semaphore,
|
||||||
point_lights: PointLightBuffer,
|
point_lights: PointLightBuffer,
|
||||||
directional_lights: DirectionalLightBuffer,
|
directional_lights: DirectionalLightBuffer,
|
||||||
object_uniforms: ObjectUniformsBuffer,
|
object_uniforms: ObjectUniformsBuffer,
|
||||||
@@ -130,6 +134,8 @@ input_forwards: bool = false,
|
|||||||
input_backwards: bool = false,
|
input_backwards: bool = false,
|
||||||
input_left: bool = false,
|
input_left: bool = false,
|
||||||
input_right: bool = false,
|
input_right: bool = false,
|
||||||
|
input_up: bool = false,
|
||||||
|
input_down: bool = false,
|
||||||
|
|
||||||
const max_textures = 1024;
|
const max_textures = 1024;
|
||||||
const max_point_lights = 1024;
|
const max_point_lights = 1024;
|
||||||
@@ -139,9 +145,10 @@ const max_objects = 1024;
|
|||||||
const camera_near_plane = 0.1;
|
const camera_near_plane = 0.1;
|
||||||
const camera_vertical_fov_deg = 90.0;
|
const camera_vertical_fov_deg = 90.0;
|
||||||
const camera_half_vertical_fov_rad = 0.5 * camera_vertical_fov_deg * std.math.rad_per_deg;
|
const camera_half_vertical_fov_rad = 0.5 * camera_vertical_fov_deg * std.math.rad_per_deg;
|
||||||
const camera_mouse_sensitivity = 0.0015;
|
const camera_mouse_sensitivity = 0.002;
|
||||||
|
|
||||||
const player_speed = 5.0;
|
const player_horizontal_speed = 11.0;
|
||||||
|
const player_vertical_speed = 7.49;
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain) !Game {
|
pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain) !Game {
|
||||||
var materials = try Materials.init(engine, allocator);
|
var materials = try Materials.init(engine, allocator);
|
||||||
@@ -295,6 +302,33 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
});
|
});
|
||||||
errdefer global_uniforms.deinit(engine);
|
errdefer global_uniforms.deinit(engine);
|
||||||
|
|
||||||
|
var global_uniforms_staging_buffer = try StagingBuffer.init(engine, .{
|
||||||
|
.capacity = @sizeOf(GlobalUniforms),
|
||||||
|
.target_queue = .graphics,
|
||||||
|
});
|
||||||
|
errdefer global_uniforms_staging_buffer.deinit(engine);
|
||||||
|
|
||||||
|
const global_uniforms_transfer_command_buffer = try engine.allocateTransferCommandBuffer();
|
||||||
|
errdefer engine.freeTransferCommandBuffer(global_uniforms_transfer_command_buffer);
|
||||||
|
|
||||||
|
try global_uniforms_transfer_command_buffer.beginCommandBuffer(&.{});
|
||||||
|
global_uniforms_transfer_command_buffer.copyBuffer(
|
||||||
|
global_uniforms_staging_buffer.buffer,
|
||||||
|
global_uniforms.buffer,
|
||||||
|
1,
|
||||||
|
&.{
|
||||||
|
.{
|
||||||
|
.src_offset = 0,
|
||||||
|
.dst_offset = 0,
|
||||||
|
.size = @sizeOf(GlobalUniforms),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
try global_uniforms_transfer_command_buffer.endCommandBuffer();
|
||||||
|
|
||||||
|
const global_uniforms_transfer_semaphore = try engine.createSemaphore();
|
||||||
|
errdefer engine.destroySemaphore(global_uniforms_transfer_semaphore);
|
||||||
|
|
||||||
var point_lights = try PointLightBuffer.init(engine, .{
|
var point_lights = try PointLightBuffer.init(engine, .{
|
||||||
.usage = .storage,
|
.usage = .storage,
|
||||||
.target_queue = .graphics,
|
.target_queue = .graphics,
|
||||||
@@ -550,6 +584,44 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const point_lights_data: []const PointLight = &.{
|
||||||
|
.{
|
||||||
|
.positionWS = .{ 0, 0, 1 },
|
||||||
|
.color = .{ 10, 10, 10 },
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.positionWS = .{ -7, 7, 1 },
|
||||||
|
.color = .{ 5, 0, 0 },
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.positionWS = .{ 7, 7, 1 },
|
||||||
|
.color = .{ 0, 0, 5 },
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.positionWS = .{ -7, -7, 1 },
|
||||||
|
.color = .{ 0, 5, 0 },
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.positionWS = .{ 7, -7, 1 },
|
||||||
|
.color = .{ 5, 5, 0 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
try point_lights.write(engine, .{
|
||||||
|
.header = @intCast(point_lights_data.len),
|
||||||
|
.elements = point_lights_data,
|
||||||
|
});
|
||||||
|
|
||||||
|
const directional_lights_data: []const DirectionalLight = &.{
|
||||||
|
.{
|
||||||
|
.directionWS = .{ 0, 0, -1 },
|
||||||
|
.color = .{ 0.2, 0.2, 0.2 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
try directional_lights.write(engine, .{
|
||||||
|
.header = @intCast(directional_lights_data.len),
|
||||||
|
.elements = directional_lights_data,
|
||||||
|
});
|
||||||
|
|
||||||
const object_count: u32 = blk: {
|
const object_count: u32 = blk: {
|
||||||
var objects: std.ArrayList(ObjectUniforms) = try .initCapacity(allocator, 289);
|
var objects: std.ArrayList(ObjectUniforms) = try .initCapacity(allocator, 289);
|
||||||
defer objects.deinit(allocator);
|
defer objects.deinit(allocator);
|
||||||
@@ -585,6 +657,9 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
.index_buffer = index_buffer,
|
.index_buffer = index_buffer,
|
||||||
|
|
||||||
.global_uniforms = global_uniforms,
|
.global_uniforms = global_uniforms,
|
||||||
|
.global_uniforms_staging_buffer = global_uniforms_staging_buffer,
|
||||||
|
.global_uniforms_transfer_command_buffer = global_uniforms_transfer_command_buffer.handle,
|
||||||
|
.global_uniforms_transfer_semaphore = global_uniforms_transfer_semaphore,
|
||||||
.point_lights = point_lights,
|
.point_lights = point_lights,
|
||||||
.directional_lights = directional_lights,
|
.directional_lights = directional_lights,
|
||||||
.object_uniforms = object_uniforms,
|
.object_uniforms = object_uniforms,
|
||||||
@@ -597,14 +672,18 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Game) void {
|
pub fn deinit(self: *Game) void {
|
||||||
|
std.log.debug("Deinitializing {*}", .{self});
|
||||||
|
|
||||||
self.vertex_buffer.deinit(self.engine);
|
self.vertex_buffer.deinit(self.engine);
|
||||||
self.index_buffer.deinit(self.engine);
|
self.index_buffer.deinit(self.engine);
|
||||||
|
|
||||||
self.global_uniforms.deinit(self.engine);
|
self.global_uniforms.deinit(self.engine);
|
||||||
|
self.global_uniforms_staging_buffer.deinit(self.engine);
|
||||||
self.point_lights.deinit(self.engine);
|
self.point_lights.deinit(self.engine);
|
||||||
self.directional_lights.deinit(self.engine);
|
self.directional_lights.deinit(self.engine);
|
||||||
self.object_uniforms.deinit(self.engine);
|
self.object_uniforms.deinit(self.engine);
|
||||||
|
|
||||||
|
self.engine.destroySemaphore(self.global_uniforms_transfer_semaphore);
|
||||||
self.engine.destroyDescriptorPool(self.descriptor_pool);
|
self.engine.destroyDescriptorPool(self.descriptor_pool);
|
||||||
self.engine.destroySampler(self.sampler);
|
self.engine.destroySampler(self.sampler);
|
||||||
self.engine.destroyPipeline(self.pipeline);
|
self.engine.destroyPipeline(self.pipeline);
|
||||||
@@ -618,12 +697,17 @@ pub fn deinit(self: *Game) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(self: *Game, dt: f32) void {
|
pub fn update(self: *Game, dt: f32) void {
|
||||||
var camera_d = Vector2.init(
|
const camera_d = Vector2
|
||||||
@as(f32, @floatFromInt(@intFromBool(self.input_right))) - @as(f32, @floatFromInt(@intFromBool(self.input_left))),
|
.init(
|
||||||
@as(f32, @floatFromInt(@intFromBool(self.input_forwards))) - @as(f32, @floatFromInt(@intFromBool(self.input_backwards))),
|
@as(f32, @floatFromInt(@intFromBool(self.input_right))) - @as(f32, @floatFromInt(@intFromBool(self.input_left))),
|
||||||
).rotate(self.camera_yaw).mulScalar(player_speed * dt);
|
@as(f32, @floatFromInt(@intFromBool(self.input_forwards))) - @as(f32, @floatFromInt(@intFromBool(self.input_backwards))),
|
||||||
|
)
|
||||||
|
.rotate(self.camera_yaw)
|
||||||
|
.mulScalar(player_horizontal_speed)
|
||||||
|
.asVector3(player_vertical_speed * (@as(f32, @floatFromInt(@intFromBool(self.input_up))) - @as(f32, @floatFromInt(@intFromBool(self.input_down)))))
|
||||||
|
.mulScalar(dt);
|
||||||
|
|
||||||
self.camera_position = Vector3.add(self.camera_position, camera_d.asVector3(0));
|
self.camera_position = Vector3.add(self.camera_position, camera_d);
|
||||||
|
|
||||||
const framebuffer_size = Vector2.init(
|
const framebuffer_size = Vector2.init(
|
||||||
@floatFromInt(self.swapchain.extent.width),
|
@floatFromInt(self.swapchain.extent.width),
|
||||||
@@ -654,58 +738,30 @@ pub fn update(self: *Game, dt: f32) void {
|
|||||||
|
|
||||||
const ambient_light = Vector3.init(0.1, 0.1, 0.1);
|
const ambient_light = Vector3.init(0.1, 0.1, 0.1);
|
||||||
|
|
||||||
self.global_uniforms.write(self.engine, .{
|
const global_uniforms_data: GlobalUniforms = .{
|
||||||
.header = .{
|
.matrixWStoVS = matrix_ws_to_vs.asArray(),
|
||||||
.matrixWStoVS = matrix_ws_to_vs.asArray(),
|
.matrixVStoCS = matrix_vs_to_cs.asArray(),
|
||||||
.matrixVStoCS = matrix_vs_to_cs.asArray(),
|
.ambientLight = ambient_light.asArray(),
|
||||||
.ambientLight = ambient_light.asArray(),
|
|
||||||
},
|
|
||||||
}) catch |err| {
|
|
||||||
std.log.err("Failed to write global uniforms: {s}", .{@errorName(err)});
|
|
||||||
@panic("Frame update failed");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const point_lights: []const PointLight = &.{
|
const staging_memory = self.global_uniforms_staging_buffer.map(self.engine) catch |err| {
|
||||||
.{
|
std.log.err("Failed to map global uniforms staging buffer: {s}", .{@errorName(err)});
|
||||||
.positionWS = .{ 0, 0, 1 },
|
|
||||||
.color = .{ 10, 10, 10 },
|
|
||||||
},
|
|
||||||
.{
|
|
||||||
.positionWS = .{ -7, 7, 1 },
|
|
||||||
.color = .{ 5, 0, 0 },
|
|
||||||
},
|
|
||||||
.{
|
|
||||||
.positionWS = .{ 7, 7, 1 },
|
|
||||||
.color = .{ 0, 0, 5 },
|
|
||||||
},
|
|
||||||
.{
|
|
||||||
.positionWS = .{ -7, -7, 1 },
|
|
||||||
.color = .{ 0, 5, 0 },
|
|
||||||
},
|
|
||||||
.{
|
|
||||||
.positionWS = .{ 7, -7, 1 },
|
|
||||||
.color = .{ 5, 5, 0 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
self.point_lights.write(self.engine, .{
|
|
||||||
.header = @intCast(point_lights.len),
|
|
||||||
.elements = point_lights,
|
|
||||||
}) catch |err| {
|
|
||||||
std.log.err("Failed to write point lights: {s}", .{@errorName(err)});
|
|
||||||
@panic("Frame update failed");
|
@panic("Frame update failed");
|
||||||
};
|
};
|
||||||
|
@memcpy(staging_memory, std.mem.asBytes(&global_uniforms_data));
|
||||||
|
self.global_uniforms_staging_buffer.unmap(self.engine);
|
||||||
|
|
||||||
const directional_lights: []const DirectionalLight = &.{
|
const submits = [_]vk.SubmitInfo{
|
||||||
.{
|
.{
|
||||||
.directionWS = .{ 0, 0, -1 },
|
.command_buffer_count = 1,
|
||||||
.color = .{ 0.2, 0.2, 0.2 },
|
.p_command_buffers = @ptrCast(&self.global_uniforms_transfer_command_buffer),
|
||||||
|
.signal_semaphore_count = 1,
|
||||||
|
.p_signal_semaphores = @ptrCast(&self.global_uniforms_transfer_semaphore),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.directional_lights.write(self.engine, .{
|
|
||||||
.header = @intCast(directional_lights.len),
|
self.engine.device.queueSubmit(self.engine.transfer_queue.handle, submits.len, &submits, .null_handle) catch |err| {
|
||||||
.elements = directional_lights,
|
std.log.err("Failed to submit global uniforms transfer: {s}", .{@errorName(err)});
|
||||||
}) catch |err| {
|
|
||||||
std.log.err("Failed to write directional lights: {s}", .{@errorName(err)});
|
|
||||||
@panic("Frame update failed");
|
@panic("Frame update failed");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -738,6 +794,12 @@ pub fn onKeyDown(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
|
|||||||
self.input_right = true;
|
self.input_right = true;
|
||||||
self.input_left = false;
|
self.input_left = false;
|
||||||
}
|
}
|
||||||
|
if (key_code == .space) {
|
||||||
|
self.input_up = true;
|
||||||
|
}
|
||||||
|
if (key_code == .left_shift) {
|
||||||
|
self.input_down = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onKeyUp(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
|
pub fn onKeyUp(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
|
||||||
@@ -755,6 +817,12 @@ pub fn onKeyUp(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
|
|||||||
if (key_code == .d) {
|
if (key_code == .d) {
|
||||||
self.input_right = false;
|
self.input_right = false;
|
||||||
}
|
}
|
||||||
|
if (key_code == .space) {
|
||||||
|
self.input_up = false;
|
||||||
|
}
|
||||||
|
if (key_code == .left_shift) {
|
||||||
|
self.input_down = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onMouseMove(self: *Game, dx: f32, dy: f32) void {
|
pub fn onMouseMove(self: *Game, dx: f32, dy: f32) void {
|
||||||
@@ -820,7 +888,15 @@ fn render(self: *Game) !void {
|
|||||||
}
|
}
|
||||||
try command_buffer.endCommandBuffer();
|
try command_buffer.endCommandBuffer();
|
||||||
|
|
||||||
const res = try self.swapchain.present(self.engine, command_buffer.handle);
|
const res = try self.swapchain.present(self.engine, .{
|
||||||
|
.command_buffer = command_buffer.handle,
|
||||||
|
.wait_semaphores = &.{
|
||||||
|
.{
|
||||||
|
.semaphore = self.global_uniforms_transfer_semaphore,
|
||||||
|
.stage_flags = .{ .vertex_shader_bit = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
_ = res;
|
_ = res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ pub fn init(engine: *Engine, allocator: std.mem.Allocator) !Materials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Materials, engine: *Engine, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Materials, engine: *Engine, allocator: std.mem.Allocator) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*} and Allocator{{{*},{*}}}", .{ self, engine, allocator.ptr, allocator.vtable });
|
||||||
|
|
||||||
self.material_buffer.deinit(engine);
|
self.material_buffer.deinit(engine);
|
||||||
self.map.deinit(allocator);
|
self.map.deinit(allocator);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ pub fn init(engine: *Engine, allocator: std.mem.Allocator) !Textures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Textures, engine: *Engine, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Textures, engine: *Engine, allocator: std.mem.Allocator) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*} and Allocator{{{*},{*}}}", .{ self, engine, allocator.ptr, allocator.vtable });
|
||||||
|
|
||||||
for (self.textures.items) |*texture| {
|
for (self.textures.items) |*texture| {
|
||||||
texture.deinit(engine);
|
texture.deinit(engine);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ pub const Mode = union(enum) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
pub fn deinit(self: *Mode, instance: vk.InstanceProxy, vk_allocator: *VkAllocator) void {
|
pub fn deinit(self: *Mode, instance: vk.InstanceProxy, vk_allocator: *VkAllocator) void {
|
||||||
|
std.log.debug("Deinitializing {*} with InstanceProxy@{{{X},{*}}} and {*}", .{ self, instance.handle, instance.wrapper, vk_allocator });
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.headless => {},
|
.headless => {},
|
||||||
.surface => |x| {
|
.surface => |x| {
|
||||||
@@ -103,6 +104,7 @@ transfer_queue: Queue,
|
|||||||
graphics_command_pool: vk.CommandPool,
|
graphics_command_pool: vk.CommandPool,
|
||||||
compute_command_pool: vk.CommandPool,
|
compute_command_pool: vk.CommandPool,
|
||||||
transfer_command_pool: vk.CommandPool,
|
transfer_command_pool: vk.CommandPool,
|
||||||
|
transient_transfer_command_pool: vk.CommandPool,
|
||||||
|
|
||||||
prng_ptr: *std.Random.Pcg,
|
prng_ptr: *std.Random.Pcg,
|
||||||
random: std.Random,
|
random: std.Random,
|
||||||
@@ -320,29 +322,27 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
|||||||
|
|
||||||
// --- CREATE COMMAND POOLS, GET QUEUES ------------------------------------
|
// --- CREATE COMMAND POOLS, GET QUEUES ------------------------------------
|
||||||
|
|
||||||
const command_pool_create_flags: vk.CommandPoolCreateFlags = .{
|
|
||||||
.transient_bit = true,
|
|
||||||
.reset_command_buffer_bit = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const graphics_command_pool = try device.createCommandPool(&.{
|
const graphics_command_pool = try device.createCommandPool(&.{
|
||||||
.flags = command_pool_create_flags,
|
|
||||||
.queue_family_index = queue_allocations.graphics_queue.family,
|
.queue_family_index = queue_allocations.graphics_queue.family,
|
||||||
}, &vk_allocator.interface);
|
}, &vk_allocator.interface);
|
||||||
errdefer device.destroyCommandPool(graphics_command_pool, &vk_allocator.interface);
|
errdefer device.destroyCommandPool(graphics_command_pool, &vk_allocator.interface);
|
||||||
|
|
||||||
const compute_command_pool = try device.createCommandPool(&.{
|
const compute_command_pool = try device.createCommandPool(&.{
|
||||||
.flags = command_pool_create_flags,
|
|
||||||
.queue_family_index = queue_allocations.compute_queue.family,
|
.queue_family_index = queue_allocations.compute_queue.family,
|
||||||
}, &vk_allocator.interface);
|
}, &vk_allocator.interface);
|
||||||
errdefer device.destroyCommandPool(compute_command_pool, &vk_allocator.interface);
|
errdefer device.destroyCommandPool(compute_command_pool, &vk_allocator.interface);
|
||||||
|
|
||||||
const transfer_command_pool = try device.createCommandPool(&.{
|
const transfer_command_pool = try device.createCommandPool(&.{
|
||||||
.flags = command_pool_create_flags,
|
|
||||||
.queue_family_index = queue_allocations.transfer_queue.family,
|
.queue_family_index = queue_allocations.transfer_queue.family,
|
||||||
}, &vk_allocator.interface);
|
}, &vk_allocator.interface);
|
||||||
errdefer device.destroyCommandPool(transfer_command_pool, &vk_allocator.interface);
|
errdefer device.destroyCommandPool(transfer_command_pool, &vk_allocator.interface);
|
||||||
|
|
||||||
|
const transient_transfer_command_pool = try device.createCommandPool(&.{
|
||||||
|
.flags = .{ .transient_bit = true },
|
||||||
|
.queue_family_index = queue_allocations.transfer_queue.family,
|
||||||
|
}, &vk_allocator.interface);
|
||||||
|
errdefer device.destroyCommandPool(transient_transfer_command_pool, &vk_allocator.interface);
|
||||||
|
|
||||||
const graphics_queue: Queue = .initAllocation(device, queue_allocations.graphics_queue);
|
const graphics_queue: Queue = .initAllocation(device, queue_allocations.graphics_queue);
|
||||||
const compute_queue: Queue = .initAllocation(device, queue_allocations.compute_queue);
|
const compute_queue: Queue = .initAllocation(device, queue_allocations.compute_queue);
|
||||||
const transfer_queue: Queue = .initAllocation(device, queue_allocations.transfer_queue);
|
const transfer_queue: Queue = .initAllocation(device, queue_allocations.transfer_queue);
|
||||||
@@ -383,6 +383,7 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
|||||||
.graphics_command_pool = graphics_command_pool,
|
.graphics_command_pool = graphics_command_pool,
|
||||||
.compute_command_pool = compute_command_pool,
|
.compute_command_pool = compute_command_pool,
|
||||||
.transfer_command_pool = transfer_command_pool,
|
.transfer_command_pool = transfer_command_pool,
|
||||||
|
.transient_transfer_command_pool = transient_transfer_command_pool,
|
||||||
|
|
||||||
.prng_ptr = prng_ptr,
|
.prng_ptr = prng_ptr,
|
||||||
.random = random,
|
.random = random,
|
||||||
@@ -390,6 +391,8 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Engine) void {
|
pub fn deinit(self: *Engine) void {
|
||||||
|
std.log.debug("Deinitializing {*}", .{self});
|
||||||
|
|
||||||
const allocator = self.vk_allocator.allocator;
|
const allocator = self.vk_allocator.allocator;
|
||||||
|
|
||||||
allocator.destroy(self.prng_ptr);
|
allocator.destroy(self.prng_ptr);
|
||||||
@@ -397,6 +400,7 @@ pub fn deinit(self: *Engine) void {
|
|||||||
self.device.destroyCommandPool(self.graphics_command_pool, &self.vk_allocator.interface);
|
self.device.destroyCommandPool(self.graphics_command_pool, &self.vk_allocator.interface);
|
||||||
self.device.destroyCommandPool(self.compute_command_pool, &self.vk_allocator.interface);
|
self.device.destroyCommandPool(self.compute_command_pool, &self.vk_allocator.interface);
|
||||||
self.device.destroyCommandPool(self.transfer_command_pool, &self.vk_allocator.interface);
|
self.device.destroyCommandPool(self.transfer_command_pool, &self.vk_allocator.interface);
|
||||||
|
self.device.destroyCommandPool(self.transient_transfer_command_pool, &self.vk_allocator.interface);
|
||||||
|
|
||||||
self.device.destroyDevice(&self.vk_allocator.interface);
|
self.device.destroyDevice(&self.vk_allocator.interface);
|
||||||
allocator.destroy(self.device.wrapper);
|
allocator.destroy(self.device.wrapper);
|
||||||
@@ -433,6 +437,16 @@ pub fn allocate(self: *const Engine, memory_requirements: vk.MemoryRequirements,
|
|||||||
return error.NoSuitableMemoryType;
|
return error.NoSuitableMemoryType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn allocateTransientTransferCommandBuffer(self: *const Engine) !vk.CommandBufferProxy {
|
||||||
|
var command_buffer: vk.CommandBuffer = undefined;
|
||||||
|
try self.device.allocateCommandBuffers(&.{
|
||||||
|
.command_pool = self.transient_transfer_command_pool,
|
||||||
|
.level = .primary,
|
||||||
|
.command_buffer_count = 1,
|
||||||
|
}, @ptrCast(&command_buffer));
|
||||||
|
return .init(command_buffer, self.device.wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn allocateTransferCommandBuffer(self: *const Engine) !vk.CommandBufferProxy {
|
pub fn allocateTransferCommandBuffer(self: *const Engine) !vk.CommandBufferProxy {
|
||||||
var command_buffer: vk.CommandBuffer = undefined;
|
var command_buffer: vk.CommandBuffer = undefined;
|
||||||
try self.device.allocateCommandBuffers(&.{
|
try self.device.allocateCommandBuffers(&.{
|
||||||
@@ -457,6 +471,10 @@ pub fn freeTransferCommandBuffer(self: *const Engine, command_buffer: vk.Command
|
|||||||
self.device.freeCommandBuffers(self.transfer_command_pool, 1, @ptrCast(&command_buffer));
|
self.device.freeCommandBuffers(self.transfer_command_pool, 1, @ptrCast(&command_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn freeTransientTransferCommandBuffer(self: *const Engine, command_buffer: vk.CommandBufferProxy) void {
|
||||||
|
self.device.freeCommandBuffers(self.transient_transfer_command_pool, 1, @ptrCast(&command_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn freeGraphicsCommandBuffer(self: *const Engine, command_buffer: vk.CommandBufferProxy) void {
|
pub fn freeGraphicsCommandBuffer(self: *const Engine, command_buffer: vk.CommandBufferProxy) void {
|
||||||
self.device.freeCommandBuffers(self.graphics_command_pool, 1, @ptrCast(&command_buffer));
|
self.device.freeCommandBuffers(self.graphics_command_pool, 1, @ptrCast(&command_buffer));
|
||||||
}
|
}
|
||||||
@@ -1125,5 +1143,5 @@ pub fn updateDescriptorSets(self: *Engine, update_info: DescriptorSetsUpdateInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn waitForFence(self: *Engine, fence: vk.Fence) !void {
|
pub fn waitForFence(self: *Engine, fence: vk.Fence) !void {
|
||||||
_ = try self.device.waitForFences(1, @ptrCast(&fence), .true, std.math.maxInt(u64));
|
_ = try self.device.waitForFences(1, @ptrCast(&fence), .true, 1 * std.time.ns_per_s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self, engine: *Engine) void {
|
pub fn deinit(self: *Self, engine: *Engine) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
|
||||||
|
|
||||||
engine.freeMemory(self.device_memory);
|
engine.freeMemory(self.device_memory);
|
||||||
engine.destroyBuffer(self.buffer);
|
engine.destroyBuffer(self.buffer);
|
||||||
|
|
||||||
@@ -144,8 +146,8 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
|
|||||||
@memcpy(staging_memory[array_write_offset..write_size], std.mem.sliceAsBytes(write_info.elements));
|
@memcpy(staging_memory[array_write_offset..write_size], std.mem.sliceAsBytes(write_info.elements));
|
||||||
staging_buffer.unmap(engine);
|
staging_buffer.unmap(engine);
|
||||||
|
|
||||||
const command_buffer = try engine.allocateTransferCommandBuffer();
|
const command_buffer = try engine.allocateTransientTransferCommandBuffer();
|
||||||
defer engine.freeTransferCommandBuffer(command_buffer);
|
defer engine.freeTransientTransferCommandBuffer(command_buffer);
|
||||||
|
|
||||||
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||||
command_buffer.copyBuffer(
|
command_buffer.copyBuffer(
|
||||||
@@ -188,8 +190,8 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
|
|||||||
@memcpy(staging_memory, data);
|
@memcpy(staging_memory, data);
|
||||||
staging_buffer.unmap(engine);
|
staging_buffer.unmap(engine);
|
||||||
|
|
||||||
const command_buffer = try engine.allocateTransferCommandBuffer();
|
const command_buffer = try engine.allocateTransientTransferCommandBuffer();
|
||||||
defer engine.freeTransferCommandBuffer(command_buffer);
|
defer engine.freeTransientTransferCommandBuffer(command_buffer);
|
||||||
|
|
||||||
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||||
command_buffer.copyBuffer(
|
command_buffer.copyBuffer(
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ pub fn init(engine: *Engine, init_info: InitInfo) !StagingBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *StagingBuffer, engine: *Engine) void {
|
pub fn deinit(self: *StagingBuffer, engine: *Engine) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
|
||||||
|
|
||||||
engine.freeMemory(self.device_memory);
|
engine.freeMemory(self.device_memory);
|
||||||
engine.destroyBuffer(self.buffer);
|
engine.destroyBuffer(self.buffer);
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ pub fn init(engine: *Engine) !Swapchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Swapchain, engine: *Engine) void {
|
pub fn deinit(self: *Swapchain, engine: *Engine) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
|
||||||
|
|
||||||
const allocator = engine.vk_allocator.allocator;
|
const allocator = engine.vk_allocator.allocator;
|
||||||
|
|
||||||
for (self.swapchain_images) |swapchain_image| {
|
for (self.swapchain_images) |swapchain_image| {
|
||||||
@@ -197,7 +199,18 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
self.semaphore_image_acquired = semaphore_image_acquired;
|
self.semaphore_image_acquired = semaphore_image_acquired;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn present(self: *Swapchain, engine: *Engine, command_buffer: vk.CommandBuffer) !PresentResult {
|
pub const WaitSemaphore = struct {
|
||||||
|
semaphore: vk.Semaphore,
|
||||||
|
stage_flags: vk.PipelineStageFlags = .{ .top_of_pipe_bit = true },
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PresentInfo = struct {
|
||||||
|
command_buffer: vk.CommandBuffer,
|
||||||
|
wait_semaphores: []const WaitSemaphore,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !PresentResult {
|
||||||
|
const allocator = engine.vk_allocator.allocator;
|
||||||
const device = engine.device;
|
const device = engine.device;
|
||||||
const mode = &engine.mode.surface;
|
const mode = &engine.mode.surface;
|
||||||
|
|
||||||
@@ -213,28 +226,30 @@ pub fn present(self: *Swapchain, engine: *Engine, command_buffer: vk.CommandBuff
|
|||||||
|
|
||||||
// --- SUBMIT COMMAND BUFFER -----------------------------------------------
|
// --- SUBMIT COMMAND BUFFER -----------------------------------------------
|
||||||
|
|
||||||
const wait_semaphores = [_]vk.Semaphore{
|
var wait_semaphores = std.MultiArrayList(WaitSemaphore){};
|
||||||
current_swapchain_image.semaphore_image_acquired,
|
defer wait_semaphores.deinit(allocator);
|
||||||
};
|
try wait_semaphores.ensureTotalCapacity(allocator, 1 + present_info.wait_semaphores.len);
|
||||||
|
|
||||||
const pipeline_stages_flags = [_]vk.PipelineStageFlags{
|
wait_semaphores.appendAssumeCapacity(.{
|
||||||
.{ .top_of_pipe_bit = true },
|
.semaphore = current_swapchain_image.semaphore_image_acquired,
|
||||||
};
|
.stage_flags = .{ .top_of_pipe_bit = true },
|
||||||
|
});
|
||||||
std.debug.assert(wait_semaphores.len == pipeline_stages_flags.len);
|
for (present_info.wait_semaphores) |wait_semaphore| {
|
||||||
|
wait_semaphores.appendAssumeCapacity(wait_semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
const signal_semaphores = [_]vk.Semaphore{
|
const signal_semaphores = [_]vk.Semaphore{
|
||||||
current_swapchain_image.semaphore_render_finished,
|
current_swapchain_image.semaphore_render_finished,
|
||||||
};
|
};
|
||||||
|
|
||||||
current_swapchain_image.command_buffer = command_buffer;
|
current_swapchain_image.command_buffer = present_info.command_buffer;
|
||||||
try device.queueSubmit(engine.graphics_queue.handle, 1, &.{
|
try device.queueSubmit(engine.graphics_queue.handle, 1, &.{
|
||||||
.{
|
.{
|
||||||
.wait_semaphore_count = wait_semaphores.len,
|
.wait_semaphore_count = @intCast(wait_semaphores.len),
|
||||||
.p_wait_semaphores = &wait_semaphores,
|
.p_wait_semaphores = wait_semaphores.items(.semaphore).ptr,
|
||||||
.p_wait_dst_stage_mask = &pipeline_stages_flags,
|
.p_wait_dst_stage_mask = wait_semaphores.items(.stage_flags).ptr,
|
||||||
.command_buffer_count = 1,
|
.command_buffer_count = 1,
|
||||||
.p_command_buffers = @ptrCast(&command_buffer),
|
.p_command_buffers = @ptrCast(&present_info.command_buffer),
|
||||||
.signal_semaphore_count = signal_semaphores.len,
|
.signal_semaphore_count = signal_semaphores.len,
|
||||||
.p_signal_semaphores = &signal_semaphores,
|
.p_signal_semaphores = &signal_semaphores,
|
||||||
},
|
},
|
||||||
@@ -393,6 +408,8 @@ const SwapchainImage = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: SwapchainImage, engine: *Engine) void {
|
fn deinit(self: SwapchainImage, engine: *Engine) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*}", .{ &self, engine });
|
||||||
|
|
||||||
engine.waitForFence(self.fence) catch {};
|
engine.waitForFence(self.fence) catch {};
|
||||||
engine.destroyFramebuffer(self.framebuffer);
|
engine.destroyFramebuffer(self.framebuffer);
|
||||||
engine.destroyFence(self.fence);
|
engine.destroyFence(self.fence);
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Texture, engine: *Engine) void {
|
pub fn deinit(self: *Texture, engine: *Engine) void {
|
||||||
|
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
|
||||||
|
|
||||||
engine.destroyImageView(self.image_view);
|
engine.destroyImageView(self.image_view);
|
||||||
engine.freeMemory(self.device_memory);
|
engine.freeMemory(self.device_memory);
|
||||||
engine.destroyImage(self.image);
|
engine.destroyImage(self.image);
|
||||||
@@ -178,8 +180,8 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
|
|||||||
|
|
||||||
// --- TRANSITION TO TRANSFER_DST_OPTIMAL AND COPY -----------------
|
// --- TRANSITION TO TRANSFER_DST_OPTIMAL AND COPY -----------------
|
||||||
|
|
||||||
const transfer_command_buffer = try engine.allocateTransferCommandBuffer();
|
const transfer_command_buffer = try engine.allocateTransientTransferCommandBuffer();
|
||||||
defer engine.freeTransferCommandBuffer(transfer_command_buffer);
|
defer engine.freeTransientTransferCommandBuffer(transfer_command_buffer);
|
||||||
|
|
||||||
try transfer_command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
try transfer_command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *VkAllocator) void {
|
pub fn deinit(self: *VkAllocator) void {
|
||||||
|
std.log.debug("Deinitializing {*}", .{self});
|
||||||
|
|
||||||
const allocator = self.allocator;
|
const allocator = self.allocator;
|
||||||
|
|
||||||
self.allocations.deinit(allocator);
|
self.allocations.deinit(allocator);
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ pub fn init(_allocator: std.mem.Allocator) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
|
std.log.debug("Deinitializing atoms", .{});
|
||||||
|
|
||||||
string_arena.deinit();
|
string_arena.deinit();
|
||||||
map.deinit(allocator);
|
map.deinit(allocator);
|
||||||
array.deinit(allocator);
|
array.deinit(allocator);
|
||||||
|
|||||||
@@ -80,8 +80,13 @@ pub fn main() !void {
|
|||||||
t1 = t2;
|
t1 = t2;
|
||||||
|
|
||||||
game.update(dt);
|
game.update(dt);
|
||||||
std.Thread.sleep(1 * std.time.ns_per_ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std.log.debug("Exitted the game loop", .{});
|
||||||
|
std.posix.abort();
|
||||||
|
|
||||||
|
//for (swapchain.swapchain_images) |x| engine.waitForFence(x.fence) catch {};
|
||||||
|
//engine.device.deviceWaitIdle() catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const CallbackContext = struct {
|
const CallbackContext = struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user