From 03ca4e3c36ecd03eff012b137ddf4de0312e3e51 Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Mon, 28 Nov 2022 21:26:40 +0100 Subject: [PATCH] Implement top-level acceleration structures in framework and reduce code in realtime ray tracing example via substitution Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- README.md | 2 +- include/vkcv/Core.hpp | 20 + projects/CMakeLists.txt | 2 +- projects/rt_ambient_occlusion/.gitignore | 1 + .../CMakeLists.txt | 18 +- .../README.md | 10 +- .../resources/shaders/ambientOcclusion.rchit | 4 +- .../resources/shaders/ambientOcclusion.rgen | 0 .../resources/shaders/ambientOcclusion.rmiss | 0 .../src/main.cpp | 63 +-- projects/rtx_ambient_occlusion/.gitignore | 1 - .../src/RTX/ASManager.cpp | 468 ------------------ .../src/RTX/ASManager.hpp | 187 ------- .../rtx_ambient_occlusion/src/RTX/RTX.cpp | 30 -- .../rtx_ambient_occlusion/src/RTX/RTX.hpp | 100 ---- ...occlusion.png => rt_ambient_occlusion.png} | 0 src/vkcv/AccelerationStructureManager.cpp | 309 +++++++++--- src/vkcv/AccelerationStructureManager.hpp | 16 +- src/vkcv/BufferManager.cpp | 26 +- src/vkcv/BufferManager.hpp | 10 +- src/vkcv/Core.cpp | 16 +- src/vkcv/DescriptorSetManager.cpp | 7 +- src/vkcv/RayTracingPipelineManager.cpp | 17 +- 23 files changed, 365 insertions(+), 942 deletions(-) create mode 100644 projects/rt_ambient_occlusion/.gitignore rename projects/{rtx_ambient_occlusion => rt_ambient_occlusion}/CMakeLists.txt (62%) rename projects/{rtx_ambient_occlusion => rt_ambient_occlusion}/README.md (50%) rename projects/{rtx_ambient_occlusion => rt_ambient_occlusion}/resources/shaders/ambientOcclusion.rchit (93%) rename projects/{rtx_ambient_occlusion => rt_ambient_occlusion}/resources/shaders/ambientOcclusion.rgen (100%) rename projects/{rtx_ambient_occlusion => rt_ambient_occlusion}/resources/shaders/ambientOcclusion.rmiss (100%) rename projects/{rtx_ambient_occlusion => rt_ambient_occlusion}/src/main.cpp (75%) delete mode 100644 projects/rtx_ambient_occlusion/.gitignore delete mode 100644 projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp delete mode 100644 projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp delete mode 100644 projects/rtx_ambient_occlusion/src/RTX/RTX.cpp delete mode 100644 projects/rtx_ambient_occlusion/src/RTX/RTX.hpp rename screenshots/{rtx_ambient_occlusion.png => rt_ambient_occlusion.png} (100%) diff --git a/README.md b/README.md index db60c73d..c45910f2 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ targets: - [particle_simulation](projects/particle_simulation/README.md) - [path_tracer](projects/path_tracer/README.md) - [ray_tracer](projects/ray_tracer/README.md) - - [rtx_ambient_occlusion](projects/rtx_ambient_occlusion/README.md) + - [rt_ambient_occlusion](projects/rt_ambient_occlusion/README.md) - [sph](projects/sph/README.md) - [voxelization](projects/voxelization/README.md) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index d7d850f7..3e5b6e5f 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -970,6 +970,16 @@ namespace vkcv { AccelerationStructureHandle createAccelerationStructure( const std::vector<GeometryData> &geometryData); + /** + * @brief Creates an acceleration structure handle built with a given list of + * other bottom-level acceleration structures. + * + * @param[in] handles List of acceleration structure handles + * @return Acceleration structure handle + */ + AccelerationStructureHandle createAccelerationStructure( + const std::vector<AccelerationStructureHandle> &handles); + /** * @brief the underlying vulkan handle for an acceleration structure * by its given acceleration structure handle. @@ -990,5 +1000,15 @@ namespace vkcv { [[nodiscard]] vk::Buffer getVulkanBuffer( const vkcv::AccelerationStructureHandle &handle) const; + /** + * @brief Returns the device address of an acceleration structure represented + * by a given acceleration structure handle. + * + * @param[in] handle Acceleration structure handle + * @return Device address of the acceleration structure + */ + [[nodiscard]] vk::DeviceAddress getAccelerationStructureDeviceAddress( + const vkcv::AccelerationStructureHandle &handle) const; + }; } // namespace vkcv diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 3860ec7a..322eaa5b 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -15,6 +15,6 @@ add_subdirectory(mpm) add_subdirectory(particle_simulation) add_subdirectory(path_tracer) add_subdirectory(ray_tracer) -add_subdirectory(rtx_ambient_occlusion) +add_subdirectory(rt_ambient_occlusion) add_subdirectory(sph) add_subdirectory(voxelization) \ No newline at end of file diff --git a/projects/rt_ambient_occlusion/.gitignore b/projects/rt_ambient_occlusion/.gitignore new file mode 100644 index 00000000..774481bc --- /dev/null +++ b/projects/rt_ambient_occlusion/.gitignore @@ -0,0 +1 @@ +rt_ambient_occlusion \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/CMakeLists.txt b/projects/rt_ambient_occlusion/CMakeLists.txt similarity index 62% rename from projects/rtx_ambient_occlusion/CMakeLists.txt rename to projects/rt_ambient_occlusion/CMakeLists.txt index 7a64f46b..a20dab4d 100644 --- a/projects/rtx_ambient_occlusion/CMakeLists.txt +++ b/projects/rt_ambient_occlusion/CMakeLists.txt @@ -1,25 +1,15 @@ cmake_minimum_required(VERSION 3.16) -project(rtx_ambient_occlusion) +project(rt_ambient_occlusion) # setting c++ standard for the project set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(rtx_source ${PROJECT_SOURCE_DIR}/src/RTX) - -set(rtx_sources - ${rtx_source}/RTX.hpp - ${rtx_source}/RTX.cpp - - ${rtx_source}/ASManager.hpp - ${rtx_source}/ASManager.cpp -) - # adding source files to the project -add_project(rtx_ambient_occlusion src/main.cpp ${rtx_sources}) +add_project(rt_ambient_occlusion src/main.cpp) # including headers of dependencies and the VkCV framework -target_include_directories(rtx_ambient_occlusion SYSTEM BEFORE PRIVATE +target_include_directories(rt_ambient_occlusion SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} @@ -29,7 +19,7 @@ target_include_directories(rtx_ambient_occlusion SYSTEM BEFORE PRIVATE ${vkcv_shader_compiler_include}) # linking with libraries from all dependencies and the VkCV framework -target_link_libraries(rtx_ambient_occlusion +target_link_libraries(rt_ambient_occlusion vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera diff --git a/projects/rtx_ambient_occlusion/README.md b/projects/rt_ambient_occlusion/README.md similarity index 50% rename from projects/rtx_ambient_occlusion/README.md rename to projects/rt_ambient_occlusion/README.md index d9fd98cf..14c6c552 100644 --- a/projects/rtx_ambient_occlusion/README.md +++ b/projects/rt_ambient_occlusion/README.md @@ -1,7 +1,7 @@ -# RTX ambient occlusion +# RT ambient occlusion An example project to show usage of hardware accelerated ray tracing with the VkCV framework - + ## Details @@ -14,12 +14,6 @@ ambient occlusion in realtime. Here is a list of the used extensions: -- [VK_KHR_get_physical_device_properties2](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_get_physical_device_properties2.html) -- [VK_KHR_maintenance3](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_maintenance3.html) -- [VK_KHR_deferred_host_operations](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_deferred_host_operations.html) -- [VK_KHR_spirv_1_4](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_spirv_1_4.html) -- [VK_KHR_pipeline_library](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_pipeline_library.html) -- [VK_EXT_descriptor_indexing](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_descriptor_indexing.html) - [VK_KHR_buffer_device_address](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_buffer_device_address.html) - [VK_KHR_acceleration_structure](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_acceleration_structure.html) - [VK_KHR_ray_tracing_pipeline](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_ray_tracing_pipeline.html) diff --git a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rchit b/projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rchit similarity index 93% rename from projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rchit rename to projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rchit index 03806c4f..807fe544 100644 --- a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rchit +++ b/projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rchit @@ -11,12 +11,12 @@ layout(location = 0) rayPayloadInEXT Payload { vec3 worldNormal; } payload; -layout(binding = 2, set = 0, scalar) buffer rtxVertices +layout(binding = 2, set = 0, scalar) buffer rtVertices { float vertices[]; }; -layout(binding = 3, set = 0, scalar) buffer rtxIndices +layout(binding = 3, set = 0, scalar) buffer rtIndices { uint16_t indices[]; }; diff --git a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rgen b/projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rgen similarity index 100% rename from projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rgen rename to projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rgen diff --git a/projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss b/projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss similarity index 100% rename from projects/rtx_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss rename to projects/rt_ambient_occlusion/resources/shaders/ambientOcclusion.rmiss diff --git a/projects/rtx_ambient_occlusion/src/main.cpp b/projects/rt_ambient_occlusion/src/main.cpp similarity index 75% rename from projects/rtx_ambient_occlusion/src/main.cpp rename to projects/rt_ambient_occlusion/src/main.cpp index 1c491097..fd722518 100644 --- a/projects/rtx_ambient_occlusion/src/main.cpp +++ b/projects/rt_ambient_occlusion/src/main.cpp @@ -2,14 +2,13 @@ #include <vkcv/camera/CameraManager.hpp> #include <vkcv/geometry/Teapot.hpp> #include <vkcv/shader/GLSLCompiler.hpp> -#include "RTX/RTX.hpp" /** * Note: This project is based on the following tutorial https://github.com/Apress/Ray-Tracing-Gems-II/tree/main/Chapter_16. */ int main(int argc, const char** argv) { - const std::string applicationName = "RTX Ambient Occlusion"; + const std::string applicationName = "Ray Tracing: Ambient Occlusion"; vkcv::Features features; features.requireExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); @@ -49,8 +48,6 @@ int main(int argc, const char** argv) { features ); - vkcv::rtx::ASManager asManager(&core); - vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 600, true); vkcv::geometry::Teapot teapot (glm::vec3(0.0f), 1.0f); @@ -65,43 +62,36 @@ int main(int argc, const char** argv) { vkcv::shader::GLSLCompiler compiler (vkcv::shader::GLSLCompileTarget::RAY_TRACING); - vkcv::ShaderProgram rtxShaderProgram; + vkcv::ShaderProgram shaderProgram; compiler.compile(vkcv::ShaderStage::RAY_GEN, std::filesystem::path("resources/shaders/ambientOcclusion.rgen"), - [&rtxShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - rtxShaderProgram.addShader(shaderStage, path); + [&shaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + shaderProgram.addShader(shaderStage, path); }); compiler.compile(vkcv::ShaderStage::RAY_CLOSEST_HIT, std::filesystem::path("resources/shaders/ambientOcclusion.rchit"), - [&rtxShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - rtxShaderProgram.addShader(shaderStage, path); + [&shaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + shaderProgram.addShader(shaderStage, path); }); compiler.compile(vkcv::ShaderStage::RAY_MISS, std::filesystem::path("resources/shaders/ambientOcclusion.rmiss"), - [&rtxShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { - rtxShaderProgram.addShader(shaderStage, path); + [&shaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + shaderProgram.addShader(shaderStage, path); }); std::vector<vkcv::DescriptorSetHandle> descriptorSetHandles; std::vector<vkcv::DescriptorSetLayoutHandle> descriptorSetLayoutHandles; - vkcv::DescriptorSetLayoutHandle rtxShaderDescriptorSetLayout = core.createDescriptorSetLayout(rtxShaderProgram.getReflectedDescriptors().at(0)); - vkcv::DescriptorSetHandle rtxShaderDescriptorSet = core.createDescriptorSet(rtxShaderDescriptorSetLayout); - descriptorSetHandles.push_back(rtxShaderDescriptorSet); - descriptorSetLayoutHandles.push_back(rtxShaderDescriptorSetLayout); + vkcv::DescriptorSetLayoutHandle shaderDescriptorSetLayout = core.createDescriptorSetLayout(shaderProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle shaderDescriptorSet = core.createDescriptorSet(shaderDescriptorSetLayout); + descriptorSetHandles.push_back(shaderDescriptorSet); + descriptorSetLayoutHandles.push_back(shaderDescriptorSetLayout); vkcv::AccelerationStructureHandle blas = core.createAccelerationStructure({ geometryData }); - - asManager.add(geometryData, blas); - - // init RTXModule - vkcv::rtx::RTXModule rtxModule ( - &core, - &asManager, - descriptorSetHandles - ); + vkcv::AccelerationStructureHandle tlas = core.createAccelerationStructure({ blas }); { vkcv::DescriptorWrites writes; + writes.writeAcceleration(1, { core.getVulkanAccelerationStructure(tlas) }); writes.writeStorageBuffer(2, geometryData.getVertexBufferBinding().buffer); writes.writeStorageBuffer(3, geometryData.getIndexBuffer()); core.writeDescriptorSet(descriptorSetHandles[0], writes); @@ -114,16 +104,14 @@ int main(int argc, const char** argv) { glm::vec4 camera_forward; // for computing ray direction }; - auto rtxPipeline = core.createRayTracingPipeline(vkcv::RayTracingPipelineConfig( - rtxShaderProgram, + auto pipeline = core.createRayTracingPipeline(vkcv::RayTracingPipelineConfig( + shaderProgram, descriptorSetLayoutHandles )); vkcv::ImageHandle depthBuffer; const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); - - vkcv::DescriptorWrites rtxWrites; core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, uint32_t swapchainWidth, uint32_t swapchainHeight) { @@ -149,22 +137,25 @@ int main(int argc, const char** argv) { raytracingPushData.camera_up = glm::vec4(cameraManager.getActiveCamera().getUp(),0); raytracingPushData.camera_forward = glm::vec4(cameraManager.getActiveCamera().getFront(),0); - vkcv::PushConstants pushConstantsRTX = vkcv::pushConstants<RaytracingPushConstantData>(); - pushConstantsRTX.appendDrawcall(raytracingPushData); + vkcv::PushConstants pushConstants = vkcv::pushConstants<RaytracingPushConstantData>(); + pushConstants.appendDrawcall(raytracingPushData); + + { + vkcv::DescriptorWrites writes; + writes.writeStorageImage(0, swapchainInput); + core.writeDescriptorSet(shaderDescriptorSet, writes); + } auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - rtxWrites.writeStorageImage(0, swapchainInput); - core.writeDescriptorSet(rtxShaderDescriptorSet, rtxWrites); - core.prepareImageForStorage(cmdStream, swapchainInput); core.recordRayGenerationToCmdStream( cmdStream, - rtxPipeline, + pipeline, vkcv::DispatchSize(swapchainWidth, swapchainHeight), - { vkcv::useDescriptorSet(0, rtxShaderDescriptorSet) }, - pushConstantsRTX, + { vkcv::useDescriptorSet(0, shaderDescriptorSet) }, + pushConstants, windowHandle ); diff --git a/projects/rtx_ambient_occlusion/.gitignore b/projects/rtx_ambient_occlusion/.gitignore deleted file mode 100644 index 61b2ff94..00000000 --- a/projects/rtx_ambient_occlusion/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rtx_ambient_occlusion \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp b/projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp deleted file mode 100644 index b18cb345..00000000 --- a/projects/rtx_ambient_occlusion/src/RTX/ASManager.cpp +++ /dev/null @@ -1,468 +0,0 @@ -#include "ASManager.hpp" -#include <array> - -namespace vkcv::rtx { - - - ASManager::ASManager(vkcv::Core *core) : - m_core(core), - m_device(&(core->getContext().getDevice())){ - // INFO: Using RTX extensions implies that we cannot use the standard dispatcher from Vulkan because using RTX - // specific functions via vk::Device will result in validation errors. Instead we need to use a - // vk::DispatchLoaderDynamic which is used as dispatcher parameter of the device functions. - m_rtxDispatcher = vk::DispatchLoaderDynamic( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") ); - m_rtxDispatcher.init(m_core->getContext().getInstance()); - - // TODO: Recursive call of buildBLAS for bigger scenes. Currently, the RTX module only supports one mesh. - } - - ASManager::~ASManager() noexcept { - m_rtxDispatcher = vk::DispatchLoaderDynamic( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") ); - m_rtxDispatcher.init(m_core->getContext().getInstance()); - - // destroy every BLAS, its data containers and free used memory blocks - for (size_t i=0; i < m_bottomLevelAccelerationStructures.size(); i++) { - BottomLevelAccelerationStructure blas = m_bottomLevelAccelerationStructures[i]; - //m_core->getContext().getDevice().destroyAccelerationStructureKHR(blas.vulkanHandle, nullptr, m_rtxDispatcher); - } - - // destroy the TLAS, its data containers and free used memory blocks - TopLevelAccelerationStructure tlas = m_topLevelAccelerationStructure; - m_core->getContext().getDevice().destroyAccelerationStructureKHR(tlas.vulkanHandle, nullptr, m_rtxDispatcher); - m_core->getContext().getDevice().destroy(tlas.tlasBuffer.vulkanHandle); - m_core->getContext().getDevice().destroy(tlas.gpuBufferInstances.vulkanHandle); - - m_core->getContext().getDevice().freeMemory(tlas.tlasBuffer.deviceMemory); - m_core->getContext().getDevice().freeMemory(tlas.gpuBufferInstances.deviceMemory); - } - - - - vk::CommandPool ASManager::createCommandPool() { - vk::CommandPool commandPool; - vk::CommandPoolCreateInfo commandPoolCreateInfo; - commandPoolCreateInfo.setQueueFamilyIndex(m_core->getContext().getQueueManager().getComputeQueues()[0].familyIndex); - vk::Result res = m_device->createCommandPool(&commandPoolCreateInfo, nullptr, &commandPool); - if (res != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "ASManager: command pool could not be created! (%s)", vk::to_string(res).c_str()); - } - return commandPool; - }; - - vk::CommandBuffer ASManager::createAndBeginCommandBuffer(vk::CommandPool commandPool) - { - vk::CommandBufferAllocateInfo commandBufferAllocateInfo{}; - commandBufferAllocateInfo.setLevel(vk::CommandBufferLevel::ePrimary); - commandBufferAllocateInfo.setCommandPool(commandPool); - commandBufferAllocateInfo.setCommandBufferCount(1); - vk::CommandBuffer commandBuffer; - vk::Result result = m_device->allocateCommandBuffers(&commandBufferAllocateInfo, &commandBuffer); - if (result != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "ASManager: command buffer for Acceleration Strucutre Build could not be allocated! (%s)", vk::to_string(result).c_str()); - } - - const vk::CommandBufferBeginInfo beginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - commandBuffer.begin(beginInfo); - return commandBuffer; - } - - void ASManager::submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer) - { - commandBuffer.end(); - - vk::SubmitInfo submitInfo; - submitInfo.setCommandBufferCount(1); - submitInfo.setPCommandBuffers(&commandBuffer); - - vkcv::Queue queue = m_core->getContext().getQueueManager().getComputeQueues()[0]; - - queue.handle.submit(submitInfo); - queue.handle.waitIdle(); - - m_device->freeCommandBuffers(commandPool, 1, &commandBuffer); - m_device->destroyCommandPool(commandPool); - } - - vk::DeviceAddress ASManager::getBufferDeviceAddress(vk::Buffer buffer) - { - vk::BufferDeviceAddressInfo bufferDeviceAddressInfo(buffer); - return m_device->getBufferAddress(bufferDeviceAddressInfo); - } - - void ASManager::createBuffer(RTXBuffer& buffer) { - - vk::BufferCreateInfo bufferCreateInfo; - bufferCreateInfo.setFlags(vk::BufferCreateFlags()); - bufferCreateInfo.setUsage(buffer.bufferUsageFlagBits); - bufferCreateInfo.setSize(buffer.deviceSize); - - buffer.vulkanHandle = m_device->createBuffer(bufferCreateInfo); - vk::MemoryRequirements2 memoryRequirements2; - vk::MemoryDedicatedRequirements dedicatedRequirements; - vk::BufferMemoryRequirementsInfo2 bufferRequirements; - - bufferRequirements.setBuffer(buffer.vulkanHandle); - memoryRequirements2.pNext = &dedicatedRequirements; - m_device->getBufferMemoryRequirements2(&bufferRequirements, &memoryRequirements2); - - vk::PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties = m_core->getContext().getPhysicalDevice().getMemoryProperties(); - - uint32_t memoryTypeIndex = -1; - for (size_t i = 0; i < physicalDeviceMemoryProperties.memoryTypeCount; i++) { - if ((memoryRequirements2.memoryRequirements.memoryTypeBits & (1 << i)) - && (physicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & buffer.memoryPropertyFlagBits) == buffer.memoryPropertyFlagBits) { - memoryTypeIndex = i; - break; - } - } - - vk::MemoryAllocateInfo memoryAllocateInfo( - memoryRequirements2.memoryRequirements.size, // size of allocation in bytes - memoryTypeIndex // index identifying a memory type from the memoryTypes array of the vk::PhysicalDeviceMemoryProperties structure. - ); - vk::MemoryAllocateFlagsInfo allocateFlagsInfo( - vk::MemoryAllocateFlagBits::eDeviceAddress // vk::MemoryAllocateFlags - ); - memoryAllocateInfo.setPNext(&allocateFlagsInfo); // extend memory allocate info with allocate flag info - buffer.deviceMemory = m_device->allocateMemory(memoryAllocateInfo); - - uint32_t memoryOffset = 0; - m_device->bindBufferMemory(buffer.vulkanHandle, buffer.deviceMemory, memoryOffset); - - // only fill data in case of CPU buffer - if (buffer.bufferType == RTXBufferType::STAGING) { - void* mapped = m_device->mapMemory(buffer.deviceMemory, memoryOffset, buffer.deviceSize); - std::memcpy(mapped, buffer.data, buffer.deviceSize); - m_device->unmapMemory(buffer.deviceMemory); - } - } - - void ASManager::copyFromCPUToGPU(RTXBuffer& cpuBuffer, RTXBuffer& gpuBuffer) { - vk::CommandPool commandPool= createCommandPool(); - vk::CommandBuffer commandBuffer= createAndBeginCommandBuffer(commandPool); - vk::BufferCopy bufferCopy; - bufferCopy.size = cpuBuffer.deviceSize; - commandBuffer.copyBuffer(cpuBuffer.vulkanHandle, gpuBuffer.vulkanHandle, 1, &bufferCopy); - - submitCommandBuffer(commandPool,commandBuffer); - - m_device->destroyBuffer(cpuBuffer.vulkanHandle); - m_device->freeMemory(cpuBuffer.deviceMemory); - } - - void ASManager::buildBLAS(const vkcv::VertexData &vertexData) { - // TODO: organize hierarchical structure of multiple BLAS - - const auto& originalVertexBuffer = vertexData.getVertexBufferBindings()[0].buffer; - const auto& originalIndexBuffer = vertexData.getIndexBuffer(); - - const auto vbSize = m_core->getBufferSize(originalVertexBuffer); - - vk::DeviceAddress vertexBufferAddress = m_core->getBufferDeviceAddress(originalVertexBuffer);//getBufferDeviceAddress(vertexBuffer.vulkanHandle); - vk::DeviceAddress indexBufferAddress = m_core->getBufferDeviceAddress(originalIndexBuffer);//getBufferDeviceAddress(indexBuffer.vulkanHandle); - - // triangle mesh data - vk::AccelerationStructureGeometryTrianglesDataKHR asTriangles( - vk::Format::eR32G32B32Sfloat, // vertex format - vertexBufferAddress, // vertex buffer address (vk::DeviceOrHostAddressConstKHR) - 3 * sizeof(float), // vertex stride (vk::DeviceSize) - uint32_t(vbSize / (3 * sizeof(float)) - 1), // maxVertex (uint32_t) - vk::IndexType::eUint16, // indexType (vk::IndexType) --> INFO: UINT16 oder UINT32! - indexBufferAddress, // indexData (vk::DeviceOrHostAddressConstKHR) - {} // transformData (vk::DeviceOrHostAddressConstKHR) - ); - - // Geometry data - vk::AccelerationStructureGeometryKHR asGeometry( - vk::GeometryTypeKHR::eTriangles, // The geometry type, e.g. triangles, AABBs, instances - asTriangles, // the geometry data - vk::GeometryFlagBitsKHR::eOpaque // This flag disables any-hit shaders to increase ray tracing performance - ); - - // Ranges for data lists - vk::AccelerationStructureBuildRangeInfoKHR asRangeInfo( - uint32_t(vertexData.getCount() / 3), // the primitiveCount (uint32_t) - 0, // primitiveOffset (uint32_t) - 0, // firstVertex (uint32_t) - 0 // transformOffset (uint32_t) - ); - - // Settings and array of geometries to build into BLAS - vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo( - vk::AccelerationStructureTypeKHR::eBottomLevel, // type of the AS: bottom vs. top - vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency - vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update - {}, // src AS (this seems to be for copying AS) - {}, // dst AS (this seems to be for copying AS) - 1, // the geometryCount. TODO: how many do we need? - &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry? - ); - - // Calculate memory needed for AS - vk::AccelerationStructureBuildSizesInfoKHR asBuildSizesInfo; - m_device->getAccelerationStructureBuildSizesKHR( - vk::AccelerationStructureBuildTypeKHR::eDevice, // build on device instead of host - &asBuildInfo, // pointer to build info - &asRangeInfo.primitiveCount, // array of number of primitives per geometry - &asBuildSizesInfo, // output pointer to store sizes - m_rtxDispatcher - ); - - // create buffer for acceleration structure - RTXBuffer blasBuffer; - blasBuffer.bufferType = RTXBufferType::ACCELERATION; - blasBuffer.deviceSize = asBuildSizesInfo.accelerationStructureSize; - blasBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR - | vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eStorageBuffer; - blasBuffer.memoryPropertyFlagBits = { vk::MemoryPropertyFlagBits::eDeviceLocal }; - - createBuffer(blasBuffer); - - // Create an empty AS object - vk::AccelerationStructureCreateInfoKHR asCreateInfo( - vk::AccelerationStructureCreateFlagsKHR(), // creation flags - blasBuffer.vulkanHandle, // allocated AS buffer. - 0, - asBuildSizesInfo.accelerationStructureSize, // size of the AS - asBuildInfo.type // type of the AS - ); - - // Create the intended AS object - vk::AccelerationStructureKHR blasKHR; - vk::Result res = m_device->createAccelerationStructureKHR( - &asCreateInfo, // AS create info - nullptr, // allocator callbacks - &blasKHR, // the AS - m_rtxDispatcher - ); - if (res != vk::Result::eSuccess) { - vkcv_log(vkcv::LogLevel::ERROR, "The Bottom Level Acceleration Structure could not be build! (%s)", vk::to_string(res).c_str()); - } - asBuildInfo.setDstAccelerationStructure(blasKHR); - - // Create temporary scratch buffer used for building the AS - RTXBuffer scratchBuffer; - scratchBuffer.bufferType = RTXBufferType::SCRATCH; - scratchBuffer.deviceSize = asBuildSizesInfo.buildScratchSize; - scratchBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eStorageBuffer; - scratchBuffer.memoryPropertyFlagBits = { vk::MemoryPropertyFlagBits::eDeviceLocal }; - - createBuffer(scratchBuffer); - - asBuildInfo.setScratchData(getBufferDeviceAddress(scratchBuffer.vulkanHandle)); - - // Pointer to rangeInfo, used later for build - vk::AccelerationStructureBuildRangeInfoKHR* pointerToRangeInfo = &asRangeInfo; - - vk::CommandPool commandPool = createCommandPool(); - vk::CommandBuffer commandBuffer = createAndBeginCommandBuffer(commandPool); - - commandBuffer.buildAccelerationStructuresKHR(1, &asBuildInfo, &pointerToRangeInfo, m_rtxDispatcher); - - submitCommandBuffer(commandPool, commandBuffer); - - m_core->getContext().getDevice().destroyBuffer(scratchBuffer.vulkanHandle, nullptr, m_rtxDispatcher); - m_core->getContext().getDevice().freeMemory(scratchBuffer.deviceMemory, nullptr, m_rtxDispatcher); - - BottomLevelAccelerationStructure blas = { - vertexData.getVertexBufferBindings()[0].buffer, - vertexData.getIndexBuffer(), - nullptr, - blasKHR - }; - m_bottomLevelAccelerationStructures.push_back(blas); - } - - void ASManager::add(const vkcv::GeometryData &geometryData, const vkcv::AccelerationStructureHandle &blas) { - BottomLevelAccelerationStructure blasEntry = { - geometryData.getVertexBufferBinding().buffer, - geometryData.getIndexBuffer(), - m_core->getVulkanBuffer(blas), - m_core->getVulkanAccelerationStructure(blas) - }; - - m_bottomLevelAccelerationStructures.push_back(blasEntry); - } - - void ASManager::buildTLAS() { - // TODO: organize hierarchical structure of multiple BLAS - - // We need an the device address of each BLAS --> TODO: for loop for bigger scenes - vk::AccelerationStructureDeviceAddressInfoKHR addressInfo( - m_bottomLevelAccelerationStructures[0].vulkanHandle - ); - vk::DeviceAddress blasAddress = m_device->getAccelerationStructureAddressKHR(&addressInfo, m_rtxDispatcher); - - std::array<std::array<float, 4>, 3> transformMatrix = { - std::array<float, 4>{1.f, 0.f, 0.f, 0.f}, - std::array<float, 4>{0.f, 1.f, 0.f, 0.f}, - std::array<float, 4>{0.f, 0.f, 1.f, 0.f}, - }; - - vk::TransformMatrixKHR transformMatrixKhr( - transformMatrix // std::array<std::array<float,4>,3> const& - ); - - vk::AccelerationStructureInstanceKHR accelerationStructureInstanceKhr( - transformMatrixKhr, // vk::TransformMatrixKHR transform_ = {}, - 0, // uint32_t instanceCustomIndex, - 0xFF, //uint32_t mask_ = {}, - 0, // uint32_t instanceShaderBindingTableRecordOffset, - vk::GeometryInstanceFlagBitsKHR::eTriangleFacingCullDisable, // vk::GeometryInstanceFlagsKHR - blasAddress // uint64_t accelerationStructureReference (the device address of the BLAS) - ); - - // create a buffer of instances on the device and upload the array of instances to it - RTXBuffer stagingBufferInstances; - stagingBufferInstances.bufferType = RTXBufferType::STAGING; - stagingBufferInstances.deviceSize = sizeof(accelerationStructureInstanceKhr); - stagingBufferInstances.data = &accelerationStructureInstanceKhr; - stagingBufferInstances.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eTransferSrc; - stagingBufferInstances.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostCoherent - | vk::MemoryPropertyFlagBits::eHostVisible; - - createBuffer(stagingBufferInstances); - - RTXBuffer bufferInstances; - bufferInstances.bufferType = RTXBufferType::GPU; - bufferInstances.deviceSize = sizeof(accelerationStructureInstanceKhr); - bufferInstances.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eTransferDst - | vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR; - bufferInstances.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eDeviceLocal; - - createBuffer(bufferInstances); - copyFromCPUToGPU(stagingBufferInstances, bufferInstances); // automatically deletes and frees memory of stagingBufferInstances - - vk::MemoryBarrier barrier; - barrier.setSrcAccessMask(vk::AccessFlagBits::eTransferWrite); - barrier.setDstAccessMask(vk::AccessFlagBits::eAccelerationStructureWriteKHR); - vk::CommandPool commandPool = createCommandPool(); - vk::CommandBuffer commandBuffer = createAndBeginCommandBuffer(commandPool); - commandBuffer.pipelineBarrier( - vk::PipelineStageFlagBits::eTransfer, - vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR, - {},1,&barrier,0, nullptr,0,nullptr); - submitCommandBuffer(commandPool, commandBuffer); - - - // ranging information for TLAS build - vk::AccelerationStructureBuildRangeInfoKHR asRangeInfo( - 1, // primitiveCount -> number of instances - 0, // primitiveOffset - 0, // firstVertex - 0 //transformOffset - ); - - vk::DeviceAddress bufferInstancesAddress = getBufferDeviceAddress(bufferInstances.vulkanHandle); - - vk::AccelerationStructureGeometryInstancesDataKHR asInstances( - false, // vk::Bool32 arrayOfPointers - bufferInstancesAddress // vk::DeviceOrHostAddressConstKHR data_ = {} - ); - - // Geometry, in this case instances of BLAS - vk::AccelerationStructureGeometryKHR asGeometry( - vk::GeometryTypeKHR::eInstances, // vk::GeometryTypeKHR geometryType_ = vk::GeometryTypeKHR::eTriangles - asInstances, // vk::AccelerationStructureGeometryDataKHR geometry_ = {} - {} // vk::GeometryFlagsKHR flags_ = {} - ); - - // Finally, create the TLAS - vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo( - vk::AccelerationStructureTypeKHR::eTopLevel, // type of the AS: bottom vs. top - vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency - vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update - {}, // src AS (this seems to be for copying AS) - {}, // dst AS (this seems to be for copying AS) - 1, // the geometryCount. - &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry? - ); - - // AS size and scratch space size, given by count of instances (1) - vk::AccelerationStructureBuildSizesInfoKHR asSizeInfo; - m_core->getContext().getDevice().getAccelerationStructureBuildSizesKHR( - vk::AccelerationStructureBuildTypeKHR::eDevice, - &asBuildInfo, - &asRangeInfo.primitiveCount, - &asSizeInfo, - m_rtxDispatcher - ); - - // Create buffer for the TLAS - RTXBuffer tlasBuffer; - tlasBuffer.bufferType = RTXBufferType::ACCELERATION; - tlasBuffer.deviceSize = asSizeInfo.accelerationStructureSize; - tlasBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR - | vk::BufferUsageFlagBits::eShaderDeviceAddress - | vk::BufferUsageFlagBits::eStorageBuffer; - - createBuffer(tlasBuffer); - - // Create empty TLAS object - vk::AccelerationStructureCreateInfoKHR asCreateInfo( - {}, // creation flags - tlasBuffer.vulkanHandle, // allocated AS buffer. - 0, - asSizeInfo.accelerationStructureSize, // size of the AS - asBuildInfo.type // type of the AS - ); - - vk::AccelerationStructureKHR tlas; - vk::Result res = m_device->createAccelerationStructureKHR(&asCreateInfo, nullptr, &tlas, m_rtxDispatcher); - if (res != vk::Result::eSuccess) { - vkcv_log(LogLevel::ERROR, "Top Level Acceleration Structure could not be created! (%s)", vk::to_string(res).c_str()); - } - asBuildInfo.setDstAccelerationStructure(tlas); - - // Create temporary scratch buffer used for building the AS - RTXBuffer tlasScratchBuffer; // scratch buffer - tlasScratchBuffer.bufferType = RTXBufferType::ACCELERATION; - tlasScratchBuffer.deviceSize = asSizeInfo.buildScratchSize; - tlasScratchBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderDeviceAddressKHR - | vk::BufferUsageFlagBits::eStorageBuffer; - - createBuffer(tlasScratchBuffer); - - vk::BufferDeviceAddressInfo tempBuildDataBufferDeviceAddressInfo(tlasScratchBuffer.vulkanHandle); - vk::DeviceAddress tempBuildBufferDataAddress = m_core->getContext().getDevice().getBufferAddressKHR(tempBuildDataBufferDeviceAddressInfo, m_rtxDispatcher); - asBuildInfo.setScratchData(tempBuildBufferDataAddress); - - // Pointer to rangeInfo, used later for build - vk::AccelerationStructureBuildRangeInfoKHR* pointerToRangeInfo = &asRangeInfo; - - // Build the TLAS. - - vk::CommandPool commandPool2 = createCommandPool(); - vk::CommandBuffer commandBuffer2 = createAndBeginCommandBuffer(commandPool2); - commandBuffer2.buildAccelerationStructuresKHR(1, &asBuildInfo, &pointerToRangeInfo, m_rtxDispatcher); - submitCommandBuffer(commandPool2, commandBuffer2); - - m_device->destroyBuffer(tlasScratchBuffer.vulkanHandle, nullptr, m_rtxDispatcher); - m_device->freeMemory(tlasScratchBuffer.deviceMemory, nullptr, m_rtxDispatcher); - - m_topLevelAccelerationStructure = { - bufferInstances, - tlasBuffer, - tlasScratchBuffer, - tlas - }; - } - - TopLevelAccelerationStructure ASManager::getTLAS() - { - return m_topLevelAccelerationStructure; - } - - BottomLevelAccelerationStructure ASManager::getBLAS(uint32_t id) - { - return m_bottomLevelAccelerationStructures[id]; - } - - const vk::DispatchLoaderDynamic& ASManager::getDispatcher() { - return m_rtxDispatcher; - } -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp b/projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp deleted file mode 100644 index 825d5e65..00000000 --- a/projects/rtx_ambient_occlusion/src/RTX/ASManager.hpp +++ /dev/null @@ -1,187 +0,0 @@ -#pragma once - -#include <vkcv/Core.hpp> - -namespace vkcv::rtx { - - /** - * @brief Used for @#RTXBuffer creation depending on the @#RTXBufferType. - */ - enum class RTXBufferType { - STAGING, - GPU, - ACCELERATION, - SHADER_BINDING, - SCRATCH - }; - - /** - * @brief Used as a container to handle buffer creation and destruction in RTX-specific use cases. - */ - struct RTXBuffer { - RTXBufferType bufferType; - void* data; - vk::DeviceSize deviceSize; - vk::DeviceMemory deviceMemory; - vk::BufferUsageFlags bufferUsageFlagBits; - vk::MemoryPropertyFlags memoryPropertyFlagBits; - vk::Buffer vulkanHandle; - }; - - /** - * @brief Used as a container to handle bottom-level acceleration structure (BLAS) construction and destruction. - */ - struct BottomLevelAccelerationStructure { - vkcv::BufferHandle vertexBuffer; - vkcv::BufferHandle indexBuffer; - vk::Buffer accelerationBuffer; - vk::AccelerationStructureKHR vulkanHandle; - }; - - /** - * @brief Used as a container to handle top-level acceleration structure (TLAS) construction and destruction. - */ - struct TopLevelAccelerationStructure { - RTXBuffer gpuBufferInstances; - RTXBuffer tlasBuffer; - RTXBuffer tempBuildDataBuffer; // scratch buffer - vk::AccelerationStructureKHR vulkanHandle; - }; - - /** - * @brief A class for managing acceleration structures (bottom, top). - */ - class ASManager { - private: - Core* m_core; - const vk::Device* m_device; - std::vector<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructures; - TopLevelAccelerationStructure m_topLevelAccelerationStructure; - vk::DispatchLoaderDynamic m_rtxDispatcher; - - /** - * Creates a command pool. - */ - vk::CommandPool createCommandPool(); - - /** - * @brief Takes a @p cmdPool, allocates a command buffer and starts recording it. - * @param cmdPool The command pool. - * @return The allocated command buffer. - */ - vk::CommandBuffer createAndBeginCommandBuffer( vk::CommandPool cmdPool); - - /** - * @brief Ends the @p commandBuffer,submits it and waits. Afterwards frees the @p commandBuffer. - * @param commandPool The command pool. - * @param commandBuffer The command buffer. - */ - void submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer); - - /** - * @brief Gets the device address of a @p buffer. - * @param buffer The buffer. - * @return The device address of the @p buffer. - */ - vk::DeviceAddress getBufferDeviceAddress(vk::Buffer buffer); - - /** - * @brief Copies @p cpuBuffer data into a @p gpuBuffer. Typical use case is a staging buffer (namely, - * @p cpuBuffer) used to fill a @p gpuBuffer with @p vk::MemoryPropertyFlagBits::eDeviceLocal flag set. - * @p cpuBuffer is destroyed and freed after copying. - * @param cpuBuffer - * @param gpuBuffer - */ - void copyFromCPUToGPU(RTXBuffer &cpuBuffer, RTXBuffer &gpuBuffer); - - public: - - /** - * @brief Constructor of @#ASManager . - * @param core - */ - ASManager(vkcv::Core *core); - - /** - * @brief Default destructor of @#ASManager. - */ - ~ASManager(); - - /** - * @brief Returns a @#RTXBuffer object holding data of type @p T. - * @param data The input data of type @p T. - * @return A @#RTXBuffer object holding @p data of type @p T. - */ - template<class T> - RTXBuffer makeBufferFromData(std::vector<T>& data) { - - // first: Staging Buffer creation - RTXBuffer stagingBuffer; - stagingBuffer.bufferType = RTXBufferType::STAGING; - stagingBuffer.deviceSize = sizeof(T) * data.size(); - stagingBuffer.data = data.data(); - stagingBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eTransferSrc; - stagingBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible; - - createBuffer(stagingBuffer); - - // second: create AS Buffer - RTXBuffer targetBuffer; - targetBuffer.bufferType = RTXBufferType::GPU; - targetBuffer.deviceSize = sizeof(T) * data.size(); - targetBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR - | vk::BufferUsageFlagBits::eTransferDst - | vk::BufferUsageFlagBits::eStorageBuffer - | vk::BufferUsageFlagBits::eShaderDeviceAddress; - targetBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eDeviceLocal; - - createBuffer(targetBuffer); - - // copy from CPU to GPU - copyFromCPUToGPU(stagingBuffer, targetBuffer); - - return targetBuffer; - } - - /** - * @brief A helper function used by @#ASManager::makeBufferFromData. Creates a fully initialized @#RTXBuffer object - * from partially specified @p buffer. All missing data of @p buffer will be completed by this function. - * @param buffer The partially specified @#RTXBuffer holding that part of information which is required for - * successfully creating a @p vk::Buffer object. - */ - void createBuffer(RTXBuffer& buffer); - - /** - * @brief Build a Bottom Level Acceleration Structure (BLAS) object from given @p vertexBuffer and @p indexBuffer. - * @param[in] vertexData The vertex data. - */ - void buildBLAS(const vkcv::VertexData &vertexData); - - void add(const vkcv::GeometryData &geometryData, const vkcv::AccelerationStructureHandle &blas); - - /** - * @brief Build a Top Level Acceleration Structure (TLAS) object from the created - * @#ASManager::m_accelerationStructures objects. - */ - void buildTLAS(); - - /** - * @brief Returns the top-level acceleration structure (TLAS) buffer. - * @return A @#TopLevelAccelerationStructure object holding the TLAS. - */ - TopLevelAccelerationStructure getTLAS(); - - /** - * @brief Returns the bottom-level acceleration structure at @p id. - * @param id The ID used for indexing. - * @return The specified @#BottomLevelAccelerationStructure object. - */ - BottomLevelAccelerationStructure getBLAS(uint32_t id); - - /** - * @brief Returns the dispatcher member variable for access in the @#RTXModule. - * @return The dispatcher member variable. - */ - const vk::DispatchLoaderDynamic& getDispatcher(); - }; -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp b/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp deleted file mode 100644 index 4fd33be9..00000000 --- a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "RTX.hpp" - -namespace vkcv::rtx { - - RTXModule::RTXModule(Core* core, - ASManager* asManager, - std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles){ - m_core = core; - m_asManager = asManager; - // build acceleration structures BLAS then TLAS --> see ASManager - m_asManager->buildTLAS(); - RTXDescriptors(descriptorSetHandles); - } - - - RTXModule::~RTXModule() - {} - - - void RTXModule::RTXDescriptors(std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles) - { - //TLAS-Descriptor-Write - { - vkcv::DescriptorWrites writes; - writes.writeAcceleration(1, { m_asManager->getTLAS().vulkanHandle }); - m_core->writeDescriptorSet(descriptorSetHandles[0], writes); - } - } - -} \ No newline at end of file diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTX.hpp b/projects/rtx_ambient_occlusion/src/RTX/RTX.hpp deleted file mode 100644 index 9a71bc17..00000000 --- a/projects/rtx_ambient_occlusion/src/RTX/RTX.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include <vector> -#include "vulkan/vulkan.hpp" -#include <vkcv/Core.hpp> -#include "ASManager.hpp" - -namespace vkcv::rtx { - - //struct that holds all shader binding table regions - struct ShaderBindingTableRegions { - vk::StridedDeviceAddressRegionKHR rgenRegion; - vk::StridedDeviceAddressRegionKHR rmissRegion; - vk::StridedDeviceAddressRegionKHR rchitRegion; - vk::StridedDeviceAddressRegionKHR rcallRegion; - }; - - class RTXModule { - private: - - Core* m_core; - ASManager* m_asManager; - vk::Pipeline m_pipeline; - vk::PipelineLayout m_pipelineLayout; - RTXBuffer m_shaderBindingTableBuffer; - vk::DeviceSize m_shaderGroupBaseAlignment; - - public: - - /** - * @brief Initializes the @#RTXModule with scene data. - * @param core The reference to the @#Core. - * @param asManager The reference to the @#ASManager. - * @param vertexData The vertex data of the scene. - * @param descriptorSetHandles The descriptor set handles for RTX. - */ - RTXModule(Core* core, - ASManager* asManager, - std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles); - - /** - * @brief Default #RTXModule destructor. - */ - ~RTXModule(); - - /** - * @brief Returns the RTX pipeline. - * @return The RTX pipeline. - */ - vk::Pipeline getPipeline(); - - /** - * @brief Returns the shader binding table buffer. - * @return The shader binding table buffer. - */ - vk::Buffer getShaderBindingTableBuffer(); - - /** - * @brief Returns the shader group base alignment for partitioning the shader binding table buffer. - * @return The shader group base alignment. - */ - vk::DeviceSize getShaderGroupBaseAlignment(); - - /** - * @brief Returns the RTX pipeline layout. - * @return The RTX pipeline layout. - */ - vk::PipelineLayout getPipelineLayout(); - - /** - * @brief Sets the shader group base alignment and creates the shader binding table by allocating a shader - * binding table buffer. The allocation depends on @p shaderCount and the shader group base alignment. - * @param shaderCount The amount of shaders to be used for RTX. - */ - void createShaderBindingTable(uint32_t shaderCount); - - /** - * @brief Divides the shader binding table into regions for each shader type - * (ray generation, ray miss, ray closest hit, callable) and returns them as a struct. - * @return The struct holding all four regions of type vk::StridedDeviceAddressRegionKHR. - */ - ShaderBindingTableRegions createRegions(); - - /** - * @brief Creates Descriptor-Writes for RTX - * @param descriptorSetHandles The descriptorSetHandles for RTX. - */ - void RTXDescriptors(std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles); - - /** - * @brief Creates the RTX pipeline and the RTX pipeline layout. Currently, only RayGen, RayClosestHit and - * RayMiss are supported. - * @param pushConstantSize The size of the push constant used in the RTX shaders. - * @param descriptorSetLayouts The descriptor set layout handles. - * @param rtxShader The RTX shader program. - */ - void createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader); - }; - -} diff --git a/screenshots/rtx_ambient_occlusion.png b/screenshots/rt_ambient_occlusion.png similarity index 100% rename from screenshots/rtx_ambient_occlusion.png rename to screenshots/rt_ambient_occlusion.png diff --git a/src/vkcv/AccelerationStructureManager.cpp b/src/vkcv/AccelerationStructureManager.cpp index b0b213d4..919a0677 100644 --- a/src/vkcv/AccelerationStructureManager.cpp +++ b/src/vkcv/AccelerationStructureManager.cpp @@ -71,6 +71,20 @@ namespace vkcv { return getBufferManager().getBuffer(accelerationStructure.m_storageBuffer); } + vk::DeviceAddress AccelerationStructureManager::getAccelerationStructureDeviceAddress( + const vkcv::AccelerationStructureHandle &handle) const { + auto &accelerationStructure = (*this) [handle]; + + const vk::AccelerationStructureDeviceAddressInfoKHR addressInfo ( + accelerationStructure.m_accelerationStructure + ); + + return getCore().getContext().getDevice().getAccelerationStructureAddressKHR( + addressInfo, + getCore().getContext().getDispatchLoaderDynamic() + ); + } + static vk::Format getVertexFormat(GeometryVertexType vertexType) { switch (vertexType) { case GeometryVertexType::POSITION_FLOAT3: @@ -97,6 +111,109 @@ namespace vkcv { } } + static AccelerationStructureEntry buildAccelerationStructure( + Core& core, + BufferManager& bufferManager, + std::vector<vk::AccelerationStructureBuildGeometryInfoKHR> &geometryInfos, + const std::vector<std::vector<vk::AccelerationStructureBuildRangeInfoKHR>> &rangeInfos, + size_t accelerationStructureSize, + size_t scratchBufferSize, + vk::AccelerationStructureTypeKHR accelerationStructureType) { + const auto &dynamicDispatch = core.getContext().getDispatchLoaderDynamic(); + const vk::PhysicalDevice &physicalDevice = core.getContext().getPhysicalDevice(); + + vk::PhysicalDeviceAccelerationStructurePropertiesKHR accelerationStructureProperties; + + vk::PhysicalDeviceProperties2 physicalProperties2; + physicalProperties2.pNext = &accelerationStructureProperties; + physicalDevice.getProperties2(&physicalProperties2); + + const auto minScratchAlignment = ( + accelerationStructureProperties.minAccelerationStructureScratchOffsetAlignment + ); + + const BufferHandle &asStorageBuffer = bufferManager.createBuffer( + typeGuard<uint8_t>(), + BufferType::ACCELERATION_STRUCTURE_STORAGE, + BufferMemoryType::DEVICE_LOCAL, + accelerationStructureSize, + false + ); + + const BufferHandle &asScratchBuffer = bufferManager.createBuffer( + vkcv::typeGuard<uint8_t>(), + BufferType::STORAGE, + BufferMemoryType::DEVICE_LOCAL, + scratchBufferSize, + false, + minScratchAlignment + ); + + if ((!asStorageBuffer) || (!asScratchBuffer)) { + return {}; + } + + const vk::AccelerationStructureCreateInfoKHR asCreateInfo ( + vk::AccelerationStructureCreateFlagsKHR(), + bufferManager.getBuffer(asStorageBuffer), + 0, + accelerationStructureSize, + accelerationStructureType + ); + + vk::AccelerationStructureKHR accelerationStructure; + const vk::Result result = core.getContext().getDevice().createAccelerationStructureKHR( + &asCreateInfo, + nullptr, + &accelerationStructure, + dynamicDispatch + ); + + if (result != vk::Result::eSuccess) { + return {}; + } + + const vk::DeviceAddress scratchBufferAddress = bufferManager.getBufferDeviceAddress( + asScratchBuffer + ); + + for (auto& geometryInfo : geometryInfos) { + geometryInfo.setDstAccelerationStructure(accelerationStructure); + geometryInfo.setScratchData(scratchBufferAddress); + } + + std::vector<const vk::AccelerationStructureBuildRangeInfoKHR*> pRangeInfos; + pRangeInfos.resize(rangeInfos.size()); + + for (size_t i = 0; i < rangeInfos.size(); i++) { + pRangeInfos[i] = rangeInfos[i].data(); + } + + auto cmdStream = core.createCommandStream(vkcv::QueueType::Compute); + + core.recordCommandsToStream( + cmdStream, + [&geometryInfos, &pRangeInfos, &dynamicDispatch]( + const vk::CommandBuffer &cmdBuffer) { + cmdBuffer.buildAccelerationStructuresKHR( + static_cast<uint32_t>(geometryInfos.size()), + geometryInfos.data(), + pRangeInfos.data(), + dynamicDispatch + ); + }, + nullptr + ); + + core.submitCommandStream(cmdStream, false); + core.getContext().getDevice().waitIdle(); // TODO: Fix that mess! + + return { + accelerationStructure, + asStorageBuffer + }; + } + AccelerationStructureHandle AccelerationStructureManager::createAccelerationStructure( const std::vector<GeometryData> &geometryData) { std::vector<vk::AccelerationStructureGeometryKHR> geometries; @@ -189,96 +306,158 @@ namespace vkcv { scratchBufferSize = std::max(scratchBufferSize, asBuildSizesInfo.buildScratchSize); } - const BufferHandle &asStorageBuffer = bufferManager.createBuffer( - typeGuard<uint8_t>(), - BufferType::ACCELERATION_STRUCTURE_STORAGE, - BufferMemoryType::DEVICE_LOCAL, + const auto entry = buildAccelerationStructure( + getCore(), + bufferManager, + geometryInfos, + rangeInfos, accelerationStructureSize, - false + scratchBufferSize, + vk::AccelerationStructureTypeKHR::eBottomLevel ); - vk::PhysicalDeviceAccelerationStructurePropertiesKHR accelerationStructureProperties; + if ((!entry.m_accelerationStructure) || (!entry.m_storageBuffer)) { + return {}; + } - vk::PhysicalDeviceProperties2 physicalProperties2; - physicalProperties2.pNext = &accelerationStructureProperties; + return add(entry); + } + + AccelerationStructureHandle AccelerationStructureManager::createAccelerationStructure( + const std::vector<AccelerationStructureHandle> &accelerationStructures) { + std::vector<vk::AccelerationStructureInstanceKHR> asInstances; + asInstances.reserve(accelerationStructures.size()); - getCore().getContext().getPhysicalDevice().getProperties2(&physicalProperties2); + auto& bufferManager = getBufferManager(); - const auto minScratchAlignment = ( - accelerationStructureProperties.minAccelerationStructureScratchOffsetAlignment - ); + const auto &dynamicDispatch = getCore().getContext().getDispatchLoaderDynamic(); - const BufferHandle &asScratchBuffer = bufferManager.createBuffer( - vkcv::TypeGuard(minScratchAlignment), - BufferType::STORAGE, + for (const auto& accelerationStructure : accelerationStructures) { + const vk::DeviceAddress asDeviceAddress = getAccelerationStructureDeviceAddress( + accelerationStructure + ); + + const std::array<std::array<float, 4>, 3> transformMatrixValues = { + std::array<float, 4>{1.f, 0.f, 0.f, 0.f}, + std::array<float, 4>{0.f, 1.f, 0.f, 0.f}, + std::array<float, 4>{0.f, 0.f, 1.f, 0.f}, + }; + + const vk::TransformMatrixKHR transformMatrix ( + transformMatrixValues + ); + + const vk::GeometryInstanceFlagsKHR instanceFlags ( + vk::GeometryInstanceFlagBitsKHR::eTriangleFacingCullDisable + ); + + const vk::AccelerationStructureInstanceKHR asInstance ( + transformMatrix, + 0, + 0xFF, + 0, + instanceFlags, + asDeviceAddress + ); + + asInstances.push_back(asInstance); + } + + const auto asInstanceTypeGuard = typeGuard<vk::AccelerationStructureInstanceKHR>(); + + auto asInputBuffer = bufferManager.createBuffer( + asInstanceTypeGuard, + BufferType::ACCELERATION_STRUCTURE_INPUT, BufferMemoryType::DEVICE_LOCAL, - (scratchBufferSize + minScratchAlignment - 1) / minScratchAlignment, + asInstances.size() * asInstanceTypeGuard.typeSize(), false ); - if ((!asStorageBuffer) || (!asScratchBuffer)) { - return {}; - } - - const vk::AccelerationStructureCreateInfoKHR asCreateInfo ( - vk::AccelerationStructureCreateFlagsKHR(), - bufferManager.getBuffer(asStorageBuffer), + bufferManager.fillBuffer( + asInputBuffer, + asInstances.data(), 0, - accelerationStructureSize, - vk::AccelerationStructureTypeKHR::eBottomLevel + 0 ); - vk::AccelerationStructureKHR accelerationStructure; - const vk::Result result = getCore().getContext().getDevice().createAccelerationStructureKHR( - &asCreateInfo, - nullptr, - &accelerationStructure, - dynamicDispatch + const vk::AccelerationStructureBuildRangeInfoKHR asBuildRangeInfo ( + static_cast<uint32_t>(asInstances.size()), + 0, + 0, + 0 ); - if (result != vk::Result::eSuccess) { - return {}; - } + auto cmdStream = getCore().createCommandStream(QueueType::Compute); - vk::DeviceAddress scratchBufferAddress = bufferManager.getBufferDeviceAddress( - asScratchBuffer - ); - - if (scratchBufferAddress % minScratchAlignment != 0) { - scratchBufferAddress += ( - minScratchAlignment - (scratchBufferAddress % minScratchAlignment) + getCore().recordCommandsToStream(cmdStream, [](const vk::CommandBuffer &cmdBuffer) { + const vk::MemoryBarrier barrier ( + vk::AccessFlagBits::eTransferWrite, + vk::AccessFlagBits::eAccelerationStructureReadKHR ); - } + + cmdBuffer.pipelineBarrier( + vk::PipelineStageFlagBits::eTransfer, + vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR, + {}, + barrier, + nullptr, + nullptr + ); + }, nullptr); - for (auto& geometryInfo : geometryInfos) { - geometryInfo.setDstAccelerationStructure(accelerationStructure); - geometryInfo.setScratchData(scratchBufferAddress); - } + getCore().submitCommandStream(cmdStream, false); - std::vector<vk::AccelerationStructureBuildRangeInfoKHR*> pRangeInfos; - pRangeInfos.resize(rangeInfos.size()); + const vk::DeviceAddress inputBufferAddress = bufferManager.getBufferDeviceAddress( + asInputBuffer + ); - for (size_t i = 0; i < rangeInfos.size(); i++) { - pRangeInfos[i] = rangeInfos[i].data(); - } + const vk::AccelerationStructureGeometryInstancesDataKHR asInstancesData ( + false, + inputBufferAddress + ); - auto cmdStream = getCore().createCommandStream(vkcv::QueueType::Compute); + const vk::AccelerationStructureGeometryKHR asGeometry ( + vk::GeometryTypeKHR::eInstances, + asInstancesData, + {} + ); - getCore().recordCommandsToStream( - cmdStream, - [&geometryInfos, &pRangeInfos, &dynamicDispatch]( - const vk::CommandBuffer &cmdBuffer) { - cmdBuffer.buildAccelerationStructuresKHR( - static_cast<uint32_t>(geometryInfos.size()), - geometryInfos.data(), - pRangeInfos.data(), - dynamicDispatch - ); - }, nullptr); + std::vector<vk::AccelerationStructureBuildGeometryInfoKHR> asBuildGeometryInfos = { + vk::AccelerationStructureBuildGeometryInfoKHR( + vk::AccelerationStructureTypeKHR::eTopLevel, + vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, + vk::BuildAccelerationStructureModeKHR::eBuild, + {}, + {}, + 1, + &(asGeometry) + ) + }; - getCore().submitCommandStream(cmdStream, false); + vk::AccelerationStructureBuildSizesInfoKHR asBuildSizesInfo; + getCore().getContext().getDevice().getAccelerationStructureBuildSizesKHR( + vk::AccelerationStructureBuildTypeKHR::eDevice, + asBuildGeometryInfos.data(), + &(asBuildRangeInfo.primitiveCount), + &(asBuildSizesInfo), + dynamicDispatch + ); + + const auto entry = buildAccelerationStructure( + getCore(), + bufferManager, + asBuildGeometryInfos, + { { asBuildRangeInfo } }, + asBuildSizesInfo.accelerationStructureSize, + asBuildSizesInfo.buildScratchSize, + vk::AccelerationStructureTypeKHR::eTopLevel + ); + + if ((!entry.m_accelerationStructure) || (!entry.m_storageBuffer)) { + return {}; + } - return add({ accelerationStructure, asStorageBuffer }); + return add(entry); } } diff --git a/src/vkcv/AccelerationStructureManager.hpp b/src/vkcv/AccelerationStructureManager.hpp index 155b5767..d7cc67f1 100644 --- a/src/vkcv/AccelerationStructureManager.hpp +++ b/src/vkcv/AccelerationStructureManager.hpp @@ -20,7 +20,7 @@ namespace vkcv { struct AccelerationStructureEntry { vk::AccelerationStructureKHR m_accelerationStructure; - vkcv::BufferHandle m_storageBuffer; + BufferHandle m_storageBuffer; }; /** @@ -64,9 +64,23 @@ namespace vkcv { [[nodiscard]] vk::Buffer getVulkanBuffer(const AccelerationStructureHandle &handle) const; + /** + * @brief Returns the Vulkan device address of an acceleration + * structure represented by a given acceleration structure + * handle id. + * + * @param[in] handle Acceleration structure handle + * @return Vulkan device address + */ + [[nodiscard]] vk::DeviceAddress getAccelerationStructureDeviceAddress( + const AccelerationStructureHandle &handle) const; + [[nodiscard]] AccelerationStructureHandle createAccelerationStructure( const std::vector<GeometryData> &geometryData); + [[nodiscard]] AccelerationStructureHandle createAccelerationStructure( + const std::vector<AccelerationStructureHandle> &accelerationStructures); + }; } \ No newline at end of file diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp index b7732588..a8767ece 100644 --- a/src/vkcv/BufferManager.cpp +++ b/src/vkcv/BufferManager.cpp @@ -114,7 +114,7 @@ namespace vkcv { BufferHandle BufferManager::createBuffer(const TypeGuard &typeGuard, BufferType type, BufferMemoryType memoryType, size_t size, - bool readable) { + bool readable, size_t alignment) { vk::BufferCreateFlags createFlags; vk::BufferUsageFlags usageFlags; @@ -173,7 +173,7 @@ namespace vkcv { const vma::Allocator &allocator = getCore().getContext().getAllocator(); vma::MemoryUsage memoryUsage; - bool mappable = false; + bool mappable; switch (memoryType) { case BufferMemoryType::DEVICE_LOCAL: @@ -205,7 +205,7 @@ namespace vkcv { | vma::AllocationCreateFlagBits::eHostAccessSequentialWrite; } - auto bufferAllocation = allocator.createBuffer( + const auto bufferAllocation = allocator.createBufferWithAlignment( vk::BufferCreateInfo(createFlags, size, usageFlags), vma::AllocationCreateInfo( allocationCreateFlags, @@ -215,11 +215,12 @@ namespace vkcv { 0, vma::Pool(), nullptr - ) + ), + static_cast<vk::DeviceSize>(alignment) ); - vk::Buffer buffer = bufferAllocation.first; - vma::Allocation allocation = bufferAllocation.second; + const vk::Buffer buffer = bufferAllocation.first; + const vma::Allocation allocation = bufferAllocation.second; const vk::MemoryPropertyFlags finalMemoryFlags = allocator.getAllocationMemoryProperties( allocation @@ -406,8 +407,11 @@ namespace vkcv { ); } - void BufferManager::fillBuffer(const BufferHandle &handle, const void* data, size_t size, - size_t offset) { + void BufferManager::fillBuffer(const BufferHandle &handle, + const void* data, + size_t size, + size_t offset, + bool forceStaging) { auto &buffer = (*this) [handle]; if (size == 0) { @@ -422,7 +426,7 @@ namespace vkcv { const size_t max_size = std::min(size, buffer.m_size - offset); - if (buffer.m_mappable) { + if ((buffer.m_mappable) && (!forceStaging)) { void* mapped = allocator.mapMemory(buffer.m_allocation); memcpy(reinterpret_cast<char*>(mapped) + offset, data, max_size); allocator.unmapMemory(buffer.m_allocation); @@ -445,7 +449,9 @@ namespace vkcv { } } - void BufferManager::readBuffer(const BufferHandle &handle, void* data, size_t size, + void BufferManager::readBuffer(const BufferHandle &handle, + void* data, + size_t size, size_t offset) { auto &buffer = (*this) [handle]; diff --git a/src/vkcv/BufferManager.hpp b/src/vkcv/BufferManager.hpp index 818c907c..891b59fc 100644 --- a/src/vkcv/BufferManager.hpp +++ b/src/vkcv/BufferManager.hpp @@ -79,11 +79,12 @@ namespace vkcv { * @param[in] size Size of buffer in bytes * @param[in] supportIndirect Support of indirect usage * @param[in] readable Support read functionality + * @param[in] alignment (optional) Alignment for buffer memory * @return New buffer handle */ [[nodiscard]] BufferHandle createBuffer(const TypeGuard &typeGuard, BufferType type, BufferMemoryType memoryType, size_t size, - bool readable); + bool readable, size_t alignment = 0); /** * @brief Returns the Vulkan buffer handle of a buffer @@ -156,8 +157,13 @@ namespace vkcv { * @param[in] data Pointer to data * @param[in] size Size of data in bytes * @param[in] offset Offset to fill in data in bytes + * @param[in] forceStaging (Optional) Flag to enforce transfer via staging buffer */ - void fillBuffer(const BufferHandle &handle, const void* data, size_t size, size_t offset); + void fillBuffer(const BufferHandle &handle, + const void* data, + size_t size, + size_t offset, + bool forceStaging = false); /** * @brief Reads from a buffer represented by a given diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index db8cdf53..f2152223 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -1351,11 +1351,18 @@ namespace vkcv { return m_ImageManager->getVulkanDeviceMemory(handle); } - AccelerationStructureHandle Core::createAccelerationStructure(const std::vector<GeometryData> &geometryData) { + AccelerationStructureHandle Core::createAccelerationStructure( + const std::vector<GeometryData> &geometryData) { return m_AccelerationStructureManager->createAccelerationStructure(geometryData); } - vk::AccelerationStructureKHR Core::getVulkanAccelerationStructure(const AccelerationStructureHandle &handle) const { + AccelerationStructureHandle Core::createAccelerationStructure( + const std::vector<AccelerationStructureHandle> &handles) { + return m_AccelerationStructureManager->createAccelerationStructure(handles); + } + + vk::AccelerationStructureKHR Core::getVulkanAccelerationStructure( + const AccelerationStructureHandle &handle) const { return m_AccelerationStructureManager->getVulkanAccelerationStructure(handle); } @@ -1363,4 +1370,9 @@ namespace vkcv { return m_AccelerationStructureManager->getVulkanBuffer(handle); } + vk::DeviceAddress Core::getAccelerationStructureDeviceAddress( + const vkcv::AccelerationStructureHandle &handle) const { + return m_AccelerationStructureManager->getAccelerationStructureDeviceAddress(handle); + } + } // namespace vkcv diff --git a/src/vkcv/DescriptorSetManager.cpp b/src/vkcv/DescriptorSetManager.cpp index e6ac1c22..b33221b1 100644 --- a/src/vkcv/DescriptorSetManager.cpp +++ b/src/vkcv/DescriptorSetManager.cpp @@ -22,13 +22,14 @@ namespace vkcv { vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1000), vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, 1000), vk::DescriptorPoolSize(vk::DescriptorType::eUniformBufferDynamic, 1000), - vk::DescriptorPoolSize(vk::DescriptorType::eStorageBufferDynamic, 1000), // for RTX - vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1000) // for RTX + vk::DescriptorPoolSize(vk::DescriptorType::eStorageBufferDynamic, 1000), + vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1000) }; m_PoolInfo = vk::DescriptorPoolCreateInfo( vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1000, - static_cast<uint32_t>(m_PoolSizes.size()), m_PoolSizes.data()); + static_cast<uint32_t>(m_PoolSizes.size()), m_PoolSizes.data() + ); return allocateDescriptorPool(); } diff --git a/src/vkcv/RayTracingPipelineManager.cpp b/src/vkcv/RayTracingPipelineManager.cpp index 70f05b98..147c216d 100644 --- a/src/vkcv/RayTracingPipelineManager.cpp +++ b/src/vkcv/RayTracingPipelineManager.cpp @@ -403,26 +403,21 @@ namespace vkcv { ); const BufferHandle &shaderBindingTable = bufferManager.createBuffer( - TypeGuard(baseAlignment), + typeGuard<uint8_t>(), BufferType::SHADER_BINDING, BufferMemoryType::DEVICE_LOCAL, - (shaderBindingTableSize + baseAlignment - 1) / baseAlignment, - false + shaderBindingTableSize, + false, + baseAlignment ); - vk::DeviceAddress bufferBaseAddress = bufferManager.getBufferDeviceAddress( + const vk::DeviceAddress bufferBaseAddress = bufferManager.getBufferDeviceAddress( shaderBindingTable ); - size_t bufferBaseOffset = 0; - if (bufferBaseAddress % baseAlignment != 0) { - bufferBaseOffset = (baseAlignment - (bufferBaseAddress % baseAlignment)); - bufferBaseAddress += bufferBaseOffset; - } - void* mappedBindingTable = bufferManager.mapBuffer( shaderBindingTable, - bufferBaseOffset, + 0, shaderBindingTableSize ); -- GitLab