Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 6 additions & 16 deletions assets/shaders/vulkan/culling.comp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@

layout(local_size_x = 64) in;

struct DrawIndirectCommand {
uint vertexCount;
uint instanceCount;
uint firstVertex;
uint firstInstance;
};

struct ChunkAABB {
vec4 min_point;
vec4 max_point;
Expand All @@ -18,13 +11,13 @@ layout(std430, binding = 0) readonly buffer ChunkAABBs {
ChunkAABB chunks[];
} aabb_buffer;

layout(std430, binding = 1) coherent writeonly buffer DrawCommands {
uint visible_count;
layout(std430, binding = 1) writeonly buffer VisibleIndices {
uint count;
uint _pad0;
uint _pad1;
uint _pad2;
DrawIndirectCommand commands[];
} cmd_buffer;
uint indices[];
} visible_buffer;

layout(std430, binding = 2) coherent buffer VisibleCountBuffer {
uint count;
Expand Down Expand Up @@ -68,11 +61,8 @@ void main() {
if (aabbVisible(aabb_min, aabb_max)) {
uint slot = atomicAdd(visible_counter.count, 1);

if (slot < cmd_buffer.commands.length()) {
cmd_buffer.commands[slot].vertexCount = 0;
cmd_buffer.commands[slot].instanceCount = 1;
cmd_buffer.commands[slot].firstVertex = 0;
cmd_buffer.commands[slot].firstInstance = idx;
if (slot < visible_buffer.indices.length()) {
visible_buffer.indices[slot] = idx;
}
}
}
46 changes: 28 additions & 18 deletions src/engine/graphics/vulkan/culling_system.zig
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const std = @import("std");
const c = @import("../../c.zig").c;
const c = @import("../../../c.zig").c;
const rhi_pkg = @import("../rhi.zig");
const log = @import("../core/log.zig");
const Mat4 = @import("../math/mat4.zig").Mat4;
const log = @import("../../core/log.zig");
const Mat4 = @import("../../math/mat4.zig").Mat4;
const VulkanContext = @import("rhi_context_types.zig").VulkanContext;
const Utils = @import("utils.zig");

Expand All @@ -26,7 +26,7 @@ pub const CullingSystem = struct {
vk_ctx: *VulkanContext,

aabb_buffers: [MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer,
command_buffers: [MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer,
visible_index_buffers: [MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer,
counter_buffers: [MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer,
counter_readback_buffers: [MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer,

Expand Down Expand Up @@ -59,7 +59,7 @@ pub const CullingSystem = struct {
.vk_ctx = vk_ctx,
.max_chunks = clamped_max,
.aabb_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer),
.command_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer),
.visible_index_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer),
.counter_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer),
.counter_readback_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer),
.descriptor_sets = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]c.VkDescriptorSet),
Expand All @@ -68,7 +68,7 @@ pub const CullingSystem = struct {

errdefer self.destroyAllBuffers();
const aabb_size = clamped_max * @sizeOf(ChunkCullData);
const cmd_size = @sizeOf(u32) * 4 + clamped_max * @sizeOf(c.VkDrawIndirectCommand);
const index_buffer_size = @sizeOf(u32) * 4 + clamped_max * @sizeOf(u32);

for (0..MAX_FRAMES_IN_FLIGHT) |i| {
self.aabb_buffers[i] = try Utils.createVulkanBuffer(
Expand All @@ -78,11 +78,11 @@ pub const CullingSystem = struct {
c.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | c.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
);

self.command_buffers[i] = try Utils.createVulkanBuffer(
self.visible_index_buffers[i] = try Utils.createVulkanBuffer(
&vk_ctx.vulkan_device,
cmd_size,
c.VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | c.VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
c.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
index_buffer_size,
c.VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
c.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | c.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
);

self.counter_buffers[i] = try Utils.createVulkanBuffer(
Expand Down Expand Up @@ -189,11 +189,11 @@ pub const CullingSystem = struct {
var compute_barrier = std.mem.zeroes(c.VkMemoryBarrier);
compute_barrier.sType = c.VK_STRUCTURE_TYPE_MEMORY_BARRIER;
compute_barrier.srcAccessMask = c.VK_ACCESS_SHADER_WRITE_BIT;
compute_barrier.dstAccessMask = c.VK_ACCESS_INDIRECT_COMMAND_READ_BIT | c.VK_ACCESS_TRANSFER_READ_BIT;
compute_barrier.dstAccessMask = c.VK_ACCESS_HOST_READ_BIT | c.VK_ACCESS_TRANSFER_READ_BIT;
c.vkCmdPipelineBarrier(
cmd,
c.VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
c.VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | c.VK_PIPELINE_STAGE_TRANSFER_BIT,
c.VK_PIPELINE_STAGE_HOST_BIT | c.VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
1,
&compute_barrier,
Expand All @@ -213,6 +213,16 @@ pub const CullingSystem = struct {
return ptr.*;
}

pub fn readVisibleIndices(self: *CullingSystem, frame_index: usize, count: u32, out: []u32) void {
if (count == 0) return;
const buf = &self.visible_index_buffers[frame_index];
if (buf.mapped_ptr == null) return;
const copy_count = @min(@as(usize, @intCast(count)), @min(out.len, self.max_chunks));
if (copy_count == 0) return;
const src: [*]const u32 = @ptrCast(@alignCast(buf.mapped_ptr.?));
@memcpy(out[0..copy_count], src[4 .. 4 + copy_count]);
}

fn copyCounterToReadback(self: *CullingSystem, cmd: c.VkCommandBuffer, frame_index: usize) void {
const src = self.counter_buffers[frame_index];
const dst = self.counter_readback_buffers[frame_index];
Expand Down Expand Up @@ -336,7 +346,7 @@ pub const CullingSystem = struct {

var writes: [3 * MAX_FRAMES_IN_FLIGHT]c.VkWriteDescriptorSet = undefined;
var aabb_infos: [MAX_FRAMES_IN_FLIGHT]c.VkDescriptorBufferInfo = undefined;
var cmd_infos: [MAX_FRAMES_IN_FLIGHT]c.VkDescriptorBufferInfo = undefined;
var index_infos: [MAX_FRAMES_IN_FLIGHT]c.VkDescriptorBufferInfo = undefined;
var counter_infos: [MAX_FRAMES_IN_FLIGHT]c.VkDescriptorBufferInfo = undefined;
var n: usize = 0;

Expand All @@ -346,8 +356,8 @@ pub const CullingSystem = struct {
.offset = 0,
.range = aabb_range,
};
cmd_infos[i] = c.VkDescriptorBufferInfo{
.buffer = self.command_buffers[i].buffer,
index_infos[i] = c.VkDescriptorBufferInfo{
.buffer = self.visible_index_buffers[i].buffer,
.offset = 0,
.range = c.VK_WHOLE_SIZE,
};
Expand All @@ -372,7 +382,7 @@ pub const CullingSystem = struct {
writes[n].dstBinding = 1;
writes[n].descriptorType = c.VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writes[n].descriptorCount = 1;
writes[n].pBufferInfo = &cmd_infos[i];
writes[n].pBufferInfo = &index_infos[i];
n += 1;

writes[n] = std.mem.zeroes(c.VkWriteDescriptorSet);
Expand Down Expand Up @@ -407,13 +417,13 @@ pub const CullingSystem = struct {

for (0..MAX_FRAMES_IN_FLIGHT) |i| {
unmapAndDestroy(vk, &self.aabb_buffers[i]);
unmapAndDestroy(vk, &self.command_buffers[i]);
unmapAndDestroy(vk, &self.visible_index_buffers[i]);
unmapAndDestroy(vk, &self.counter_buffers[i]);
unmapAndDestroy(vk, &self.counter_readback_buffers[i]);
}

self.aabb_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer);
self.command_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer);
self.visible_index_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer);
self.counter_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer);
self.counter_readback_buffers = std.mem.zeroes([MAX_FRAMES_IN_FLIGHT]Utils.VulkanBuffer);
}
Expand Down
2 changes: 1 addition & 1 deletion src/world/world.zig
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub const World = struct {
};

log.log.info("World.initGen: initializing WorldRenderer", .{});
world.renderer = try WorldRenderer.init(allocator, rhi.resourceManager(), rhi.renderContext(), rhi.query(), &world.storage);
world.renderer = try WorldRenderer.init(allocator, rhi.resourceManager(), rhi.renderContext(), rhi.query(), &world.storage, rhi);
errdefer _ = world.renderer;

log.log.info("World.initGen: initializing WorldStreamer (render_distance={})", .{safe_render_distance});
Expand Down
Loading
Loading