Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scene refactoring #35

Closed
wants to merge 1 commit into from
Closed
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
171 changes: 26 additions & 145 deletions src/aabb_scene.cc
Original file line number Diff line number Diff line change
@@ -1,70 +1,6 @@
#include "aabb_scene.hh"
#include "misc.hh"

namespace
{
using namespace tr;

void record_blas_update(
vk::CommandBuffer& cb,
vk::AccelerationStructureKHR blas,
size_t total_aabb_count,
gpu_buffer& aabb_buffer,
vkm<vk::Buffer>& scratch_buffer,
bool update,
timer& update_timer,
uint32_t frame_index
){
if(total_aabb_count == 0)
return;

update_timer.begin(cb, frame_index);
aabb_buffer.upload(frame_index, cb);

vk::MemoryBarrier barrier(
vk::AccessFlagBits::eTransferWrite,
vk::AccessFlagBits::eAccelerationStructureWriteKHR
);

cb.pipelineBarrier(
vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR,
{},
barrier, {}, {}
);

vk::AccelerationStructureGeometryKHR geom(
vk::GeometryTypeKHR::eAabbs,
vk::AccelerationStructureGeometryAabbsDataKHR(
aabb_buffer.get_address(),
sizeof(vk::AabbPositionsKHR)
),
vk::GeometryFlagBitsKHR::eOpaque
);

vk::AccelerationStructureBuildGeometryInfoKHR blas_build_info(
vk::AccelerationStructureTypeKHR::eBottomLevel,
vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace|
vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate,
update ? vk::BuildAccelerationStructureModeKHR::eUpdate : vk::BuildAccelerationStructureModeKHR::eBuild,
update ? blas : vk::AccelerationStructureKHR{},
blas,
1,
&geom,
nullptr,
scratch_buffer.get_address()
);

vk::AccelerationStructureBuildRangeInfoKHR offset(
total_aabb_count, 0, 0, 0
);

cb.buildAccelerationStructuresKHR({blas_build_info}, {&offset});
update_timer.end(cb, frame_index);
}

}

