Browse Source

Some more RT code in resource and scene

Panagiotis Christopoulos Charitos 5 years ago
parent
commit
f9dc0ea0ce

+ 17 - 0
anki/renderer/RenderQueue.h

@@ -9,6 +9,7 @@
 #include <anki/resource/RenderingKey.h>
 #include <anki/ui/Canvas.h>
 #include <anki/shaders/include/ClusteredShadingTypes.h>
+#include <anki/shaders/include/ModelTypes.h>
 
 namespace anki
 {
@@ -347,6 +348,21 @@ static_assert(std::is_trivially_destructible<FogDensityQueueElement>::value == t
 /// A callback to fill a coverage buffer.
 using FillCoverageBufferCallback = void (*)(void* userData, F32* depthValues, U32 width, U32 height);
 
+/// Ray tracing queue element.
+class RayTracingInstanceQueueElement final
+{
+public:
+	ModelGpuDescriptor m_modelDescriptor;
+	Array<ConstWeakArray<U8>, U(RayTracingMaterialType::COUNT)> m_shaderGroupHandles;
+
+	/// This points to the GR objects that are m_modelDescriptor is referencing. Use this to add a refcount to avoid
+	/// accidential deletions.
+	WeakArray<GrObject*> m_grObjects;
+};
+
+static_assert(std::is_trivially_destructible<RayTracingInstanceQueueElement>::value == true,
+			  "Should be trivially destructible");
+
 /// The render queue. This is what the renderer is fed to render.
 class RenderQueue : public RenderingMatrices
 {
@@ -366,6 +382,7 @@ public:
 	WeakArray<FogDensityQueueElement> m_fogDensityVolumes;
 	WeakArray<UiQueueElement> m_uis;
 	WeakArray<GenericGpuComputeJobQueueElement> m_genericGpuComputeJobs;
+	WeakArray<RayTracingInstanceQueueElement> m_rayTracingInstances;
 
 	/// Applies only if the RenderQueue holds shadow casters. It's the max timesamp of all shadow casters
 	Timestamp m_shadowRenderablesLastUpdateTimestamp = 0;

+ 12 - 0
anki/resource/Common.h

@@ -53,6 +53,18 @@ enum class VertexAttributeLocation : U8
 	FIRST = POSITION,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VertexAttributeLocation)
+
+enum class RayTracingMaterialType : U8
+{
+	SHADOWS,
+	GI,
+	REFLECTIONS,
+	PATH_TRACING,
+
+	COUNT,
+	FIRST = 0
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(RayTracingMaterialType)
 /// @}
 
 /// Deleter for ResourcePtr.

+ 4 - 2
anki/resource/MaterialResource.cpp

@@ -1156,11 +1156,13 @@ Error MaterialResource::parseRtMaterial(XmlElement rtMaterialEl)
 					const U32 textureIdx = GPU_MATERIAL_TEXTURES[i].m_textureSlot;
 					ANKI_CHECK(getManager().loadResource(fname, variant.m_textureResources[textureIdx], false));
 
-					variant.m_textureViews[textureIdx] = variant.m_textureResources[textureIdx]->getGrTextureView();
+					variant.m_textureViews[variant.m_textureViewCount] =
+						variant.m_textureResources[textureIdx]->getGrTextureView();
 
 					gpuMaterial.m_bindlessTextureIndices[textureIdx] =
-						U16(variant.m_textureViews[textureIdx]->getOrCreateBindlessTextureIndex());
+						U16(variant.m_textureViews[variant.m_textureViewCount]->getOrCreateBindlessTextureIndex());
 
+					++variant.m_textureViewCount;
 					found = true;
 					break;
 				}

+ 16 - 14
anki/resource/MaterialResource.h

@@ -22,18 +22,6 @@ class XmlElement;
 /// @addtogroup resource
 /// @{
 
-enum class RayTracingMaterialType : U8
-{
-	SHADOWS,
-	GI,
-	REFLECTIONS,
-	PATH_TRACING,
-
-	COUNT,
-	FIRST = 0
-};
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(RayTracingMaterialType)
-
 /// The ID of a buildin material variable.
 enum class BuiltinMaterialVariableId : U8
 {
@@ -283,9 +271,10 @@ public:
 		return m_materialGpuDescriptor;
 	}
 
-	const Array<TextureViewPtr, TEXTURE_CHANNEL_COUNT>& getTextureViews() const
+	/// Get the texture views that are referenced by what getMaterialGpuDescriptor() returned. Used for life tracking.
+	const ConstWeakArray<TextureViewPtr> getTextureViews() const
 	{
-		return m_textureViews;
+		return ConstWeakArray<TextureViewPtr>((m_textureViewCount) ? &m_textureViews[0] : nullptr, m_textureViewCount);
 	}
 
 private:
@@ -293,6 +282,7 @@ private:
 	MaterialGpuDescriptor m_materialGpuDescriptor;
 	Array<TextureResourcePtr, TEXTURE_CHANNEL_COUNT> m_textureResources; ///< Keep the resources alive.
 	Array<TextureViewPtr, TEXTURE_CHANNEL_COUNT> m_textureViews; ///< Cache the GPU objects.
+	U8 m_textureViewCount = 0;
 
 	RayTracingMaterialVariant()
 	{
@@ -392,6 +382,18 @@ public:
 
 	const MaterialVariant& getOrCreateVariant(const RenderingKey& key) const;
 
+	const RayTracingMaterialVariant& getRayTracingVariant(U32 lod, RayTracingMaterialType type) const
+	{
+		(void)lod; // Not supported for now
+		ANKI_ASSERT(m_rt[type].m_prog.isCreated());
+		return m_rt[type].m_variant;
+	}
+
+	Bool getRayTracingTypeSupported(RayTracingMaterialType type) const
+	{
+		return m_rt[type].m_prog.isCreated();
+	}
+
 private:
 	class SubMutation
 	{

+ 18 - 3
anki/resource/MeshResource.h

@@ -117,6 +117,18 @@ public:
 		return m_meshGpuDescriptor;
 	}
 
+	/// Get the buffer that contains all the indices of all submesses.
+	BufferPtr getIndexBuffer() const
+	{
+		return m_indexBuff;
+	}
+
+	/// Get the buffer that contains all the vertices of all submesses.
+	BufferPtr getVertexBuffer() const
+	{
+		return m_vertBuff;
+	}
+
 private:
 	class LoadTask;
 	class LoadContext;
@@ -124,8 +136,9 @@ private:
 	static constexpr U VERTEX_BUFFER_ALIGNMENT = 64;
 
 	/// Sub-mesh data
-	struct SubMesh
+	class SubMesh
 	{
+	public:
 		U32 m_firstIndex;
 		U32 m_indexCount;
 		Obb m_obb;
@@ -140,15 +153,17 @@ private:
 	// Vertex stuff
 	U32 m_vertCount = 0;
 
-	struct VertBuffInfo
+	class VertBuffInfo
 	{
+	public:
 		U32 m_offset; ///< Offset from the base of m_vertBuff.
 		U32 m_stride;
 	};
 	DynamicArray<VertBuffInfo> m_vertBufferInfos;
 
-	struct AttribInfo
+	class AttribInfo
 	{
+	public:
 		Format m_fmt = Format::NONE;
 		U32 m_relativeOffset = 0;
 		U8 m_buffIdx = 0;

+ 32 - 2
anki/resource/ModelResource.cpp

@@ -30,8 +30,8 @@ static Bool attributeIsRequired(VertexAttributeLocation loc, Pass pass, Bool has
 	}
 }
 
-void ModelPatch::getRenderingDataSub(const RenderingKey& key, WeakArray<U8> subMeshIndicesArray,
-									 ModelRenderingInfo& inf) const
+void ModelPatch::getRenderingInfo(const RenderingKey& key, WeakArray<U8> subMeshIndicesArray,
+								  ModelRenderingInfo& inf) const
 {
 	const Bool hasSkin = m_model->getSkeleton().isCreated();
 
@@ -104,6 +104,36 @@ void ModelPatch::getRenderingDataSub(const RenderingKey& key, WeakArray<U8> subM
 	inf.m_indicesCountArray[0] = indexCount;
 }
 
+Bool ModelPatch::getRayTracingInfo(U32 lod, RayTracingMaterialType type, ModelRayTracingInfo& info) const
+{
+	const Bool supported = m_mtl->getRayTracingTypeSupported(type);
+	if(!supported)
+	{
+		return false;
+	}
+
+	info.m_grObjectReferenceCount = 0;
+	memset(&info.m_descriptor, 0, sizeof(info.m_descriptor));
+
+	// Mesh
+	const MeshResourcePtr& mesh = m_meshes[min(U32(m_meshCount - 1), lod)];
+	info.m_bottomLevelAccelerationStructure = mesh->getBottomLevelAccelerationStructure();
+	info.m_descriptor.m_mesh = mesh->getMeshGpuDescriptor();
+	info.m_grObjectReferences[info.m_grObjectReferenceCount++] = mesh->getIndexBuffer();
+	info.m_grObjectReferences[info.m_grObjectReferenceCount++] = mesh->getVertexBuffer();
+
+	// Material
+	const RayTracingMaterialVariant& materialVariant = m_mtl->getRayTracingVariant(lod, type);
+	info.m_descriptor.m_material = materialVariant.getMaterialGpuDescriptor();
+	info.m_shaderGroupHandle = materialVariant.getHitShaderGroupHandle();
+	for(U32 i = 0; i < materialVariant.getTextureViews().getSize(); ++i)
+	{
+		info.m_grObjectReferences[info.m_grObjectReferenceCount++] = materialVariant.getTextureViews()[i];
+	}
+
+	return true;
+}
+
 U32 ModelPatch::getLodCount() const
 {
 	return max<U32>(m_meshCount, getMaterial()->getLodCount());

+ 18 - 4
anki/resource/ModelResource.h

@@ -17,9 +17,6 @@
 namespace anki
 {
 
-// Forward
-class PhysicsCollisionShape;
-
 /// @addtogroup resource
 /// @{
 
@@ -83,6 +80,19 @@ public:
 	U32 m_prevFrameBoneTransformsBinding;
 };
 
+/// Part of the information required to create a TLAS and a SBT.
+class ModelRayTracingInfo
+{
+public:
+	ModelGpuDescriptor m_descriptor;
+	AccelerationStructurePtr m_bottomLevelAccelerationStructure;
+	ConstWeakArray<U8> m_shaderGroupHandle;
+
+	/// Get some pointers that the m_descriptor is pointing to. Use these pointers for life tracking.
+	Array<GrObjectPtr, TEXTURE_CHANNEL_COUNT + 2> m_grObjectReferences;
+	U32 m_grObjectReferenceCount;
+};
+
 /// Model patch interface class. Its very important class and it binds the material with the mesh
 class ModelPatch
 {
@@ -125,7 +135,11 @@ public:
 
 	/// Get information for multiDraw rendering. Given an array of submeshes that are visible return the correct indices
 	/// offsets and counts.
-	void getRenderingDataSub(const RenderingKey& key, WeakArray<U8> subMeshIndicesArray, ModelRenderingInfo& inf) const;
+	void getRenderingInfo(const RenderingKey& key, WeakArray<U8> subMeshIndicesArray, ModelRenderingInfo& inf) const;
+
+	/// Get the ray tracing info.
+	/// @return Return's false if the @a type is not supported.
+	Bool getRayTracingInfo(U32 lod, RayTracingMaterialType type, ModelRayTracingInfo& info) const;
 
 private:
 	ModelResource* m_model ANKI_DEBUG_CODE(= nullptr);

+ 0 - 20
anki/resource/RenderingKey.h

@@ -126,24 +126,4 @@ constexpr Bool isPacked<RenderingKey>()
 	return sizeof(RenderingKey) == 5;
 }
 
-/// The hash function
-class RenderingKeyHasher
-{
-public:
-	U64 operator()(const RenderingKey& key) const
-	{
-		return computeHash(&key, sizeof(key));
-	}
-};
-
-/// The collision evaluation function
-class RenderingKeyEqual
-{
-public:
-	Bool operator()(const RenderingKey& a, const RenderingKey& b) const
-	{
-		return a == b;
-	}
-};
-
 } // end namespace anki

+ 16 - 4
anki/scene/CameraNode.cpp

@@ -7,6 +7,7 @@
 #include <anki/scene/components/FrustumComponent.h>
 #include <anki/scene/components/MoveComponent.h>
 #include <anki/scene/components/SpatialComponent.h>
+#include <anki/scene/SceneGraph.h>
 
 namespace anki
 {
@@ -78,7 +79,7 @@ Error CameraNode::init(FrustumType frustumType)
 
 	// Frustum component
 	FrustumComponent* frc = newComponent<FrustumComponent>(this, frustumType);
-	frc->setEnabledVisibilityTests(
+	const FrustumComponentVisibilityTestFlag visibilityFlags =
 		FrustumComponentVisibilityTestFlag::RENDER_COMPONENTS | FrustumComponentVisibilityTestFlag::LIGHT_COMPONENTS
 		| FrustumComponentVisibilityTestFlag::LENS_FLARE_COMPONENTS
 		| FrustumComponentVisibilityTestFlag::REFLECTION_PROBES | FrustumComponentVisibilityTestFlag::REFLECTION_PROXIES
@@ -86,7 +87,15 @@ Error CameraNode::init(FrustumType frustumType)
 		| FrustumComponentVisibilityTestFlag::FOG_DENSITY_COMPONENTS
 		| FrustumComponentVisibilityTestFlag::GLOBAL_ILLUMINATION_PROBES | FrustumComponentVisibilityTestFlag::EARLY_Z
 		| FrustumComponentVisibilityTestFlag::ALL_SHADOWS_ENABLED
-		| FrustumComponentVisibilityTestFlag::GENERIC_COMPUTE_JOB_COMPONENTS);
+		| FrustumComponentVisibilityTestFlag::GENERIC_COMPUTE_JOB_COMPONENTS;
+	frc->setEnabledVisibilityTests(visibilityFlags);
+
+	// One more component for RT
+	if(getSceneGraph().getRayTracedShadowsEnabled())
+	{
+		FrustumComponent* rtFrustumComponent = newComponent<FrustumComponent>(this, FrustumType::ORTHOGRAPHIC);
+		rtFrustumComponent->setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::RAY_TRACING_SHADOWS);
+	}
 
 	// Feedback component #2
 	newComponent<FrustumFeedbackComponent>();
@@ -117,8 +126,11 @@ void CameraNode::onFrustumComponentUpdate(FrustumComponent& fr)
 void CameraNode::onMoveComponentUpdate(MoveComponent& move)
 {
 	// Frustum
-	FrustumComponent& fr = getComponent<FrustumComponent>();
-	fr.setTransform(move.getWorldTransform());
+	const Error err = iterateComponentsOfType<FrustumComponent>([&](FrustumComponent& fc) {
+		fc.setTransform(move.getWorldTransform());
+		return Error::NONE;
+	});
+	(void)err;
 
 	// Spatial
 	SpatialComponent& sp = getComponent<SpatialComponent>();

+ 1 - 0
anki/scene/ConfigDefs.h

@@ -8,3 +8,4 @@ ANKI_CONFIG_OPTION(scene_earlyZDistance, 10.0, 0.0, MAX_F64,
 ANKI_CONFIG_OPTION(scene_reflectionProbeEffectiveDistance, 256.0, 1.0, MAX_F64, "How far reflection probes can look")
 ANKI_CONFIG_OPTION(scene_reflectionProbeShadowEffectiveDistance, 32.0, 1.0, MAX_F64,
 				   "How far to render shadows for reflection probes")
+ANKI_CONFIG_OPTION(scene_rayTracedShadows, 0, 0, 1, "Enable or not ray traced shadows. Ignored if RT is not supported")

+ 1 - 1
anki/scene/ModelNode.cpp

@@ -180,7 +180,7 @@ void ModelNode::draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData
 
 		ctx.m_key.setVelocity(moved && ctx.m_key.getPass() == Pass::GB);
 		ModelRenderingInfo modelInf;
-		patch.getRenderingDataSub(ctx.m_key, WeakArray<U8>(), modelInf);
+		patch.getRenderingInfo(ctx.m_key, WeakArray<U8>(), modelInf);
 
 		// Bones storage
 		if(m_model->getSkeleton())

+ 2 - 0
anki/scene/SceneGraph.cpp

@@ -89,6 +89,8 @@ Error SceneGraph::init(AllocAlignedCallback allocCb, void* allocCbData, ThreadHi
 	PhysicsDebugNode* pnode;
 	ANKI_CHECK(newSceneNode<PhysicsDebugNode>("_physicsDebugNode", pnode));
 
+	m_enableRtShadows = config.getBool("scene_rayTracedShadows") && m_gr->getDeviceCapabilities().m_rayTracingEnabled;
+
 	return Error::NONE;
 }
 

+ 7 - 0
anki/scene/SceneGraph.h

@@ -223,6 +223,11 @@ public:
 		return *m_octree;
 	}
 
+	Bool getRayTracedShadowsEnabled() const
+	{
+		return m_enableRtShadows;
+	}
+
 private:
 	class UpdateSceneNodesCtx;
 
@@ -262,6 +267,8 @@ private:
 	SceneGraphLimits m_limits;
 	SceneGraphStats m_stats;
 
+	Bool m_enableRtShadows = false;
+
 	/// Put a node in the appropriate containers
 	ANKI_USE_RESULT Error registerNode(SceneNode* node);
 	void unregisterNode(SceneNode* node);

+ 2 - 6
anki/scene/SceneNode.h

@@ -134,10 +134,8 @@ public:
 	template<typename Component>
 	Component* tryGetComponent()
 	{
-		U32 count = m_components.getSize();
-		while(count-- != 0)
+		for(SceneComponent* comp : m_components)
 		{
-			SceneComponent* comp = m_components[count];
 			if(comp->getType() == Component::CLASS_TYPE)
 			{
 				return static_cast<Component*>(comp);
@@ -150,10 +148,8 @@ public:
 	template<typename Component>
 	const Component* tryGetComponent() const
 	{
-		U32 count = m_components.getSize();
-		while(count-- != 0)
+		for(const SceneComponent* comp : m_components)
 		{
-			const SceneComponent* comp = m_components[count];
 			if(comp->getType() == Component::CLASS_TYPE)
 			{
 				return static_cast<const Component*>(comp);

+ 7 - 4
anki/scene/components/FrustumComponent.h

@@ -20,7 +20,7 @@ namespace anki
 /// @{
 
 /// Flags that affect visibility tests.
-enum class FrustumComponentVisibilityTestFlag : U16
+enum class FrustumComponentVisibilityTestFlag : U32
 {
 	NONE = 0,
 	RENDER_COMPONENTS = 1 << 0,
@@ -39,13 +39,16 @@ enum class FrustumComponentVisibilityTestFlag : U16
 	GLOBAL_ILLUMINATION_PROBES = 1 << 13,
 	EARLY_Z = 1 << 14,
 	GENERIC_COMPUTE_JOB_COMPONENTS = 1 << 15,
-
-	LAST = GENERIC_COMPUTE_JOB_COMPONENTS,
+	RAY_TRACING_SHADOWS = 1 << 16,
+	RAY_TRACING_GI = 1 << 17,
+	RAY_TRACING_REFLECTIONS = 1 << 18,
+	RAY_TRACING_PATH_TRACING = 1 << 19,
 
 	ALL = RENDER_COMPONENTS | LIGHT_COMPONENTS | LENS_FLARE_COMPONENTS | SHADOW_CASTERS | POINT_LIGHT_SHADOWS_ENABLED
 		  | SPOT_LIGHT_SHADOWS_ENABLED | DIRECTIONAL_LIGHT_SHADOWS_ALL_CASCADES | DIRECTIONAL_LIGHT_SHADOWS_1_CASCADE
 		  | REFLECTION_PROBES | REFLECTION_PROXIES | OCCLUDERS | DECALS | FOG_DENSITY_COMPONENTS
-		  | GLOBAL_ILLUMINATION_PROBES | EARLY_Z | GENERIC_COMPUTE_JOB_COMPONENTS,
+		  | GLOBAL_ILLUMINATION_PROBES | EARLY_Z | GENERIC_COMPUTE_JOB_COMPONENTS | RAY_TRACING_SHADOWS | RAY_TRACING_GI
+		  | RAY_TRACING_REFLECTIONS | RAY_TRACING_PATH_TRACING,
 
 	ALL_SHADOWS_ENABLED =
 		POINT_LIGHT_SHADOWS_ENABLED | SPOT_LIGHT_SHADOWS_ENABLED | DIRECTIONAL_LIGHT_SHADOWS_ALL_CASCADES