diff --git a/framework/core/acceleration_structure.cpp b/framework/core/acceleration_structure.cpp index f14f10d7c..4ad0885e2 100644 --- a/framework/core/acceleration_structure.cpp +++ b/framework/core/acceleration_structure.cpp @@ -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( 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; diff --git a/framework/core/acceleration_structure.h b/framework/core/acceleration_structure.h index 5dc7ea76c..0c29a919f 100644 --- a/framework/core/acceleration_structure.h +++ b/framework/core/acceleration_structure.h @@ -133,6 +133,11 @@ class AccelerationStructure geometries.clear(); } + void set_scrach_buffer_alignment(VkDeviceSize alignment) + { + scratch_buffer_alignment = alignment; + } + private: vkb::core::DeviceC &device; @@ -144,6 +149,8 @@ class AccelerationStructure VkAccelerationStructureBuildSizesInfoKHR build_sizes_info{}; + VkDeviceSize scratch_buffer_alignment{0}; + struct Geometry { VkAccelerationStructureGeometryKHR geometry{}; @@ -159,4 +166,4 @@ class AccelerationStructure std::unique_ptr buffer{nullptr}; }; } // namespace core -} // namespace vkb \ No newline at end of file +} // namespace vkb diff --git a/framework/core/allocated.h b/framework/core/allocated.h index e62ce9cd0..e224f5edb 100644 --- a/framework/core/allocated.h +++ b/framework/core/allocated.h @@ -300,7 +300,7 @@ class Allocated : public vkb::core::VulkanResource * 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. @@ -338,7 +338,7 @@ class Allocated : public vkb::core::VulkanResource 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 = {}; @@ -403,31 +403,46 @@ inline void Allocated::clear() } template -inline typename Allocated::BufferType Allocated::create_buffer(BufferCreateInfoType const &create_info) +inline typename Allocated::BufferType Allocated::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(create_buffer_impl(reinterpret_cast(create_info))); + return static_cast(create_buffer_impl(reinterpret_cast(create_info), alignment)); } } template -inline vk::Buffer Allocated::create_buffer_impl(vk::BufferCreateInfo const &create_info) +inline vk::Buffer Allocated::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(&create_info), - &allocation_create_info, - reinterpret_cast(&buffer), - &allocation, - &allocation_info); + auto result = VK_SUCCESS; + if (alignment == 0) + { + result = vmaCreateBuffer( + get_memory_allocator(), + reinterpret_cast(&create_info), + &allocation_create_info, + reinterpret_cast(&buffer), + &allocation, + &allocation_info); + } + else + { + result = vmaCreateBufferWithAlignment( + get_memory_allocator(), + reinterpret_cast(&create_info), + &allocation_create_info, + alignment, + reinterpret_cast(&buffer), + &allocation, + &allocation_info); + } if (result != VK_SUCCESS) { diff --git a/framework/core/buffer.h b/framework/core/buffer.h index f7c9f75c5..5bcd4439d 100644 --- a/framework/core/buffer.h +++ b/framework/core/buffer.h @@ -56,6 +56,14 @@ struct BufferBuilder BufferPtr build_unique(vkb::core::Device &device) const; BufferBuilder &with_flags(BufferCreateFlagsType flags); BufferBuilder &with_usage(BufferUsageFlagsType usage); + BufferBuilder &with_alignment(DeviceSizeType align); + DeviceSizeType get_alignment() const + { + return alignment; + } + + private: + DeviceSizeType alignment{0}; }; using BufferBuilderC = BufferBuilder; @@ -98,6 +106,13 @@ inline BufferBuilder &BufferBuilder::with_usage(Buffer return *this; } +template +inline BufferBuilder &BufferBuilder::with_alignment(DeviceSizeType align) +{ + this->alignment = align; + return *this; +} + /*=========================================================*/ template @@ -221,6 +236,7 @@ inline Buffer::Buffer(vkb::core::Device &device, BufferBuilder(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()) @@ -230,7 +246,7 @@ template inline Buffer::Buffer(vkb::core::Device &device, const BufferBuilder &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()); diff --git a/samples/extensions/ray_queries/ray_queries.cpp b/samples/extensions/ray_queries/ray_queries.cpp index d7cfcb193..4d311c0da 100644 --- a/samples/extensions/ray_queries/ray_queries.cpp +++ b/samples/extensions/ray_queries/ray_queries.cpp @@ -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(width) / static_cast(height), 0.1f, 512.0f); camera.set_rotation(glm::vec3(0.0f, 90.0f, 0.0f)); @@ -225,6 +231,7 @@ void RayQueries::create_top_level_acceleration_structure() // Top Level AS with single instance top_level_acceleration_structure = std::make_unique(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); } @@ -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); } diff --git a/samples/extensions/ray_queries/ray_queries.h b/samples/extensions/ray_queries/ray_queries.h index 729e22ae8..8d4f6f420 100644 --- a/samples/extensions/ray_queries/ray_queries.h +++ b/samples/extensions/ray_queries/ray_queries.h @@ -74,12 +74,13 @@ class RayQueries : public ApiVulkanSample std::unique_ptr uniform_buffer{nullptr}; // Ray tracing structures - VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{}; - std::unique_ptr top_level_acceleration_structure = nullptr; - std::unique_ptr 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 top_level_acceleration_structure = nullptr; + std::unique_ptr 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}; diff --git a/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp b/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp index 644dd37f8..0723305b8 100644 --- a/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp +++ b/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp @@ -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); @@ -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(), @@ -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(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(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; @@ -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(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{}; @@ -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(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; @@ -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(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0); - miss_shader_binding_table = std::make_unique(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0); - hit_shader_binding_table = std::make_unique(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0); + raygen_shader_binding_table = std::make_unique(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(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(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 shader_handle_storage(sbt_size); @@ -1350,8 +1367,13 @@ bool RaytracingExtended::prepare(const vkb::ApplicationOptions &options) std::set 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; diff --git a/samples/extensions/ray_tracing_extended/ray_tracing_extended.h b/samples/extensions/ray_tracing_extended/ray_tracing_extended.h index b31144401..7fc709e74 100644 --- a/samples/extensions/ray_tracing_extended/ray_tracing_extended.h +++ b/samples/extensions/ray_tracing_extended/ray_tracing_extended.h @@ -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 { diff --git a/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp b/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp index d66cbe69e..8e754623f 100644 --- a/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp +++ b/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp @@ -172,7 +172,7 @@ void RayTracingPositionFetch::create_bottom_level_acceleration_structure() VK_GEOMETRY_OPAQUE_BIT_KHR); } } - + bottom_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment); // To access vertex positions from a shader, we need to set the VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR for the bottom level acceleration structure VkBuildAccelerationStructureFlagsKHR acceleration_build_flags = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR | VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; bottom_level_acceleration_structure->build(queue, acceleration_build_flags, VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR); @@ -204,6 +204,7 @@ void RayTracingPositionFetch::create_top_level_acceleration_structure() top_level_acceleration_structure = std::make_unique(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); } @@ -246,9 +247,18 @@ void RayTracingPositionFetch::create_shader_binding_tables() // Raygen // Create binding table buffers for each shader type - raygen_shader_binding_table = std::make_unique(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0); - miss_shader_binding_table = std::make_unique(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0); - hit_shader_binding_table = std::make_unique(get_device(), handle_size, sbt_buffer_usage_flags, sbt_memory_usage, 0); + raygen_shader_binding_table = std::make_unique(get_device(), vkb::core::BufferBuilderC(handle_size) + .with_usage(sbt_buffer_usage_flags) + .with_vma_usage(sbt_memory_usage) + .with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment)); + miss_shader_binding_table = std::make_unique(get_device(), vkb::core::BufferBuilderC(handle_size) + .with_usage(sbt_buffer_usage_flags) + .with_vma_usage(sbt_memory_usage) + .with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment)); + hit_shader_binding_table = std::make_unique(get_device(), vkb::core::BufferBuilderC(handle_size) + .with_usage(sbt_buffer_usage_flags) + .with_vma_usage(sbt_memory_usage) + .with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment)); // Copy the pipeline's shader handles into a host buffer std::vector shader_handle_storage(sbt_size); @@ -551,8 +561,12 @@ bool RayTracingPositionFetch::prepare(const vkb::ApplicationOptions &options) // This sample renders the UI overlay on top of the ray tracing output, so we need to disable color attachment clears update_render_pass_flags(RenderPassCreateFlags::ColorAttachmentLoad); + 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; diff --git a/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.h b/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.h index b1b1b3876..196398a45 100644 --- a/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.h +++ b/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.h @@ -23,8 +23,9 @@ class RayTracingPositionFetch : 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{}; std::unique_ptr bottom_level_acceleration_structure{nullptr}; std::unique_ptr top_level_acceleration_structure{nullptr}; diff --git a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp index a7654d599..26a529338 100644 --- a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp +++ b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp @@ -271,9 +271,10 @@ void RaytracingReflection::create_bottom_level_acceleration_structure(ObjModelGp // Create a scratch buffer as a temporary storage for the acceleration structure build std::unique_ptr sc_buffer; - sc_buffer = std::make_unique(get_device(), acceleration_structure_build_sizes_info.buildScratchSize, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU); + sc_buffer = std::make_unique(get_device(), vkb::core::BufferBuilderC(acceleration_structure_build_sizes_info.buildScratchSize) + .with_usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + .with_vma_usage(VMA_MEMORY_USAGE_CPU_TO_GPU) + .with_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment)); VkAccelerationStructureBuildGeometryInfoKHR acceleration_build_geometry_info{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR}; acceleration_build_geometry_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; @@ -363,9 +364,10 @@ void RaytracingReflection::create_top_level_acceleration_structure(std::vector sc_buffer; - sc_buffer = std::make_unique(get_device(), acceleration_structure_build_sizes_info.buildScratchSize, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - VMA_MEMORY_USAGE_CPU_TO_GPU); + sc_buffer = std::make_unique(get_device(), vkb::core::BufferBuilderC(acceleration_structure_build_sizes_info.buildScratchSize) + .with_usage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + .with_vma_usage(VMA_MEMORY_USAGE_CPU_TO_GPU) + .with_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment)); VkAccelerationStructureBuildGeometryInfoKHR acceleration_build_geometry_info{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR}; acceleration_build_geometry_info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; @@ -575,9 +577,18 @@ void RaytracingReflection::create_shader_binding_tables() const VmaMemoryUsage sbt_memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU; // Create binding table buffers for each shader type - raygen_shader_binding_table = std::make_unique(get_device(), handle_size_aligned * rgen_index.size(), sbt_buffer_usage_flags, sbt_memory_usage, 0); - miss_shader_binding_table = std::make_unique(get_device(), handle_size_aligned * miss_index.size(), sbt_buffer_usage_flags, sbt_memory_usage, 0); - hit_shader_binding_table = std::make_unique(get_device(), handle_size_aligned * hit_index.size(), sbt_buffer_usage_flags, sbt_memory_usage, 0); + raygen_shader_binding_table = std::make_unique(get_device(), vkb::core::BufferBuilderC(handle_size_aligned * rgen_index.size()) + .with_usage(sbt_buffer_usage_flags) + .with_vma_usage(sbt_memory_usage) + .with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment)); + miss_shader_binding_table = std::make_unique(get_device(), vkb::core::BufferBuilderC(handle_size_aligned * miss_index.size()) + .with_usage(sbt_buffer_usage_flags) + .with_vma_usage(sbt_memory_usage) + .with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment)); + hit_shader_binding_table = std::make_unique(get_device(), vkb::core::BufferBuilderC(handle_size_aligned * hit_index.size()) + .with_usage(sbt_buffer_usage_flags) + .with_vma_usage(sbt_memory_usage) + .with_alignment(ray_tracing_pipeline_properties.shaderGroupBaseAlignment)); // Copy the pipeline's shader handles into a host buffer const auto group_count = static_cast(rgen_index.size() + miss_index.size() + hit_index.size()); diff --git a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h index c338ca38f..d2c38f17e 100644 --- a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h +++ b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h @@ -61,8 +61,9 @@ class RaytracingReflection : public ApiVulkanSample }; public: - VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR}; - VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; + VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR}; + VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; + VkPhysicalDeviceAccelerationStructurePropertiesKHR acceleration_structure_properties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR}; std::vector bottom_level_acceleration_structure; AccelerationStructure top_level_acceleration_structure; diff --git a/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp b/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp index 0a0749580..2d4b2e04d 100644 --- a/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp +++ b/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp @@ -150,6 +150,12 @@ bool MobileNerfRayQuery::prepare(const vkb::ApplicationOptions &options) camera.set_perspective(60.0f, static_cast(width) / static_cast(height), 0.01f, 256.0f); + 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); + // Each models may have submodels int models_entry = 0; for (int model_index = 0; model_index < num_models; model_index++) @@ -837,6 +843,7 @@ void MobileNerfRayQuery::create_top_level_acceleration_structure() top_level_acceleration_structure = std::make_unique(get_device(), VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR); top_level_acceleration_structure->add_instance_geometry(instances_buffer, acceleration_structure_instances.size()); + top_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment); top_level_acceleration_structure->build(queue); } @@ -880,6 +887,7 @@ void MobileNerfRayQuery::create_bottom_level_acceleration_structure(int model_en get_buffer_device_address(model.vertex_buffer->get_handle()), get_buffer_device_address(model.index_buffer->get_handle())); } + model.bottom_level_acceleration_structure->set_scrach_buffer_alignment(acceleration_structure_properties.minAccelerationStructureScratchOffsetAlignment); model.bottom_level_acceleration_structure->build(queue, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR); } diff --git a/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.h b/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.h index 3d4b4bf50..a77419727 100644 --- a/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.h +++ b/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.h @@ -167,6 +167,9 @@ class MobileNerfRayQuery : public ApiVulkanSample // Feature map format VkFormat feature_map_format = VK_FORMAT_R16G16B16A16_SFLOAT; + // Acceleration structure properties. + VkPhysicalDeviceAccelerationStructurePropertiesKHR acceleration_structure_properties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR}; + void read_json_map(); void load_shaders(); void create_uniforms();