2020namespace nbl ::asset
2121{
2222
23- class IAccelerationStructure : public IDescriptor
23+ class IAccelerationStructure : public virtual core::IReferenceCounted
2424{
2525 public:
26+ // build flags, we don't expose flags that don't make sense for certain levels
27+ enum class BUILD_FLAGS : uint8_t
28+ {
29+ ALLOW_UPDATE_BIT = 0x1u << 0u ,
30+ ALLOW_COMPACTION_BIT = 0x1u << 1u ,
31+ PREFER_FAST_TRACE_BIT = 0x1u << 2u ,
32+ PREFER_FAST_BUILD_BIT = 0x1u << 3u ,
33+ LOW_MEMORY_BIT = 0x1u << 4u ,
34+ // Provided by VK_NV_ray_tracing_motion_blur, but is ignored for BLASes and we always override and deduce from TLAS creation flag because of
35+ // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-dstAccelerationStructure-04927
36+ // MOTION_BIT = 0x1u<<5u,
37+ ALL_MASK = (01u <<5u )-1 ,
38+ };
39+
2640 // we don't expose the GENERIC type because Vulkan only intends it for API-translation layers like VKD3D or MoltenVK
2741 virtual bool isBLAS () const = 0;
2842
29- // !
30- inline E_CATEGORY getTypeCategory () const override { return EC_ACCELERATION_STRUCTURE; }
43+ virtual bool usesMotion () const = 0;
3144
3245 protected:
3346 IAccelerationStructure () = default ;
3447};
3548
36- template <class AccelerationStructure >
37- class IBottomLevelAccelerationStructure : public AccelerationStructure
49+ NBL_ENUM_ADD_BITWISE_OPERATORS (IAccelerationStructure::BUILD_FLAGS);
50+
51+ // To avoid having duplicate instantiations of flags, etc.
52+ class IBottomLevelAccelerationStructure : public IAccelerationStructure
3853{
39- static_assert (std::is_base_of_v<IAccelerationStructure,AccelerationStructure>);
54+ using base_build_flags_t = IAccelerationStructure::BUILD_FLAGS;
55+
4056 public:
41- inline bool isBLAS () const override {return true ;}
57+ inline bool isBLAS () const override { return true ; }
4258
4359 // build flags, we don't expose flags that don't make sense for certain levels
4460 enum class BUILD_FLAGS : uint16_t
4561 {
46- ALLOW_UPDATE_BIT = 0x1u << 0u ,
47- ALLOW_COMPACTION_BIT = 0x1u << 1u ,
48- PREFER_FAST_TRACE_BIT = 0x1u << 2u ,
49- PREFER_FAST_BUILD_BIT = 0x1u << 3u ,
50- LOW_MEMORY_BIT = 0x1u << 4u ,
62+ ALLOW_UPDATE_BIT = base_build_flags_t ::ALLOW_UPDATE_BIT ,
63+ ALLOW_COMPACTION_BIT = base_build_flags_t ::ALLOW_COMPACTION_BIT ,
64+ PREFER_FAST_TRACE_BIT = base_build_flags_t ::PREFER_FAST_TRACE_BIT ,
65+ PREFER_FAST_BUILD_BIT = base_build_flags_t ::PREFER_FAST_BUILD_BIT ,
66+ LOW_MEMORY_BIT = base_build_flags_t ::LOW_MEMORY_BIT ,
5167 // Synthetic flag we use to indicate that the build data are AABBs instead of triangles, we've taken away the per-geometry choice thanks to:
5268 // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03792
5369 GEOMETRY_TYPE_IS_AABB_BIT = 0x1u <<5u ,
54- // Provided by VK_NV_ray_tracing_motion_blur, but is ignored for BLASes
55- // MOTION_BIT = 0x1u<<5u
5670 // Provided by VK_EXT_opacity_micromap
5771 ALLOW_OPACITY_MICROMAP_UPDATE_BIT = 0x1u <<6u ,
5872 ALLOW_DISABLE_OPACITY_MICROMAPS_BIT = 0x1u <<7u ,
5973 ALLOW_OPACITY_MICROMAP_DATA_UPDATE_BIT = 0x1u <<8u ,
6074 // Provided by VK_NV_displacement_micromap
6175 ALLOW_DISPLACEMENT_MICROMAP_UPDATE_BIT = 0x1u <<9u ,
6276 // Provided by VK_KHR_ray_tracing_position_fetch
63- ALLOW_DATA_ACCESS_KHR = 0x1u <<11u ,
77+ ALLOW_DATA_ACCESS = 0x1u <<11u ,
6478 };
65- static inline bool validBuildFlags (const core::bitflag<BUILD_FLAGS> flags)
66- {
67- // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-03796
68- if (flags.hasFlags (BUILD_FLAGS::PREFER_FAST_BUILD_BIT) && flags.hasFlags (BUILD_FLAGS::PREFER_FAST_TRACE_BIT))
69- return false ;
7079
71- // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-07334
72- if (flags.hasFlags (BUILD_FLAGS::ALLOW_OPACITY_MICROMAP_UPDATE_BIT) && flags.hasFlags (BUILD_FLAGS::ALLOW_OPACITY_MICROMAP_DATA_UPDATE_BIT))
73- return false ;
74-
75- return true ;
76- }
7780
7881 // Apparently Vulkan allows setting these on TLAS Geometry (which are instances) but applying them to a TLAS doesn't make any SENSE AT ALL!
7982 enum class GEOMETRY_FLAGS : uint8_t
@@ -132,42 +135,40 @@ class IBottomLevelAccelerationStructure : public AccelerationStructure
132135 using AABB_t = core::aabbox3d<float >;
133136
134137 protected:
135- using AccelerationStructure::AccelerationStructure;
138+ using base_build_flags_t = IAccelerationStructure::BUILD_FLAGS;
139+ using IAccelerationStructure::IAccelerationStructure;
136140 virtual ~IBottomLevelAccelerationStructure () = default ;
137- };
138-
139- // forward declare for `static_assert`
140- class ICPUBottomLevelAccelerationStructure ;
141141
142- template <class AccelerationStructure >
143- class ITopLevelAccelerationStructure : public AccelerationStructure
144- {
145- static_assert (std::is_base_of_v<IAccelerationStructure,AccelerationStructure>);
146- public:
147- inline bool isBLAS () const override {return false ;}
148-
149- // build flags, we don't expose flags that don't make sense for certain levels
150- enum class BUILD_FLAGS : uint8_t
151- {
152- ALLOW_UPDATE_BIT = 0x1u <<0u ,
153- ALLOW_COMPACTION_BIT = 0x1u <<1u ,
154- PREFER_FAST_TRACE_BIT = 0x1u <<2u ,
155- PREFER_FAST_BUILD_BIT = 0x1u <<3u ,
156- LOW_MEMORY_BIT = 0x1u <<4u ,
157- // Synthetic flag we use to indicate `VkAccelerationStructureGeometryInstancesDataKHR::arrayOfPointers`
158- INSTANCE_DATA_IS_POINTERS_TYPE_ENCODED_LSB = 0x1u <<5u , // this flag really shouldn't be settable outside of `video::IGPU`
159- // Provided by VK_NV_ray_tracing_motion_blur, but we always override and deduce from creation flag because of
160- // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-dstAccelerationStructure-04927
161- // MOTION_BIT = 0x1u<<5u,
162- };
163142 static inline bool validBuildFlags (const core::bitflag<BUILD_FLAGS> flags)
164143 {
165144 // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-03796
166145 if (flags.hasFlags (BUILD_FLAGS::PREFER_FAST_BUILD_BIT) && flags.hasFlags (BUILD_FLAGS::PREFER_FAST_TRACE_BIT))
167146 return false ;
168147
148+ // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-07334
149+ if (flags.hasFlags (BUILD_FLAGS::ALLOW_OPACITY_MICROMAP_UPDATE_BIT) && flags.hasFlags (BUILD_FLAGS::ALLOW_OPACITY_MICROMAP_DATA_UPDATE_BIT))
150+ return false ;
151+
169152 return true ;
170153 }
154+ };
155+ NBL_ENUM_ADD_BITWISE_OPERATORS (IBottomLevelAccelerationStructure::BUILD_FLAGS);
156+
157+ // forward declare for `static_assert`
158+ class ICPUBottomLevelAccelerationStructure ;
159+
160+ class ITopLevelAccelerationStructure : public IDescriptor , public IAccelerationStructure
161+ {
162+ using base_build_flags_t = IAccelerationStructure::BUILD_FLAGS;
163+
164+ public:
165+ // !
166+ inline E_CATEGORY getTypeCategory () const override {return EC_ACCELERATION_STRUCTURE;}
167+
168+ inline bool isBLAS () const override {return false ;}
169+
170+ // No extra flags for TLAS builds
171+ using BUILD_FLAGS = base_build_flags_t ;
171172
172173 enum class INSTANCE_FLAGS : uint8_t
173174 {
@@ -182,9 +183,10 @@ class ITopLevelAccelerationStructure : public AccelerationStructure
182183 FORCE_DISABLE_OPACITY_MICROMAPS_BIT = 0x1u <<5u ,
183184 };
184185 // Note: `core::matrix3x4SIMD` is equvalent to VkTransformMatrixKHR, 4x3 row_major matrix
185- template <typename blas_ref_t >
186+ template <typename _blas_ref_t >
186187 struct Instance final
187188 {
189+ using blas_ref_t = _blas_ref_t ;
188190 static_assert (sizeof (blas_ref_t )==8 && alignof (blas_ref_t )==8 );
189191 static_assert (std::is_same_v<core::smart_refctd_ptr<ICPUBottomLevelAccelerationStructure>,blas_ref_t > || std::is_standard_layout_v<blas_ref_t >);
190192
@@ -237,7 +239,7 @@ class ITopLevelAccelerationStructure : public AccelerationStructure
237239 static_assert (alignof (Instance<blas_ref_t >)==8ull );
238240 };
239241
240- // enum for distinguishing unions of Instance Types when there is no `INSTANCE_DATA_IS_POINTERS_TYPE_ENCODED_LSB` in build flags
242+ // enum for distinguishing unions of Instance Types when using a polymorphic instance
241243 enum class INSTANCE_TYPE : uint32_t
242244 {
243245 // StaticInstance
@@ -248,9 +250,33 @@ class ITopLevelAccelerationStructure : public AccelerationStructure
248250 SRT_MOTION
249251 };
250252
253+ static uint16_t getInstanceSize (const INSTANCE_TYPE type)
254+ {
255+ switch (type)
256+ {
257+ case INSTANCE_TYPE::SRT_MOTION:
258+ return sizeof ( SRTMotionInstance<ptrdiff_t >);
259+ break ;
260+ case INSTANCE_TYPE::MATRIX_MOTION:
261+ return sizeof (MatrixMotionInstance<ptrdiff_t >);
262+ break ;
263+ default :
264+ break ;
265+ }
266+ return sizeof (StaticInstance<ptrdiff_t >);
267+ }
268+
251269 protected:
252- using AccelerationStructure::AccelerationStructure ;
270+ using IAccelerationStructure::IAccelerationStructure ;
253271 virtual ~ITopLevelAccelerationStructure () = default ;
272+
273+ static inline bool validBuildFlags (const core::bitflag<BUILD_FLAGS> flags)
274+ {
275+ // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-03796
276+ if (flags.hasFlags (BUILD_FLAGS::PREFER_FAST_BUILD_BIT) && flags.hasFlags (BUILD_FLAGS::PREFER_FAST_TRACE_BIT))
277+ return false ;
278+ return true ;
279+ }
254280};
255281
256282} // end namespace nbl::asset
0 commit comments