Skip to content

Commit

Permalink
Adding raytracing support (1): acceleration struct
Browse files Browse the repository at this point in the history
  • Loading branch information
nadult committed Mar 30, 2024
1 parent a49a72e commit aa264d7
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 6 deletions.
10 changes: 8 additions & 2 deletions include/fwk/vulkan/vulkan_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,17 @@ namespace fwk {

inline auto toVk(VShaderStage stage) { return VkShaderStageFlagBits(1u << int(stage)); }
inline auto toVk(VShaderStages flags) { return VkShaderStageFlags(flags.bits); }
inline auto toVk(VDescriptorType type) { return VkDescriptorType(type); }
inline auto toVk(VDescriptorType type) {
return type == VDescriptorType::accel_struct ? VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR :
VkDescriptorType(type);
}
inline auto toVk(VDescriptorPoolFlags flags) { return VkDescriptorPoolCreateFlagBits(flags.bits); }
inline auto toVk(VPrimitiveTopology type) { return VkPrimitiveTopology(type); }
inline auto toVk(VImageUsageFlags usage) { return VkImageUsageFlags{usage.bits}; }
inline auto toVk(VBufferUsageFlags usage) { return VkBufferUsageFlags{usage.bits}; }
inline auto toVk(VBufferUsageFlags usage) {
uint32_t base_bits{usage.bits & 0x1ffu}, accel_bits{usage.bits & 0x600u};
return VkBufferUsageFlags{base_bits | (accel_bits << 10)};
}
inline auto toVk(VCommandPoolFlags flags) { return VkCommandPoolCreateFlagBits(flags.bits); }
inline auto toVk(VMemoryFlags flags) { return VkMemoryPropertyFlags(flags.bits); }
inline auto toVk(VPresentMode mode) { return VkPresentModeKHR(mode); }
Expand Down
1 change: 1 addition & 0 deletions include/fwk/vulkan/vulkan_pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ struct VDescriptorSet {

void set(int first_index, VDescriptorType type, CSpan<VBufferSpan<char>>);
void set(int first_index, CSpan<Pair<PVSampler, PVImageView>>);
void set(int first_index, PVAccelStruct);

void setStorageImage(int index, PVImageView, VImageLayout);

Expand Down
28 changes: 28 additions & 0 deletions include/fwk/vulkan/vulkan_ray_tracing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) Krzysztof Jakubowski <[email protected]>
// This file is part of libfwk. See license.txt for details.

#pragma once

#include "fwk/vulkan/vulkan_storage.h"
#include "fwk/vulkan_base.h"

namespace fwk {

DEFINE_ENUM(VAccelStructType, top_level, bottom_level);

class VulkanAccelStruct : public VulkanObjectBase<VulkanAccelStruct> {
public:
static Ex<PVAccelStruct> create(VulkanDevice &, VAccelStructType, VBufferSpan<char>);

static Ex<PVAccelStruct> build(VulkanDevice &, VBufferSpan<float3> vertices,
VBufferSpan<u32> indices);

private:
friend class VulkanDevice;
VulkanAccelStruct(VkAccelerationStructureKHR, VObjectId, PVBuffer);
~VulkanAccelStruct();

PVBuffer m_buffer;
};

}
1 change: 1 addition & 0 deletions include/fwk/vulkan/vulkan_type_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ CASE_TYPE(RenderPass, VkRenderPass, render_pass)
CASE_TYPE(ShaderModule, VkShaderModule, shader_module)
CASE_TYPE(SwapChain, VkSwapchainKHR, swap_chain)
CASE_TYPE(Sampler, VkSampler, sampler)
CASE_TYPE(AccelStruct, VkAccelerationStructureKHR, accel_struct)

#undef CASE_TYPE
9 changes: 5 additions & 4 deletions include/fwk/vulkan_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ struct VulkanVersion {

DEFINE_ENUM(VVendorId, intel, nvidia, amd, unknown);

DEFINE_ENUM(VTypeId, buffer, buffer_view, framebuffer, image, image_view, pipeline, pipeline_layout,
render_pass, sampler, shader_module, swap_chain);
DEFINE_ENUM(VTypeId, accel_struct, buffer, buffer_view, framebuffer, image, image_view, pipeline,
pipeline_layout, render_pass, sampler, shader_module, swap_chain);

// device: fastest memory with device_local (always available)
// host: fastest memory with host_visible (always available)
Expand Down Expand Up @@ -90,7 +90,8 @@ using VCommandPoolFlags = EnumFlags<VCommandPoolFlag>;
DEFINE_ENUM(VBindPoint, graphics, compute);

DEFINE_ENUM(VBufferUsage, transfer_src, transfer_dst, uniform_texel_buffer, storage_texel_buffer,
uniform_buffer, storage_buffer, index_buffer, vertex_buffer, indirect_buffer);
uniform_buffer, storage_buffer, index_buffer, vertex_buffer, indirect_buffer,
accel_struct_build_input, accel_struct_storage);
using VBufferUsageFlags = EnumFlags<VBufferUsage>;

DEFINE_ENUM(VImageUsage, transfer_src, transfer_dst, sampled, storage, color_att, depth_stencil_att,
Expand All @@ -106,7 +107,7 @@ using VShaderStages = EnumFlags<VShaderStage>;

DEFINE_ENUM(VDescriptorType, sampler, combined_image_sampler, sampled_image, storage_image,
uniform_texel_buffer, storage_texel_buffer, uniform_buffer, storage_buffer,
uniform_buffer_dynamic, storage_buffer_dynamic, input_att);
uniform_buffer_dynamic, storage_buffer_dynamic, input_att, accel_struct);
using VDescriptorTypes = EnumFlags<VDescriptorType>;

DEFINE_ENUM(VDescriptorPoolFlag, free_descriptor_set, update_after_bind, host_only);
Expand Down
1 change: 1 addition & 0 deletions src/vulkan/vulkan_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "fwk/vulkan/vulkan_framebuffer.h"
#include "fwk/vulkan/vulkan_image.h"
#include "fwk/vulkan/vulkan_pipeline.h"
#include "fwk/vulkan/vulkan_ray_tracing.h"
#include "fwk/vulkan/vulkan_shader.h"
#include "fwk/vulkan/vulkan_swap_chain.h"
#include "fwk/vulkan/vulkan_window.h"
Expand Down
20 changes: 20 additions & 0 deletions src/vulkan/vulkan_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "fwk/vulkan/vulkan_device.h"
#include "fwk/vulkan/vulkan_instance.h"
#include "fwk/vulkan/vulkan_internal.h"
#include "fwk/vulkan/vulkan_ray_tracing.h"
#include "fwk/vulkan/vulkan_shader.h"

namespace fwk {
Expand Down Expand Up @@ -165,6 +166,25 @@ void VDescriptorSet::setStorageImage(int index, PVImageView image_view, VImageLa
vkUpdateDescriptorSets(device->handle(), 1, &write, 0, nullptr);
}

void VDescriptorSet::set(int index, PVAccelStruct as) {
if(!(bindings_map & (1ull << index)))
return;
VkWriteDescriptorSetAccelerationStructureKHR as_info{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR};
auto as_handle = as->handle();
as_info.pAccelerationStructures = &as_handle;
as_info.accelerationStructureCount = 1;

VkWriteDescriptorSet write{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};
write.descriptorCount = 1;
write.dstSet = handle;
write.dstBinding = index;
write.dstArrayElement = 0;
write.descriptorType = toVk(VDescriptorType::storage_image);
write.pNext = &as_info;
vkUpdateDescriptorSets(device->handle(), 1, &write, 0, nullptr);
}

VulkanRenderPass::VulkanRenderPass(VkRenderPass handle, VObjectId id)
: VulkanObjectBase(handle, id) {}
VulkanRenderPass ::~VulkanRenderPass() {
Expand Down
102 changes: 102 additions & 0 deletions src/vulkan/vulkan_ray_tracing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (C) Krzysztof Jakubowski <[email protected]>
// This file is part of libfwk. See license.txt for details.

#include "fwk/vulkan/vulkan_ray_tracing.h"

#include "fwk/enum_map.h"
#include "fwk/sys/assert.h"
#include "fwk/vulkan/vulkan_command_queue.h"
#include "fwk/vulkan/vulkan_device.h"
#include "fwk/vulkan/vulkan_internal.h"
#include "fwk/vulkan/vulkan_memory_manager.h"

namespace fwk {

VulkanAccelStruct::VulkanAccelStruct(VkAccelerationStructureKHR handle, VObjectId id,
PVBuffer buffer)
: VulkanObjectBase(handle, id), m_buffer(std::move(buffer)) {}

VulkanAccelStruct::~VulkanAccelStruct() {
deferredRelease(vkDestroyAccelerationStructureKHR, m_handle);
}

Ex<PVAccelStruct> VulkanAccelStruct::create(VulkanDevice &device, VAccelStructType type,
VBufferSpan<char> buffer) {
DASSERT(buffer.byteOffset() % 256 == 0);

VkAccelerationStructureCreateInfoKHR create_info{
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
create_info.buffer = buffer.buffer().handle();
create_info.offset = buffer.byteOffset();
create_info.size = buffer.byteOffset();
create_info.type = VkAccelerationStructureTypeKHR(type);

VkAccelerationStructureKHR handle = 0;
FWK_VK_EXPECT_CALL(vkCreateAccelerationStructureKHR, device.handle(), &create_info, nullptr,
&handle);
return device.createObject(handle, buffer.buffer());
}

template <class T> static u64 getAddress(VulkanDevice &device, VBufferSpan<T> buffer) {
VkBufferDeviceAddressInfo info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
info.buffer = buffer.buffer().handle();
return vkGetBufferDeviceAddress(device.handle(), &info) + buffer.byteOffset();
}

Ex<PVAccelStruct> VulkanAccelStruct::build(VulkanDevice &device, VBufferSpan<float3> vertices,
VBufferSpan<u32> indices) {
VkAccelerationStructureGeometryTrianglesDataKHR triangles{
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR};
triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
triangles.vertexData.deviceAddress = getAddress(device, vertices);
triangles.vertexStride = sizeof(float3);
triangles.indexType = VK_INDEX_TYPE_UINT32;
triangles.indexData.deviceAddress = getAddress(device, indices);
DASSERT(vertices.size() > 0);
triangles.maxVertex = vertices.size() - 1;

VkAccelerationStructureGeometryKHR geometry{
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR};
geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
geometry.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
geometry.geometry.triangles = triangles;

VkAccelerationStructureBuildRangeInfoKHR offset;
offset.firstVertex = vertices.byteOffset() / sizeof(float3);
offset.primitiveCount = indices.size() / 3;
offset.primitiveOffset = 0;
offset.transformOffset = 0;

VkAccelerationStructureBuildGeometryInfoKHR build_info{
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
build_info.type =
VkAccelerationStructureTypeKHR::VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
build_info.flags = 0; // TODO: compaction
build_info.pGeometries = &geometry;
build_info.geometryCount = 1;

VkAccelerationStructureBuildSizesInfoKHR size_info{
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR};
uint32_t prim_count = indices.size() / 3;

vkGetAccelerationStructureBuildSizesKHR(
device.handle(),
VkAccelerationStructureBuildTypeKHR::VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
&build_info, &prim_count, &size_info);

auto buffer = EX_PASS(VulkanBuffer::create(device, size_info.accelerationStructureSize,
VBufferUsage::accel_struct_storage));
auto accel = EX_PASS(VulkanAccelStruct::create(device, VAccelStructType::bottom_level, buffer));

build_info.srcAccelerationStructure = accel->handle();
build_info.dstAccelerationStructure = accel->handle();

auto *offsets = &offset;

auto result =
vkBuildAccelerationStructuresKHR(device.handle(), nullptr, 1, &build_info, &offsets);

return accel;
}

}
2 changes: 2 additions & 0 deletions windows/libfwk.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
<ClInclude Include="..\include\fwk\vulkan\vulkan_instance.h" />
<ClInclude Include="..\include\fwk\vulkan\vulkan_pipeline.h" />
<ClInclude Include="..\include\fwk\vulkan\vulkan_command_queue.h" />
<ClInclude Include="..\include\fwk\vulkan\vulkan_ray_tracing.h" />
<ClInclude Include="..\include\fwk\vulkan\vulkan_shader.h" />
<ClInclude Include="..\include\fwk\vulkan\vulkan_storage.h" />
<ClInclude Include="..\include\fwk\vulkan\vulkan_swap_chain.h" />
Expand Down Expand Up @@ -345,6 +346,7 @@
<ClCompile Include="..\src\vulkan\vulkan_instance.cpp" />
<ClCompile Include="..\src\vulkan\vulkan_pipeline.cpp" />
<ClCompile Include="..\src\vulkan\vulkan_command_queue.cpp" />
<ClCompile Include="..\src\vulkan\vulkan_ray_tracing.cpp" />
<ClCompile Include="..\src\vulkan\vulkan_shader.cpp" />
<ClCompile Include="..\src\vulkan\vulkan_storage.cpp" />
<ClCompile Include="..\src\vulkan\vulkan_swap_chain.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions windows/libfwk.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,9 @@
<ClInclude Include="..\include\fwk\gfx\image_view.h">
<Filter>include\gfx</Filter>
</ClInclude>
<ClInclude Include="..\include\fwk\vulkan\vulkan_ray_tracing.h">
<Filter>include\vulkan</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\math\base.cpp">
Expand Down Expand Up @@ -1091,6 +1094,9 @@
<ClCompile Include="..\src\gfx\canvas_3d.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="..\src\vulkan\vulkan_ray_tracing.cpp">
<Filter>src\vulkan</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\todo.txt" />
Expand Down

0 comments on commit aa264d7

Please sign in to comment.