Skip to content
Open
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
7 changes: 4 additions & 3 deletions framework/core/acceleration_structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ void AccelerationStructure::build(VkQueue queue, VkBuildAccelerationStructureFla
// Create a scratch buffer as a temporary storage for the acceleration structure build
scratch_buffer = std::make_unique<vkb::core::BufferC>(
device,
build_sizes_info.buildScratchSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
BufferBuilderC(build_sizes_info.buildScratchSize)
.with_usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
.with_vma_usage(VMA_MEMORY_USAGE_GPU_ONLY)
.with_alignment(scratch_buffer_alignment));

build_geometry_info.scratchData.deviceAddress = scratch_buffer->get_device_address();
build_geometry_info.dstAccelerationStructure = handle;
Expand Down
7 changes: 7 additions & 0 deletions framework/core/acceleration_structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ class AccelerationStructure
geometries.clear();
}

void set_scrach_buffer_alignment(VkDeviceSize alignment)
{
scratch_buffer_alignment = alignment;
}

private:
vkb::core::DeviceC &device;

Expand All @@ -144,6 +149,8 @@ class AccelerationStructure

VkAccelerationStructureBuildSizesInfoKHR build_sizes_info{};

VkDeviceSize scratch_buffer_alignment{0};

struct Geometry
{
VkAccelerationStructureGeometryKHR geometry{};
Expand Down
41 changes: 28 additions & 13 deletions framework/core/allocated.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class Allocated : public vkb::core::VulkanResource<bindingType, HandleType>
* Present in this common base class in order to allow the internal state members to remain `private`
* instead of `protected`, and because it (mostly) isolates interaction with the VMA to a single class
*/
[[nodiscard]] BufferType create_buffer(BufferCreateInfoType const &create_info);
[[nodiscard]] BufferType create_buffer(BufferCreateInfoType const &create_info, DeviceSizeType alignment);
/**
* @brief Internal method to actually create the image, allocate the memory and bind them.
* Should only be called from the `Image` derived class.
Expand Down Expand Up @@ -338,7 +338,7 @@ class Allocated : public vkb::core::VulkanResource<bindingType, HandleType>
void clear();

private:
vk::Buffer create_buffer_impl(vk::BufferCreateInfo const &create_info);
vk::Buffer create_buffer_impl(vk::BufferCreateInfo const &create_info, DeviceSizeType alignment);
vk::Image create_image_impl(vk::ImageCreateInfo const &create_info);

VmaAllocationCreateInfo allocation_create_info = {};
Expand Down Expand Up @@ -403,31 +403,46 @@ inline void Allocated<bindingType, HandleType>::clear()
}

template <vkb::BindingType bindingType, typename HandleType>
inline typename Allocated<bindingType, HandleType>::BufferType Allocated<bindingType, HandleType>::create_buffer(BufferCreateInfoType const &create_info)
inline typename Allocated<bindingType, HandleType>::BufferType Allocated<bindingType, HandleType>::create_buffer(BufferCreateInfoType const &create_info, DeviceSizeType alignment)
{
if constexpr (bindingType == vkb::BindingType::Cpp)
{
return create_buffer_impl(create_info);
return create_buffer_impl(create_info, alignment);
}
else
{
return static_cast<VkBuffer>(create_buffer_impl(reinterpret_cast<vk::BufferCreateInfo const &>(create_info)));
return static_cast<VkBuffer>(create_buffer_impl(reinterpret_cast<vk::BufferCreateInfo const &>(create_info), alignment));
}
}

template <vkb::BindingType bindingType, typename HandleType>
inline vk::Buffer Allocated<bindingType, HandleType>::create_buffer_impl(vk::BufferCreateInfo const &create_info)
inline vk::Buffer Allocated<bindingType, HandleType>::create_buffer_impl(vk::BufferCreateInfo const &create_info, DeviceSizeType alignment)
{
vk::Buffer buffer = VK_NULL_HANDLE;
VmaAllocationInfo allocation_info{};

auto result = vmaCreateBuffer(
get_memory_allocator(),
reinterpret_cast<VkBufferCreateInfo const *>(&create_info),
&allocation_create_info,
reinterpret_cast<VkBuffer *>(&buffer),
&allocation,
&allocation_info);
auto result = VK_SUCCESS;
if (alignment == 0)
{
result = vmaCreateBuffer(
get_memory_allocator(),
reinterpret_cast<VkBufferCreateInfo const *>(&create_info),
&allocation_create_info,
reinterpret_cast<VkBuffer *>(&buffer),
&allocation,
&allocation_info);
}
else
{
result = vmaCreateBufferWithAlignment(
get_memory_allocator(),
reinterpret_cast<VkBufferCreateInfo const *>(&create_info),
&allocation_create_info,
alignment,
reinterpret_cast<VkBuffer *>(&buffer),
&allocation,
&allocation_info);
}

if (result != VK_SUCCESS)
{
Expand Down
18 changes: 17 additions & 1 deletion framework/core/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ struct BufferBuilder
BufferPtr<bindingType> build_unique(vkb::core::Device<bindingType> &device) const;
BufferBuilder &with_flags(BufferCreateFlagsType flags);
BufferBuilder &with_usage(BufferUsageFlagsType usage);
BufferBuilder &with_alignment(DeviceSizeType align);
DeviceSizeType get_alignment() const
{
return alignment;
}

protected:
DeviceSizeType alignment{0};
};

using BufferBuilderC = BufferBuilder<vkb::BindingType::C>;
Expand Down Expand Up @@ -98,6 +106,13 @@ inline BufferBuilder<bindingType> &BufferBuilder<bindingType>::with_usage(Buffer
return *this;
}

template <vkb::BindingType bindingType>
inline BufferBuilder<bindingType> &BufferBuilder<bindingType>::with_alignment(DeviceSizeType align)
{
this->alignment = align;
return *this;
}

/*=========================================================*/

template <vkb::BindingType bindingType>
Expand Down Expand Up @@ -221,6 +236,7 @@ inline Buffer<bindingType>::Buffer(vkb::core::Device<bindingType> &device,
BufferBuilder<bindingType>(size)
.with_usage(buffer_usage)
.with_vma_usage(memory_usage)
.with_alignment(0)
.with_vma_flags(flags)
.with_queue_families(queue_family_indices)
.with_implicit_sharing_mode())
Expand All @@ -230,7 +246,7 @@ template <vkb::BindingType bindingType>
inline Buffer<bindingType>::Buffer(vkb::core::Device<bindingType> &device, const BufferBuilder<bindingType> &builder) :
ParentType(builder.get_allocation_create_info(), nullptr, &device), size(builder.get_create_info().size)
{
this->set_handle(this->create_buffer(builder.get_create_info()));
this->set_handle(this->create_buffer(builder.get_create_info(), builder.get_alignment()));
if (!builder.get_debug_name().empty())
{
this->set_debug_name(builder.get_debug_name());
Expand Down
8 changes: 8 additions & 0 deletions samples/extensions/ray_queries/ray_queries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ bool RayQueries::prepare(const vkb::ApplicationOptions &options)
device_features.pNext = &acceleration_structure_features;
vkGetPhysicalDeviceFeatures2(get_device().get_gpu().get_handle(), &device_features);

acceleration_structure_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
VkPhysicalDeviceProperties2 device_properties{};
device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
device_properties.pNext = &acceleration_structure_properties;
vkGetPhysicalDeviceProperties2(get_device().get_gpu().get_handle(), &device_properties);

camera.type = vkb::CameraType::FirstPerson;
camera.set_perspective(60.0f, static_cast<float>(width) / static_cast<float>(height), 0.1f, 512.0f);
camera.set_rotation(glm::vec3(0.0f, 90.0f, 0.0f));
Expand Down Expand Up @@ -225,6 +231,7 @@ void RayQueries::create_top_level_acceleration_structure()
// Top Level AS with single instance
top_level_acceleration_structure = std::make_unique<vkb::core::AccelerationStructure>(get_device(), VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR);
top_level_acceleration_structure->add_instance_geometry(instances_buffer, 1);
top_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment);
top_level_acceleration_structure->build(queue);
}

Expand Down Expand Up @@ -270,6 +277,7 @@ void RayQueries::create_bottom_level_acceleration_structure()
get_buffer_device_address(vertex_buffer->get_handle()),
get_buffer_device_address(index_buffer->get_handle()));
}
bottom_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment);
bottom_level_acceleration_structure->build(queue, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR);
}

