/* * Copyright 2019-2021 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * 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. * * In no event and under no legal theory, whether in tort (including negligence), * contract, or otherwise, unless required by applicable law (such as deliberate * and grossly negligent acts) or agreed to in writing, shall any Contributor be * liable for any damages, including any direct, indirect, special, incidental, * or consequential damages of any character arising as a result of this License or * out of the use or inability to use the software (including but not limited to damages * for loss of goodwill, work stoppage, computer failure or malfunction, or any and * all other commercial damages or losses), even if such Contributor has been advised * of the possibility of such damages. */ #pragma once /// \file /// Definition of the Diligent::ITopLevelAS interface and related data structures #include "../../../Primitives/interface/Object.h" #include "../../../Primitives/interface/FlagEnum.h" #include "GraphicsTypes.h" #include "Constants.h" #include "Buffer.h" #include "BottomLevelAS.h" DILIGENT_BEGIN_NAMESPACE(Diligent) // {16561861-294B-4804-96FA-1717333F769A} static const INTERFACE_ID IID_TopLevelAS = {0x16561861, 0x294b, 0x4804, {0x96, 0xfa, 0x17, 0x17, 0x33, 0x3f, 0x76, 0x9a}}; // clang-format off /// Top-level AS description. struct TopLevelASDesc DILIGENT_DERIVE(DeviceObjectAttribs) /// Allocate space for specified number of instances. Uint32 MaxInstanceCount DEFAULT_INITIALIZER(0); /// Ray tracing build flags, see Diligent::RAYTRACING_BUILD_AS_FLAGS. RAYTRACING_BUILD_AS_FLAGS Flags DEFAULT_INITIALIZER(RAYTRACING_BUILD_AS_NONE); /// The size returned by IDeviceContext::WriteTLASCompactedSize(), if this acceleration structure /// is going to be the target of a compacting copy command (IDeviceContext::CopyTLAS() with COPY_AS_MODE_COMPACT). Uint32 CompactedSize DEFAULT_INITIALIZER(0); /// Defines which command queues this BLAS can be used with. Uint64 CommandQueueMask DEFAULT_INITIALIZER(1); #if DILIGENT_CPP_INTERFACE TopLevelASDesc() noexcept {} #endif }; typedef struct TopLevelASDesc TopLevelASDesc; /// Defines hit group binding mode used by the top-level AS. DILIGENT_TYPED_ENUM(HIT_GROUP_BINDING_MODE, Uint8) { /// Each geometry in every instance may use a unique hit shader group. /// In this mode, the SBT reserves space for each geometry in every instance in /// the TLAS and uses most memory. /// See IShaderBindingTable::BindHitGroupForGeometry(). HIT_GROUP_BINDING_MODE_PER_GEOMETRY = 0, /// Each instance may use a unique hit shader group. /// In this mode, the SBT reserves one slot for each instance irrespective of /// how many geometries it contains, so it uses less memory. /// See IShaderBindingTable::BindHitGroupForInstance(). HIT_GROUP_BINDING_MODE_PER_INSTANCE, /// All instances in each TLAS will use the same hit group. /// In this mode, the SBT reserves a single slot for one hit group for each TLAS /// and uses least memory. /// See IShaderBindingTable::BindHitGroupForTLAS(). HIT_GROUP_BINDING_MODE_PER_TLAS, /// The user must specify TLASBuildInstanceData::ContributionToHitGroupIndex /// and only use IShaderBindingTable::BindHitGroupByIndex(). HIT_GROUP_BINDING_MODE_USER_DEFINED, HIT_GROUP_BINDING_MODE_LAST = HIT_GROUP_BINDING_MODE_USER_DEFINED, }; /// Defines TLAS state that was used in the last build. struct TLASBuildInfo { /// The number of instances, same as BuildTLASAttribs::InstanceCount. Uint32 InstanceCount DEFAULT_INITIALIZER(0); /// The number of hit shader groups, same as BuildTLASAttribs::HitGroupStride. Uint32 HitGroupStride DEFAULT_INITIALIZER(0); /// Hit group binding mode, same as BuildTLASAttribs::BindingMode. HIT_GROUP_BINDING_MODE BindingMode DEFAULT_INITIALIZER(HIT_GROUP_BINDING_MODE_PER_GEOMETRY); /// First hit group location, same as BuildTLASAttribs::BaseContributionToHitGroupIndex. Uint32 FirstContributionToHitGroupIndex DEFAULT_INITIALIZER(0); /// Last hit group location. Uint32 LastContributionToHitGroupIndex DEFAULT_INITIALIZER(0); }; typedef struct TLASBuildInfo TLASBuildInfo; /// Top-level AS instance description. struct TLASInstanceDesc { /// Index that corresponds to the one specified in TLASBuildInstanceData::ContributionToHitGroupIndex. Uint32 ContributionToHitGroupIndex DEFAULT_INITIALIZER(0); /// The autogenerated index of the instance. /// Same as InstanceIndex() in HLSL and gl_InstanceID in GLSL. Uint32 InstanceIndex DEFAULT_INITIALIZER(0); /// Bottom-level AS that is specified in TLASBuildInstanceData::pBLAS. IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr); #if DILIGENT_CPP_INTERFACE TLASInstanceDesc() noexcept {} #endif }; typedef struct TLASInstanceDesc TLASInstanceDesc; #define DILIGENT_INTERFACE_NAME ITopLevelAS #include "../../../Primitives/interface/DefineInterfaceHelperMacros.h" #define ITopLevelASInclusiveMethods \ IDeviceObjectInclusiveMethods; \ ITopLevelASMethods TopLevelAS /// Top-level AS interface /// Defines the methods to manipulate a TLAS object DILIGENT_BEGIN_INTERFACE(ITopLevelAS, IDeviceObject) { #if DILIGENT_CPP_INTERFACE /// Returns the top level AS description used to create the object virtual const TopLevelASDesc& DILIGENT_CALL_TYPE GetDesc() const override = 0; #endif /// Returns instance description that can be used in shader binding table. /// \param [in] Name - Instance name that is specified in TLASBuildInstanceData::InstanceName. /// \return TLASInstanceDesc object, see Diligent::TLASInstanceDesc. /// If instance does not exist then TLASInstanceDesc::ContributionToHitGroupIndex /// and TLASInstanceDesc::InstanceIndex are set to INVALID_INDEX. /// /// \note Access to the TLAS must be externally synchronized. VIRTUAL TLASInstanceDesc METHOD(GetInstanceDesc)(THIS_ const char* Name) CONST PURE; /// Returns TLAS state after the last build or update operation. /// \return TLASBuildInfo object, see Diligent::TLASBuildInfo. /// /// \note Access to the TLAS must be externally synchronized. VIRTUAL TLASBuildInfo METHOD(GetBuildInfo)(THIS) CONST PURE; /// Returns scratch buffer info for the current acceleration structure. /// \return ScratchBufferSizes object, see Diligent::ScratchBufferSizes. VIRTUAL ScratchBufferSizes METHOD(GetScratchBufferSizes)(THIS) CONST PURE; /// Returns native acceleration structure handle specific to the underlying graphics API /// \return pointer to ID3D12Resource interface, for D3D12 implementation\n /// VkAccelerationStructure handle, for Vulkan implementation VIRTUAL void* METHOD(GetNativeHandle)(THIS) PURE; /// Sets the acceleration structure usage state. /// \note This method does not perform state transition, but /// resets the internal acceleration structure state to the given value. /// This method should be used after the application finished /// manually managing the acceleration structure state and wants to hand over /// state management back to the engine. VIRTUAL void METHOD(SetState)(THIS_ RESOURCE_STATE State) PURE; /// Returns the internal acceleration structure state VIRTUAL RESOURCE_STATE METHOD(GetState)(THIS) CONST PURE; }; DILIGENT_END_INTERFACE #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" #if DILIGENT_C_INTERFACE // clang-format off # define ITopLevelAS_GetInstanceDesc(This, ...) CALL_IFACE_METHOD(TopLevelAS, GetInstanceDesc, This, __VA_ARGS__) # define ITopLevelAS_GetBuildInfo(This) CALL_IFACE_METHOD(TopLevelAS, GetBuildInfo, This) # define ITopLevelAS_GetScratchBufferSizes(This) CALL_IFACE_METHOD(TopLevelAS, GetScratchBufferSizes, This) # define ITopLevelAS_GetNativeHandle(This) CALL_IFACE_METHOD(TopLevelAS, GetNativeHandle, This) # define ITopLevelAS_SetState(This, ...) CALL_IFACE_METHOD(TopLevelAS, SetState, This, __VA_ARGS__) # define ITopLevelAS_GetState(This) CALL_IFACE_METHOD(TopLevelAS, GetState, This) // clang-format on #endif DILIGENT_END_NAMESPACE // namespace Diligent