namespace tr
{

Expand All @@ -89,11 +25,11 @@ void aabb_scene::update_acceleration_structures(
bool& need_scene_reset,
bool& command_buffers_outdated
){
auto& as = acceleration_structures[device_index];
auto& as = as_update[device_index];
auto& f = as.per_frame[frame_index];

// Update area point light buffer
as.aabb_buffer.map<vk::AabbPositionsKHR>(
aabb_buffer[device_index].map<vk::AabbPositionsKHR>(
frame_index,
[&](vk::AabbPositionsKHR* aabb){
f.aabb_count = get_aabbs(aabb);
Expand All @@ -113,19 +49,20 @@ void aabb_scene::record_acceleration_structure_build(
uint32_t frame_index,
bool update_only
){
auto& as = acceleration_structures[device_index];
auto& as = as_update[device_index];
auto& f = as.per_frame[frame_index];

record_blas_update(
as.blas_update_timer.begin(cb, frame_index);
aabb_buffer[device_index].upload(frame_index, cb);

blas->rebuild(
device_index,
frame_index,
cb,
as.blas,
f.aabb_count,
as.aabb_buffer,
as.scratch_buffer,
update_only,
as.blas_update_timer,
frame_index
{bottom_level_acceleration_structure::entry{nullptr, f.aabb_count, aabb_buffer.data(), mat4(1.0f), true}},
update_only
);
as.blas_update_timer.end(cb, frame_index);
}

void aabb_scene::add_acceleration_structure_instances(
Expand All @@ -136,7 +73,7 @@ void aabb_scene::add_acceleration_structure_instances(
size_t capacity
) const
{
auto& as = acceleration_structures[device_index];
auto& as = as_update[device_index];
auto& f = as.per_frame[frame_index];

if(f.aabb_count != 0 && instance_index < capacity)
Expand All @@ -145,7 +82,7 @@ void aabb_scene::add_acceleration_structure_instances(
inst = vk::AccelerationStructureInstanceKHR(
{}, instance_index, 1<<1, sbt_offset,
vk::GeometryInstanceFlagBitsKHR::eTriangleCullDisable,
as.blas_buffer.get_address()
blas->get_blas_address(device_index)
);
mat4 id_mat = mat4(1.0f);
memcpy((void*)&inst.transform, (void*)&id_mat, sizeof(inst.transform));
Expand All @@ -157,90 +94,34 @@ void aabb_scene::init_acceleration_structures(const char* timer_name)
if(!ctx->is_ray_tracing_supported()) return;

std::vector<device_data>& devices = ctx->get_devices();
acceleration_structures.resize(devices.size());
as_update.resize(devices.size());
aabb_buffer.clear();

for(size_t i = 0; i < devices.size(); ++i)
{
auto& as = acceleration_structures[i];
as.aabb_buffer = gpu_buffer(
auto& as = as_update[i];
aabb_buffer.emplace_back(
devices[i], max_capacity * sizeof(vk::AabbPositionsKHR),
vk::BufferUsageFlagBits::eStorageBuffer |
vk::BufferUsageFlagBits::eTransferDst |
vk::BufferUsageFlagBits::eShaderDeviceAddress|
vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR
);

vk::AccelerationStructureGeometryKHR geom(
VULKAN_HPP_NAMESPACE::GeometryTypeKHR::eAabbs,
vk::AccelerationStructureGeometryAabbsDataKHR(
as.aabb_buffer.get_address(), sizeof(vk::AabbPositionsKHR)
),
vk::GeometryFlagBitsKHR::eOpaque
);

vk::AccelerationStructureBuildGeometryInfoKHR blas_info(
vk::AccelerationStructureTypeKHR::eBottomLevel,
vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace|
vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate,
vk::BuildAccelerationStructureModeKHR::eBuild,
VK_NULL_HANDLE,
VK_NULL_HANDLE,
1,
&geom
);

vk::AccelerationStructureBuildSizesInfoKHR size_info =
devices[i].dev.getAccelerationStructureBuildSizesKHR(
vk::AccelerationStructureBuildTypeKHR::eDevice, blas_info,
{(uint32_t)max_capacity}
);

vk::BufferCreateInfo blas_buffer_info(
{}, size_info.accelerationStructureSize,
vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR|
vk::BufferUsageFlagBits::eShaderDeviceAddress,
vk::SharingMode::eExclusive
);
as.blas_buffer = create_buffer(
devices[i],
blas_buffer_info,
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
);

vk::AccelerationStructureCreateInfoKHR create_info(
{},
as.blas_buffer,
{},
size_info.accelerationStructureSize,
vk::AccelerationStructureTypeKHR::eBottomLevel,
{}
);
as.blas = vkm(
devices[i],
devices[i].dev.createAccelerationStructureKHR(create_info)
);
blas_info.dstAccelerationStructure = as.blas;

vk::BufferCreateInfo scratch_info(
{}, size_info.buildScratchSize,
vk::BufferUsageFlagBits::eStorageBuffer|
vk::BufferUsageFlagBits::eShaderDeviceAddress,
vk::SharingMode::eExclusive
);
as.scratch_buffer = create_buffer_aligned(
devices[i],
scratch_info,
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
devices[i].as_props.minAccelerationStructureScratchOffsetAlignment
);

as.blas_update_timer = timer(devices[i], timer_name);
}
blas.emplace(
*ctx,
std::vector<bottom_level_acceleration_structure::entry>{
{nullptr, max_capacity, aabb_buffer.data(), mat4(1.0f), true}
},
false, true, false
);
}

void aabb_scene::invalidate_acceleration_structures()
{
for(auto& as: acceleration_structures)
for(auto& as: as_update)
{
as.scene_reset_needed = true;
for(auto& f: as.per_frame)
Expand Down
12 changes: 5 additions & 7 deletions src/aabb_scene.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define TAURAY_AABB_SCENE_HH
#include "context.hh"
#include "timer.hh"
#include "acceleration_structure.hh"
#include "gpu_buffer.hh"

namespace tr
Expand Down Expand Up @@ -60,15 +61,12 @@ private:
size_t max_capacity;
size_t sbt_offset;

struct acceleration_structure_data
std::optional<bottom_level_acceleration_structure> blas;
std::vector<gpu_buffer> aabb_buffer;
struct as_update_data
{
bool scene_reset_needed = true;

vkm<vk::AccelerationStructureKHR> blas;
vkm<vk::Buffer> blas_buffer;
vkm<vk::Buffer> scratch_buffer;
gpu_buffer aabb_buffer;

struct per_frame_data
{
bool command_buffers_outdated = true;
Expand All @@ -77,7 +75,7 @@ private:
per_frame_data per_frame[MAX_FRAMES_IN_FLIGHT];
timer blas_update_timer;
};
std::vector<acceleration_structure_data> acceleration_structures;
std::vector<as_update_data> as_update;
};

}
Expand Down
45 changes: 32 additions & 13 deletions src/acceleration_structure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ bottom_level_acceleration_structure::bottom_level_acceleration_structure(
for(size_t i = 0; i < devices.size(); ++i)
{
buffers[i].transform_buffer = gpu_buffer(
devices[i], sizeof(vk::TransformMatrixKHR) * entries.size(),
devices[i],
sizeof(vk::TransformMatrixKHR) * entries.size(),
vk::BufferUsageFlagBits::eStorageBuffer |
vk::BufferUsageFlagBits::eTransferDst |
vk::BufferUsageFlagBits::eShaderDeviceAddress |
vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR
);
Expand Down Expand Up @@ -76,29 +79,45 @@ void bottom_level_acceleration_structure::rebuild(
buffer_data& bd = buffers[device_index];
for(size_t i = 0; i < entries.size(); ++i)
{
const mesh* m = entries[i].m;
vk::DeviceOrHostAddressConstKHR transform_address{};
transform_address.deviceAddress =
bd.transform_buffer.get_address() + sizeof(vk::TransformMatrixKHR) * i;

geometries[i] = {
vk::GeometryTypeKHR::eTriangles,
vk::AccelerationStructureGeometryTrianglesDataKHR(
vk::AccelerationStructureGeometryKHR geom;
const mesh* m = entries[i].m;
if(m)
{
geom.geometryType = vk::GeometryTypeKHR::eTriangles;
geom.geometry = vk::AccelerationStructureGeometryTrianglesDataKHR(
vk::Format::eR32G32B32Sfloat,
dev.dev.getBufferAddress({m->get_vertex_buffer(device_index)}),
sizeof(mesh::vertex),
m->get_vertices().size()-1,
vk::IndexType::eUint32,
dev.dev.getBufferAddress({m->get_index_buffer(device_index)}),
transform_address
),
(entries[i].opaque ?
vk::GeometryFlagBitsKHR::eOpaque :
vk::GeometryFlagBitsKHR::eNoDuplicateAnyHitInvocation)
};
uint32_t triangle_count = m->get_indices().size()/3;
ranges[i] = vk::AccelerationStructureBuildRangeInfoKHR{triangle_count, 0, 0, 0};
primitive_count[i] = triangle_count;
);
uint32_t triangle_count = m->get_indices().size()/3;
ranges[i] = vk::AccelerationStructureBuildRangeInfoKHR{triangle_count, 0, 0, 0};
primitive_count[i] = triangle_count;
}
else
{
geom.geometryType = vk::GeometryTypeKHR::eAabbs;
geom.geometry = vk::AccelerationStructureGeometryAabbsDataKHR(
entries[i].aabb_buffer[device_index].get_address(),
sizeof(vk::AabbPositionsKHR)
);
ranges[i] = vk::AccelerationStructureBuildRangeInfoKHR{
(uint32_t)entries[i].aabb_count, 0, 0, 0
};
primitive_count[i] = entries[i].aabb_count;
}
geom.setFlags(entries[i].opaque ?
vk::GeometryFlagBitsKHR::eOpaque :
vk::GeometryFlagBitsKHR::eNoDuplicateAnyHitInvocation
);
geometries[i] = geom;
}

vk::AccelerationStructureBuildGeometryInfoKHR blas_info(
Expand Down
7 changes: 6 additions & 1 deletion src/acceleration_structure.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ class bottom_level_acceleration_structure
public:
struct entry
{
// If nullptr, this entry is AABBs instead of a triangle mesh.
const mesh* m = nullptr;
mat4 transform = mat4(1);
size_t aabb_count = 0;
// Pointer to array of AABB buffers, indexed by device index
gpu_buffer* aabb_buffer = nullptr;

mat4 transform = mat4(1.0f);
bool opaque = true;
};

Expand Down
3 changes: 3 additions & 0 deletions src/mesh_scene.cc
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ void mesh_scene::refresh_dynamic_acceleration_structures(
const instance& inst = instance_cache[offset];
entries.push_back({
inst.m,
0, nullptr,
group.static_transformable ? inst.transform : mat4(1),
!inst.mat->potentially_transparent()
});
Expand Down Expand Up @@ -347,6 +348,7 @@ void mesh_scene::update_acceleration_structures(
const instance& inst = instance_cache[offset];
entries.push_back({
inst.m,
0, nullptr,
group.static_transformable ? inst.transform : mat4(1),
!inst.mat->potentially_transparent()
});
Expand Down Expand Up @@ -437,6 +439,7 @@ void mesh_scene::ensure_blas()
if(inst.mat->double_sided) double_sided = true;
entries.push_back({
inst.m,
0, nullptr,
group.static_transformable ? inst.transform : mat4(1),
!inst.mat->potentially_transparent()
});
Expand Down