Introduce depth buffer finally
This commit is contained in:
31
src/Game.zig
31
src/Game.zig
@@ -441,6 +441,17 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
.alpha_to_coverage_enable = .false,
|
.alpha_to_coverage_enable = .false,
|
||||||
.alpha_to_one_enable = .false,
|
.alpha_to_one_enable = .false,
|
||||||
},
|
},
|
||||||
|
.depth_stencil_state = .{
|
||||||
|
.depth_test_enable = .true,
|
||||||
|
.depth_write_enable = .true,
|
||||||
|
.depth_compare_op = .greater,
|
||||||
|
.depth_bounds_test_enable = .false,
|
||||||
|
.stencil_test_enable = .false,
|
||||||
|
.front = undefined,
|
||||||
|
.back = undefined,
|
||||||
|
.min_depth_bounds = 0,
|
||||||
|
.max_depth_bounds = 1,
|
||||||
|
},
|
||||||
.color_blend_state = .{
|
.color_blend_state = .{
|
||||||
.logic_op_enable = .false,
|
.logic_op_enable = .false,
|
||||||
.logic_op = .copy,
|
.logic_op = .copy,
|
||||||
@@ -639,10 +650,10 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
});
|
});
|
||||||
|
|
||||||
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, 578);
|
||||||
defer objects.deinit(allocator);
|
defer objects.deinit(allocator);
|
||||||
|
|
||||||
var it = Iterator3.init(.init(-8, -8, 0), .init(8, 8, 0), .one);
|
var it = Iterator3.init(.init(-8, -8, 0), .init(8, 8, 2), .init(1, 1, 2));
|
||||||
while (it.next()) |pos| {
|
while (it.next()) |pos| {
|
||||||
const material: Materials.Id = @enumFromInt(engine.random.uintLessThan(u16, @intFromEnum(materials.next_id)));
|
const material: Materials.Id = @enumFromInt(engine.random.uintLessThan(u16, @intFromEnum(materials.next_id)));
|
||||||
const matrix_os_to_ws = Matrix4x4.initTranslation(pos);
|
const matrix_os_to_ws = Matrix4x4.initTranslation(pos);
|
||||||
@@ -750,9 +761,9 @@ pub fn update(self: *Game, dt: f32) void {
|
|||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
const matrix_vs_to_cs = Matrix4x4.init(
|
const matrix_vs_to_cs = Matrix4x4.init(
|
||||||
camera_xscale, 0, 0, 0,
|
camera_xscale, 0, 0, 0,
|
||||||
0, 0, camera_near_plane, 1,
|
0, 0, 0, 1,
|
||||||
0, -camera_yscale, 0, 0,
|
0, -camera_yscale, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, camera_near_plane, 0,
|
||||||
);
|
);
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
|
|
||||||
@@ -863,7 +874,17 @@ fn render(self: *Game) !void {
|
|||||||
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||||
{
|
{
|
||||||
const clear_values = [_]vk.ClearValue{
|
const clear_values = [_]vk.ClearValue{
|
||||||
.{ .color = .{ .float_32 = .{ 0, 0, 0, 1 } } },
|
.{
|
||||||
|
.color = .{
|
||||||
|
.float_32 = .{ 0, 0, 0, 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.depth_stencil = .{
|
||||||
|
.depth = 0,
|
||||||
|
.stencil = 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
command_buffer.beginRenderPass(&.{
|
command_buffer.beginRenderPass(&.{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const vk = @import("vulkan");
|
|||||||
|
|
||||||
const Engine = @import("Engine.zig");
|
const Engine = @import("Engine.zig");
|
||||||
const QSM = @import("QueueSharingMode.zig");
|
const QSM = @import("QueueSharingMode.zig");
|
||||||
|
const Texture = @import("Texture.zig");
|
||||||
|
|
||||||
params: Params,
|
params: Params,
|
||||||
render_pass: vk.RenderPass,
|
render_pass: vk.RenderPass,
|
||||||
@@ -12,6 +13,7 @@ render_pass: vk.RenderPass,
|
|||||||
extent: vk.Extent2D = .{ .width = 0, .height = 0 },
|
extent: vk.Extent2D = .{ .width = 0, .height = 0 },
|
||||||
swapchain: vk.SwapchainKHR = .null_handle,
|
swapchain: vk.SwapchainKHR = .null_handle,
|
||||||
swapchain_images: []SwapchainImage = &.{},
|
swapchain_images: []SwapchainImage = &.{},
|
||||||
|
depth_texture: ?Texture = null,
|
||||||
image_index: u32 = 0,
|
image_index: u32 = 0,
|
||||||
semaphore_image_acquired: vk.Semaphore = .null_handle,
|
semaphore_image_acquired: vk.Semaphore = .null_handle,
|
||||||
|
|
||||||
@@ -35,6 +37,16 @@ pub fn init(engine: *Engine) !Swapchain {
|
|||||||
.initial_layout = .undefined,
|
.initial_layout = .undefined,
|
||||||
.final_layout = .present_src_khr,
|
.final_layout = .present_src_khr,
|
||||||
},
|
},
|
||||||
|
.{
|
||||||
|
.format = Texture.Usage.depth.vkFormat(),
|
||||||
|
.samples = .{ .@"1_bit" = true },
|
||||||
|
.load_op = .clear,
|
||||||
|
.store_op = .dont_care,
|
||||||
|
.stencil_load_op = .clear,
|
||||||
|
.stencil_store_op = .dont_care,
|
||||||
|
.initial_layout = .undefined,
|
||||||
|
.final_layout = .depth_stencil_attachment_optimal,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const color_attachments = [_]vk.AttachmentReference{
|
const color_attachments = [_]vk.AttachmentReference{
|
||||||
@@ -44,11 +56,39 @@ pub fn init(engine: *Engine) !Swapchain {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const depth_stencil_attachment: vk.AttachmentReference = .{
|
||||||
|
.attachment = 1,
|
||||||
|
.layout = .depth_stencil_attachment_optimal,
|
||||||
|
};
|
||||||
|
|
||||||
const subpasses = [_]vk.SubpassDescription{
|
const subpasses = [_]vk.SubpassDescription{
|
||||||
.{
|
.{
|
||||||
.pipeline_bind_point = .graphics,
|
.pipeline_bind_point = .graphics,
|
||||||
.color_attachment_count = color_attachments.len,
|
.color_attachment_count = color_attachments.len,
|
||||||
.p_color_attachments = &color_attachments,
|
.p_color_attachments = &color_attachments,
|
||||||
|
.p_depth_stencil_attachment = &depth_stencil_attachment,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const dependencies = [_]vk.SubpassDependency{
|
||||||
|
.{
|
||||||
|
.src_subpass = 0,
|
||||||
|
.dst_subpass = 0,
|
||||||
|
.src_stage_mask = .{
|
||||||
|
.color_attachment_output_bit = true,
|
||||||
|
.late_fragment_tests_bit = true,
|
||||||
|
},
|
||||||
|
.dst_stage_mask = .{
|
||||||
|
.color_attachment_output_bit = true,
|
||||||
|
.early_fragment_tests_bit = true,
|
||||||
|
},
|
||||||
|
.src_access_mask = .{
|
||||||
|
.depth_stencil_attachment_write_bit = true,
|
||||||
|
},
|
||||||
|
.dst_access_mask = .{
|
||||||
|
.color_attachment_write_bit = true,
|
||||||
|
.depth_stencil_attachment_write_bit = true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -57,6 +97,8 @@ pub fn init(engine: *Engine) !Swapchain {
|
|||||||
.p_attachments = &attachments,
|
.p_attachments = &attachments,
|
||||||
.subpass_count = subpasses.len,
|
.subpass_count = subpasses.len,
|
||||||
.p_subpasses = &subpasses,
|
.p_subpasses = &subpasses,
|
||||||
|
.dependency_count = dependencies.len,
|
||||||
|
.p_dependencies = &dependencies,
|
||||||
}, &engine.vk_allocator.interface);
|
}, &engine.vk_allocator.interface);
|
||||||
};
|
};
|
||||||
errdefer engine.device.destroyRenderPass(render_pass, &engine.vk_allocator.interface);
|
errdefer engine.device.destroyRenderPass(render_pass, &engine.vk_allocator.interface);
|
||||||
@@ -80,6 +122,10 @@ pub fn deinit(self: *Swapchain, engine: *Engine) void {
|
|||||||
}
|
}
|
||||||
allocator.free(self.swapchain_images);
|
allocator.free(self.swapchain_images);
|
||||||
|
|
||||||
|
if (self.depth_texture) |*depth_texture| {
|
||||||
|
depth_texture.deinit(engine);
|
||||||
|
}
|
||||||
|
|
||||||
if (self.swapchain != .null_handle) {
|
if (self.swapchain != .null_handle) {
|
||||||
engine.device.destroySwapchainKHR(self.swapchain, &engine.vk_allocator.interface);
|
engine.device.destroySwapchainKHR(self.swapchain, &engine.vk_allocator.interface);
|
||||||
}
|
}
|
||||||
@@ -95,6 +141,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
|
|
||||||
const old_swapchain = self.swapchain;
|
const old_swapchain = self.swapchain;
|
||||||
const old_swapchain_images = self.swapchain_images;
|
const old_swapchain_images = self.swapchain_images;
|
||||||
|
var old_depth_texture = self.depth_texture;
|
||||||
const old_semaphore_image_acquired = self.semaphore_image_acquired;
|
const old_semaphore_image_acquired = self.semaphore_image_acquired;
|
||||||
|
|
||||||
const extent = try getCurrentExtent(engine);
|
const extent = try getCurrentExtent(engine);
|
||||||
@@ -137,6 +184,10 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
allocator.free(self.swapchain_images);
|
allocator.free(self.swapchain_images);
|
||||||
self.swapchain_images = &.{};
|
self.swapchain_images = &.{};
|
||||||
|
|
||||||
|
if (old_depth_texture) |*depth_texture| {
|
||||||
|
depth_texture.deinit(engine);
|
||||||
|
}
|
||||||
|
|
||||||
if (old_swapchain != .null_handle) {
|
if (old_swapchain != .null_handle) {
|
||||||
engine.device.destroySwapchainKHR(old_swapchain, &engine.vk_allocator.interface);
|
engine.device.destroySwapchainKHR(old_swapchain, &engine.vk_allocator.interface);
|
||||||
self.swapchain = .null_handle;
|
self.swapchain = .null_handle;
|
||||||
@@ -149,6 +200,16 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
self.semaphore_image_acquired = .null_handle;
|
self.semaphore_image_acquired = .null_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- CREATE DEPTH TEXTURE ------------------------------------------------
|
||||||
|
|
||||||
|
var new_depth_texture = try Texture.init(engine, .{
|
||||||
|
.width = extent.width,
|
||||||
|
.height = extent.height,
|
||||||
|
.target_queue = .graphics,
|
||||||
|
.usage = .depth,
|
||||||
|
});
|
||||||
|
errdefer new_depth_texture.deinit(engine);
|
||||||
|
|
||||||
// --- CREATE NEW SWAPCHAIN IMAGES -----------------------------------------
|
// --- CREATE NEW SWAPCHAIN IMAGES -----------------------------------------
|
||||||
|
|
||||||
const new_swapchain_images = blk: {
|
const new_swapchain_images = blk: {
|
||||||
@@ -166,6 +227,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
.format = self.params.surface_format.format,
|
.format = self.params.surface_format.format,
|
||||||
.render_pass = self.render_pass,
|
.render_pass = self.render_pass,
|
||||||
.extent = extent,
|
.extent = extent,
|
||||||
|
.depth_stencil_image_view = new_depth_texture.image_view,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +257,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
self.extent = extent;
|
self.extent = extent;
|
||||||
self.swapchain = new_swapchain;
|
self.swapchain = new_swapchain;
|
||||||
self.swapchain_images = new_swapchain_images;
|
self.swapchain_images = new_swapchain_images;
|
||||||
|
self.depth_texture = new_depth_texture;
|
||||||
self.image_index = res.image_index;
|
self.image_index = res.image_index;
|
||||||
self.semaphore_image_acquired = semaphore_image_acquired;
|
self.semaphore_image_acquired = semaphore_image_acquired;
|
||||||
}
|
}
|
||||||
@@ -359,6 +422,7 @@ const SwapchainImage = struct {
|
|||||||
format: vk.Format,
|
format: vk.Format,
|
||||||
render_pass: vk.RenderPass,
|
render_pass: vk.RenderPass,
|
||||||
extent: vk.Extent2D,
|
extent: vk.Extent2D,
|
||||||
|
depth_stencil_image_view: vk.ImageView,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn init(engine: *Engine, props: InitProps) !SwapchainImage {
|
fn init(engine: *Engine, props: InitProps) !SwapchainImage {
|
||||||
@@ -389,7 +453,7 @@ const SwapchainImage = struct {
|
|||||||
|
|
||||||
const framebuffer = try engine.createFramebuffer(.{
|
const framebuffer = try engine.createFramebuffer(.{
|
||||||
.render_pass = props.render_pass,
|
.render_pass = props.render_pass,
|
||||||
.attachments = &.{image_view},
|
.attachments = &.{ image_view, props.depth_stencil_image_view },
|
||||||
.width = props.extent.width,
|
.width = props.extent.width,
|
||||||
.height = props.extent.height,
|
.height = props.extent.height,
|
||||||
.layers = 1,
|
.layers = 1,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ pub const Usage = enum {
|
|||||||
normal,
|
normal,
|
||||||
occlusion_roughness_metallic,
|
occlusion_roughness_metallic,
|
||||||
emissive,
|
emissive,
|
||||||
|
depth,
|
||||||
|
|
||||||
pub fn vkFormat(self: Usage) vk.Format {
|
pub fn vkFormat(self: Usage) vk.Format {
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
@@ -19,6 +20,7 @@ pub const Usage = enum {
|
|||||||
.normal => .r8g8b8a8_snorm,
|
.normal => .r8g8b8a8_snorm,
|
||||||
.occlusion_roughness_metallic => .r8g8b8a8_unorm,
|
.occlusion_roughness_metallic => .r8g8b8a8_unorm,
|
||||||
.emissive => .r16g16b16a16_sfloat,
|
.emissive => .r16g16b16a16_sfloat,
|
||||||
|
.depth => .d32_sfloat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,6 +30,7 @@ pub const Usage = enum {
|
|||||||
.normal => 4,
|
.normal => 4,
|
||||||
.occlusion_roughness_metallic => 4,
|
.occlusion_roughness_metallic => 4,
|
||||||
.emissive => 4,
|
.emissive => 4,
|
||||||
|
.depth => 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +40,7 @@ pub const Usage = enum {
|
|||||||
.normal => i8,
|
.normal => i8,
|
||||||
.occlusion_roughness_metallic => u8,
|
.occlusion_roughness_metallic => u8,
|
||||||
.emissive => f16,
|
.emissive => f16,
|
||||||
|
.depth => f32,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +84,11 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture {
|
|||||||
};
|
};
|
||||||
const transfer_queue_family = engine.transfer_queue.allocation.family;
|
const transfer_queue_family = engine.transfer_queue.allocation.family;
|
||||||
|
|
||||||
|
const queue_family_indices: []const u32 = if (init_info.usage == .depth)
|
||||||
|
&.{target_queue_family}
|
||||||
|
else
|
||||||
|
&.{ target_queue_family, transfer_queue_family };
|
||||||
|
|
||||||
const image = try engine.createImage(.{
|
const image = try engine.createImage(.{
|
||||||
.image_type = .@"2d",
|
.image_type = .@"2d",
|
||||||
.format = init_info.usage.vkFormat(),
|
.format = init_info.usage.vkFormat(),
|
||||||
@@ -93,10 +102,11 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture {
|
|||||||
.samples = .{ .@"1_bit" = true },
|
.samples = .{ .@"1_bit" = true },
|
||||||
.tiling = .optimal,
|
.tiling = .optimal,
|
||||||
.usage = .{
|
.usage = .{
|
||||||
.transfer_dst_bit = true,
|
.depth_stencil_attachment_bit = init_info.usage == .depth,
|
||||||
.sampled_bit = true,
|
.transfer_dst_bit = init_info.usage != .depth,
|
||||||
|
.sampled_bit = init_info.usage != .depth,
|
||||||
},
|
},
|
||||||
.queue_family_indices = &.{ target_queue_family, transfer_queue_family },
|
.queue_family_indices = queue_family_indices,
|
||||||
.initial_layout = .undefined,
|
.initial_layout = .undefined,
|
||||||
});
|
});
|
||||||
errdefer engine.destroyImage(image);
|
errdefer engine.destroyImage(image);
|
||||||
@@ -112,7 +122,10 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture {
|
|||||||
.view_type = .@"2d",
|
.view_type = .@"2d",
|
||||||
.format = init_info.usage.vkFormat(),
|
.format = init_info.usage.vkFormat(),
|
||||||
.subresource_range = .{
|
.subresource_range = .{
|
||||||
.aspect_mask = .{ .color_bit = true },
|
.aspect_mask = .{
|
||||||
|
.color_bit = init_info.usage != .depth,
|
||||||
|
.depth_bit = init_info.usage == .depth,
|
||||||
|
},
|
||||||
.base_mip_level = 0,
|
.base_mip_level = 0,
|
||||||
.level_count = 1,
|
.level_count = 1,
|
||||||
.base_array_layer = 0,
|
.base_array_layer = 0,
|
||||||
@@ -167,6 +180,7 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
|
|||||||
const texel_count = try std.math.mul(u32, self.width, self.height);
|
const texel_count = try std.math.mul(u32, self.width, self.height);
|
||||||
const byte_length = try std.math.mul(u32, texel_count, self.usage.bytesPerTexel());
|
const byte_length = try std.math.mul(u32, texel_count, self.usage.bytesPerTexel());
|
||||||
std.debug.assert(data.len == byte_length);
|
std.debug.assert(data.len == byte_length);
|
||||||
|
std.debug.assert(self.usage != .depth);
|
||||||
|
|
||||||
var staging_buffer = try StagingBuffer.init(engine, .{
|
var staging_buffer = try StagingBuffer.init(engine, .{
|
||||||
.capacity = @intCast(byte_length),
|
.capacity = @intCast(byte_length),
|
||||||
|
|||||||
Reference in New Issue
Block a user