You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.4 KiB
176 lines
6.4 KiB
/*
|
|
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
/**
|
|
|
|
\class nvvk::RaytracingBuilderNV
|
|
|
|
\brief nvvk::RaytracingBuilderNV is a base functionality of raytracing
|
|
|
|
This class does not implement all what you need to do raytracing, but
|
|
helps creating the BLAS and TLAS, which then can be used by different
|
|
raytracing usage.
|
|
|
|
# Setup and Usage
|
|
\code{.cpp}
|
|
m_rtBuilder.setup(device, memoryAllocator, queueIndex);
|
|
// Create array of VkGeometryNV
|
|
m_rtBuilder.buildBlas(allBlas);
|
|
// Create array of RaytracingBuilder::instance
|
|
m_rtBuilder.buildTlas(instances);
|
|
// Retrieve the acceleration structure
|
|
const VkAccelerationStructureNV& tlas = m.rtBuilder.getAccelerationStructure()
|
|
\endcode
|
|
*/
|
|
|
|
|
|
#include <mutex>
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
#if VK_NV_ray_tracing
|
|
|
|
#include "resourceallocator_vk.hpp"
|
|
#include "commands_vk.hpp" // this is only needed here to satisfy some samples that rely on it
|
|
#include "debug_util_vk.hpp"
|
|
#include "nvh/nvprint.hpp" // this is only needed here to satisfy some samples that rely on it
|
|
#include "nvmath/nvmath.h"
|
|
|
|
// See https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap33.html#acceleration-structure
|
|
struct VkGeometryInstanceNV
|
|
{
|
|
/// Transform matrix, containing only the top 3 rows
|
|
float transform[12];
|
|
/// Instance index
|
|
uint32_t instanceId : 24;
|
|
/// Visibility mask
|
|
uint32_t mask : 8;
|
|
/// Index of the hit group which will be invoked when a ray hits the instance
|
|
uint32_t hitGroupId : 24;
|
|
/// Instance flags, such as culling
|
|
uint32_t flags : 8;
|
|
/// Opaque handle of the bottom-level acceleration structure
|
|
uint64_t accelerationStructureHandle;
|
|
};
|
|
|
|
namespace nvvk {
|
|
class RaytracingBuilderNV
|
|
{
|
|
public:
|
|
RaytracingBuilderNV(RaytracingBuilderNV const&) = delete;
|
|
RaytracingBuilderNV& operator=(RaytracingBuilderNV const&) = delete;
|
|
|
|
RaytracingBuilderNV() = default;
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Initializing the allocator and querying the raytracing properties
|
|
//
|
|
void setup(VkDevice device, nvvk::ResourceAllocator* allocator, uint32_t queueIndex);
|
|
|
|
// This is an instance of a BLAS
|
|
struct Instance
|
|
{
|
|
uint32_t blasId{0}; // Index of the BLAS in m_blas
|
|
uint32_t instanceId{0}; // Instance Index (gl_InstanceID)
|
|
uint32_t hitGroupId{0}; // Hit group index in the SBT
|
|
uint32_t mask{0xFF}; // Visibility mask, will be AND-ed with ray mask
|
|
VkGeometryInstanceFlagsNV flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
|
nvmath::mat4f transform{nvmath::mat4f(1)}; // Identity
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Destroying all allocations
|
|
//
|
|
void destroy();
|
|
|
|
// Returning the constructed top-level acceleration structure
|
|
VkAccelerationStructureNV getAccelerationStructure() const;
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Create all the BLAS from the vector of vectors of VkGeometryNV
|
|
// - There will be one BLAS per vector of VkGeometryNV
|
|
// - There will be as many BLAS there are items in the geoms vector
|
|
// - The resulting BLAS are stored in m_blas
|
|
//
|
|
void buildBlas(const std::vector<std::vector<VkGeometryNV>>& geoms,
|
|
VkBuildAccelerationStructureFlagsNV flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV);
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Convert an Instance object into a VkGeometryInstanceNV
|
|
|
|
VkGeometryInstanceNV instanceToVkGeometryInstanceNV(const Instance& instance);
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Creating the top-level acceleration structure from the vector of Instance
|
|
// - See struct of Instance
|
|
// - The resulting TLAS will be stored in m_tlas
|
|
//
|
|
void buildTlas(const std::vector<Instance>& instances,
|
|
VkBuildAccelerationStructureFlagsNV flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV);
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Refit the TLAS using new instance matrices
|
|
//
|
|
void updateTlasMatrices(const std::vector<Instance>& instances);
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Refit the BLAS from updated buffers
|
|
//
|
|
void updateBlas(uint32_t blasIdx);
|
|
|
|
private:
|
|
// Bottom-level acceleration structure
|
|
struct Blas
|
|
{
|
|
nvvk::AccelNV as;
|
|
VkAccelerationStructureInfoNV asInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV, nullptr,
|
|
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV};
|
|
VkGeometryNV geometry;
|
|
};
|
|
|
|
// Top-level acceleration structure
|
|
struct Tlas
|
|
{
|
|
nvvk::AccelNV as;
|
|
VkAccelerationStructureInfoNV asInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV, nullptr,
|
|
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV};
|
|
};
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Vector containing all the BLASes built and referenced by the TLAS
|
|
std::vector<Blas> m_blas;
|
|
// Top-level acceleration structure
|
|
Tlas m_tlas;
|
|
// Instance buffer containing the matrices and BLAS ids
|
|
nvvk::Buffer m_instBuffer;
|
|
|
|
VkDevice m_device;
|
|
uint32_t m_queueIndex{0};
|
|
|
|
nvvk::ResourceAllocator* m_alloc = nullptr;
|
|
nvvk::DebugUtil m_debug;
|
|
};
|
|
|
|
} // namespace nvvk
|
|
|
|
#else
|
|
#error This include requires VK_NV_ray_tracing support in the Vulkan SDK.
|
|
#endif
|
|
|