Expand Down
13 changes: 7 additions & 6 deletions samples/extensions/ray_queries/ray_queries.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ class RayQueries : public ApiVulkanSample
std::unique_ptr<vkb::core::BufferC> uniform_buffer{nullptr};

// Ray tracing structures
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{};
std::unique_ptr<vkb::core::AccelerationStructure> top_level_acceleration_structure = nullptr;
std::unique_ptr<vkb::core::AccelerationStructure> bottom_level_acceleration_structure = nullptr;
uint64_t get_buffer_device_address(VkBuffer buffer);
void create_top_level_acceleration_structure();
void create_bottom_level_acceleration_structure();
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{};
VkPhysicalDeviceAccelerationStructurePropertiesKHR acceleration_structure_properties{};
std::unique_ptr<vkb::core::AccelerationStructure> top_level_acceleration_structure = nullptr;
std::unique_ptr<vkb::core::AccelerationStructure> bottom_level_acceleration_structure = nullptr;
uint64_t get_buffer_device_address(VkBuffer buffer);
void create_top_level_acceleration_structure();
void create_bottom_level_acceleration_structure();

VkPipeline pipeline{VK_NULL_HANDLE};
VkPipelineLayout pipeline_layout{VK_NULL_HANDLE};
Expand Down
42 changes: 32 additions & 10 deletions samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ void RaytracingExtended::create_bottom_level_acceleration_structure(bool is_upda
model_buffer.vertex_offset + (model_buffer.is_static ? static_vertex_handle : dynamic_vertex_handle),
model_buffer.index_offset + (model_buffer.is_static ? static_index_handle : dynamic_index_handle));
}
model_buffer.bottom_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment);
model_buffer.bottom_level_acceleration_structure->build(queue,
model_buffer.is_static ? VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR | VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR,
is_update ? VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR : VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR);
Expand Down Expand Up @@ -458,6 +459,7 @@ void RaytracingExtended::create_bottom_level_acceleration_structure(bool is_upda
uint32_t primitive_count = model_buffer.num_triangles;

auto &acceleration_structure_build_sizes_info = model_buffer.buildSize;
acceleration_structure_build_sizes_info.pNext = nullptr;
acceleration_structure_build_sizes_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
vkGetAccelerationStructureBuildSizesKHR(
get_device().get_handle(),
Expand Down Expand Up @@ -490,10 +492,11 @@ void RaytracingExtended::create_bottom_level_acceleration_structure(bool is_upda
// The actual build process starts here

// Create a scratch buffer as a temporary storage for the acceleration structure build
auto scratch_buffer = std::make_unique<vkb::core::BufferC>(get_device(),
model_buffer.buildSize.buildScratchSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_CPU_TO_GPU);
auto scratch_buffer = std::make_unique<vkb::core::BufferC>(get_device(), vkb::core::BufferBuilderC(model_buffer.buildSize.buildScratchSize)
.with_usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.with_vma_usage(VMA_MEMORY_USAGE_GPU_ONLY)
.with_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment));

{
VkAccelerationStructureBuildGeometryInfoKHR acceleration_build_geometry_info{};
acceleration_build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
Expand Down Expand Up @@ -659,6 +662,7 @@ void RaytracingExtended::create_top_level_acceleration_structure(bool print_time
{
top_level_acceleration_structure->update_instance_geometry(instance_uid, instances_buffer, static_cast<uint32_t>(instances.size()));
}
top_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment);
top_level_acceleration_structure->build(queue);
#else
VkDeviceOrHostAddressConstKHR instance_data_device_address{};
Expand Down Expand Up @@ -723,9 +727,10 @@ void RaytracingExtended::create_top_level_acceleration_structure(bool print_time

// Create a scratch buffer as a temporary storage for the acceleration structure build
auto scratch_buffer = std::make_unique<vkb::core::BufferC>(get_device(),
acceleration_structure_build_sizes_info.buildScratchSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_CPU_TO_GPU);
vkb::core::BufferBuilderC(acceleration_structure_build_sizes_info.buildScratchSize)
.with_usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT)
.with_vma_usage(VMA_MEMORY_USAGE_GPU_ONLY)
.with_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment));

VkAccelerationStructureBuildGeometryInfoKHR acceleration_build_geometry_info{};
acceleration_build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
Expand Down Expand Up @@ -857,9 +862,21 @@ void RaytracingExtended::create_shader_binding_tables()

// Raygen
// Create binding table buffers for each shader type
raygen_shader_binding_table = std::make_unique<vkb::core::BufferC>(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0);
miss_shader_binding_table = std::make_unique<vkb::core::BufferC>(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0);
hit_shader_binding_table = std::make_unique<vkb::core::BufferC>(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0);
raygen_shader_binding_table = std::make_unique<vkb::core::BufferC>(get_device(), vkb::core::BufferBuilderC(handle_size)
.with_usage(sbt_buffer_usage_flags)
.with_vma_usage(sbt_memory_usage)
.with_vma_flags(0)
.with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment));
miss_shader_binding_table = std::make_unique<vkb::core::BufferC>(get_device(), vkb::core::BufferBuilderC(handle_size)
.with_usage(sbt_buffer_usage_flags)
.with_vma_usage(sbt_memory_usage)
.with_vma_flags(0)
.with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment));
hit_shader_binding_table = std::make_unique<vkb::core::BufferC>(get_device(), vkb::core::BufferBuilderC(handle_size)
.with_usage(sbt_buffer_usage_flags)
.with_vma_usage(sbt_memory_usage)
.with_vma_flags(0)
.with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment));

// Copy the pipeline's shader handles into a host buffer
std::vector<uint8_t> shader_handle_storage(sbt_size);
Expand Down Expand Up @@ -1350,8 +1367,13 @@ bool RaytracingExtended::prepare(const vkb::ApplicationOptions &options)
std::set<VkImageUsageFlagBits> image_usage_flags = {VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT};
get_render_context().update_swapchain(image_usage_flags);

// Get the acceleration structure properties
acceleration_structure_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;

// Get the ray tracing pipeline properties, which we'll need later on in the sample
ray_tracing_pipeline_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
ray_tracing_pipeline_properties.pNext = &acceleration_structure_properties;

VkPhysicalDeviceProperties2 device_properties{};
device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
device_properties.pNext = &ray_tracing_pipeline_properties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
class RaytracingExtended : public ApiVulkanSample
{
public:
VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties{};
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{};
VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties{};
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{};
VkPhysicalDeviceAccelerationStructurePropertiesKHR acceleration_structure_properties{};

enum RenderMode : uint32_t
{
Expand Down
Loading