Explorar el Código

Add some code in the ModelComponent

Panagiotis Christopoulos Charitos hace 2 años
padre
commit
608ee94405

+ 4 - 2
AnKi/Renderer/HiZ.cpp

@@ -193,8 +193,10 @@ void HiZ::populateRenderGraph(RenderingContext& ctx)
 			}
 			else
 			{
-				// Bind something random
-				rgraphCtx.bindImage(0, 1, m_runCtx.m_hiZRt, firstMipSubresource);
+				// Bind something random that is not the 1st mip
+				TextureSubresourceInfo subresource;
+				subresource.m_firstMipmap = 1;
+				rgraphCtx.bindImage(0, 1, m_runCtx.m_hiZRt, subresource);
 			}
 
 			cmdb->bindStorageBuffer(0, 2, m_mipmapping.m_counterBuffer, 0, kMaxPtrSize);

+ 1 - 1
AnKi/Resource/MaterialResource.cpp

@@ -770,7 +770,7 @@ const MaterialVariant& MaterialResource::getOrCreateVariant(const RenderingKey&
 		initInfo.addMutation(kBuiltinMutatorNames[BuiltinMutatorId::kVelocity], MutatorValue(key.getVelocity()));
 	}
 
-	const ShaderProgramResourceVariant* progVariant;
+	const ShaderProgramResourceVariant* progVariant = nullptr;
 	prog.m_prog->getOrCreateVariant(initInfo, progVariant);
 
 	if(!progVariant)

+ 93 - 6
AnKi/Scene/Components/ModelComponent.cpp

@@ -33,6 +33,19 @@ ModelComponent::~ModelComponent()
 			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
 				GpuSceneContiguousArrayType::kMeshLods, patch.m_gpuSceneMeshLodsIndex);
 		}
+
+		if(patch.m_gpuSceneRenderableIndex != kMaxU32)
+		{
+			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
+				GpuSceneContiguousArrayType::kRenderablesGBuffer, patch.m_gpuSceneRenderableIndex);
+		}
+
+		if(patch.m_gpuSceneRenderableBoundingVolumeIndex != kMaxU32)
+		{
+			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
+				GpuSceneContiguousArrayType::kRenderableBoundingVolumesGBuffer,
+				patch.m_gpuSceneRenderableBoundingVolumeIndex);
+		}
 	}
 
 	SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
@@ -64,14 +77,34 @@ void ModelComponent::loadModelResource(CString filename)
 			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
 				GpuSceneContiguousArrayType::kMeshLods, patch.m_gpuSceneMeshLodsIndex);
 		}
+
+		if(patch.m_gpuSceneRenderableIndex != kMaxU32)
+		{
+			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
+				GpuSceneContiguousArrayType::kRenderablesGBuffer, patch.m_gpuSceneRenderableIndex);
+		}
+
+		if(patch.m_gpuSceneRenderableBoundingVolumeIndex != kMaxU32)
+		{
+			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
+				GpuSceneContiguousArrayType::kRenderableBoundingVolumesGBuffer,
+				patch.m_gpuSceneRenderableBoundingVolumeIndex);
+		}
 	}
 
 	m_patchInfos.resize(modelPatchCount);
 	for(U32 i = 0; i < modelPatchCount; ++i)
 	{
-		m_patchInfos[i].m_gpuSceneMeshLodsIndex =
-			U32(SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().allocate(
-				GpuSceneContiguousArrayType::kMeshLods));
+		m_patchInfos[i].m_gpuSceneMeshLodsIndex = SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().allocate(
+			GpuSceneContiguousArrayType::kMeshLods);
+
+		m_patchInfos[i].m_gpuSceneRenderableIndex =
+			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().allocate(
+				GpuSceneContiguousArrayType::kRenderablesGBuffer);
+
+		m_patchInfos[i].m_gpuSceneRenderableBoundingVolumeIndex =
+			SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().allocate(
+				GpuSceneContiguousArrayType::kRenderableBoundingVolumesGBuffer);
 	}
 
 	U32 uniformsSize = 0;
@@ -113,6 +146,8 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		return Error::kNone;
 	}
 
+	const AllGpuSceneContiguousArrays& gpuArrays = SceneGraph::getSingleton().getAllGpuSceneContiguousArrays();
+
 	const Bool resourceUpdated = m_dirty;
 	m_dirty = false;
 	const Bool moved = info.m_node->movedThisFrame() || m_firstTimeUpdate;
@@ -122,6 +157,8 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 
 	updated = resourceUpdated || moved || movedLastFrame;
 
+	const Bool hasSkin = m_skinComponent != nullptr && m_skinComponent->isEnabled();
+
 	// Upload mesh LODs and uniforms
 	if(resourceUpdated) [[unlikely]]
 	{
@@ -175,11 +212,29 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 				meshLods[l] = meshLods[l - 1];
 			}
 
-			const PtrSize offset = m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(meshLods)
-								   + SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().getArrayBase(
-									   GpuSceneContiguousArrayType::kMeshLods);
+			PtrSize offset = m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(meshLods)
+							 + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kMeshLods);
 			GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, meshLods.getSizeInBytes(),
 														 &meshLods[0]);
+
+			// Upload the GpuSceneRenderable
+			GpuSceneRenderable gpuRenderable;
+
+			gpuRenderable.m_worldTransformsOffset =
+				U32(m_gpuSceneTransformsIndex * sizeof(Mat3x4) * 2
+					+ gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kTransformPairs));
+			gpuRenderable.m_uniformsOffset = m_patchInfos[i].m_gpuSceneUniformsOffset;
+
+			gpuRenderable.m_geometryOffset =
+				U32(m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(GpuSceneMeshLod) * kMaxLodCount
+					+ gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kMeshLods));
+
+			gpuRenderable.m_boneTransformsOffset = (hasSkin) ? m_skinComponent->getBoneTransformsGpuSceneOffset() : 0;
+
+			offset = m_patchInfos[i].m_gpuSceneRenderableIndex * sizeof(GpuSceneRenderable)
+					 + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kRenderablesGBuffer);
+			GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuRenderable),
+														 &gpuRenderable);
 		}
 
 		// Upload the uniforms
@@ -199,6 +254,20 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		ANKI_ASSERT(count * 4 == m_gpuSceneUniforms.m_size);
 		GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, m_gpuSceneUniforms.m_offset,
 													 m_gpuSceneUniforms.m_size, &allUniforms[0]);
+
+		// Refresh the render state buckets
+		for(U32 i = 0; i < modelPatchCount; ++i)
+		{
+			for(RenderingTechnique t : EnumIterable<RenderingTechnique>())
+			{
+				for(U32 velocity = 0; velocity < 1; ++velocity)
+				{
+					RenderStateBucketContainer& buckets = SceneGraph::getSingleton().getRenderStateBuckets();
+
+					buckets.removeUser(t, m_patchInfos[i].m_renderStateBucketIndices[t][velocity]);
+				}
+			}
+		}
 	}
 
 	// Upload transforms
@@ -231,6 +300,24 @@ Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		const Aabb aabbWorld = aabbLocal.getTransformed(info.m_node->getWorldTransform());
 
 		m_spatial.setBoundingShape(aabbWorld);
+
+		// Upload the GpuSceneRenderableBoundingVolume to the GPU scene
+		const U32 modelPatchCount = m_model->getModelPatches().getSize();
+		for(U32 i = 0; i < modelPatchCount; ++i)
+		{
+			GpuSceneRenderableBoundingVolume gpuVolume;
+			gpuVolume.m_aabbMin = aabbWorld.getMin().xyz();
+			gpuVolume.m_aabbMax = aabbWorld.getMax().xyz();
+			gpuVolume.m_renderableOffset = m_patchInfos[i].m_gpuSceneRenderableIndex * sizeof(GpuSceneRenderable)
+										   + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kRenderablesGBuffer);
+			gpuVolume.m_renderStateBucket = 0; // TODO
+
+			const PtrSize offset =
+				U32(m_patchInfos[i].m_gpuSceneRenderableBoundingVolumeIndex * sizeof(GpuSceneRenderableBoundingVolume)
+					+ gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kRenderableBoundingVolumesGBuffer));
+
+			GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuVolume), &gpuVolume);
+		}
 	}
 
 	const Bool spatialUpdated = m_spatial.update(SceneGraph::getSingleton().getOctree());

+ 4 - 0
AnKi/Scene/Components/ModelComponent.h

@@ -6,6 +6,7 @@
 #pragma once
 
 #include <AnKi/Scene/Components/SceneComponent.h>
+#include <AnKi/Scene/RenderStateBucket.h>
 #include <AnKi/Scene/Spatial.h>
 #include <AnKi/Resource/Forward.h>
 #include <AnKi/Util/WeakArray.h>
@@ -55,6 +56,9 @@ private:
 	public:
 		U32 m_gpuSceneUniformsOffset = kMaxU32;
 		U32 m_gpuSceneMeshLodsIndex = kMaxU32;
+		U32 m_gpuSceneRenderableIndex = kMaxU32;
+		U32 m_gpuSceneRenderableBoundingVolumeIndex = kMaxU32;
+		Array2d<RenderStateBucketIndex, U32(RenderingTechnique::kCount), 2> m_renderStateBucketIndices;
 		RenderingTechniqueBit m_techniques;
 	};
 

+ 3 - 1
AnKi/Scene/ConfigVars.defs.h

@@ -30,7 +30,7 @@ ANKI_CONFIG_VAR_F32(SceneRayTracingExtendedFrustumDistance, 100.0f, 10.0f, 10000
 ANKI_CONFIG_VAR_U32(SceneReflectionProbeResolution, 128, 8, 2048, "The resolution of the reflection probe's reflection")
 
 // GPU scene
-ANKI_CONFIG_VAR_U32(SceneMinGpuSceneTransforms, 8 * 1024, 8, 100 * 1024,
+ANKI_CONFIG_VAR_U32(SceneMinGpuSceneTransforms, 2 * 10 * 1024, 8, 100 * 1024,
 					"The min number of transforms stored in the GPU scene")
 ANKI_CONFIG_VAR_U32(SceneMinGpuSceneMeshes, 8 * 1024, 8, 100 * 1024, "The min number of meshes stored in the GPU scene")
 ANKI_CONFIG_VAR_U32(SceneMinGpuSceneParticleEmitters, 1 * 1024, 8, 100 * 1024,
@@ -43,3 +43,5 @@ ANKI_CONFIG_VAR_U32(SceneMinGpuSceneGlobalIlluminationProbes, 128, 8, 100 * 1024
 ANKI_CONFIG_VAR_U32(SceneMinGpuSceneDecals, 2 * 1024, 8, 100 * 1024, "The min number of decals stored in the GPU scene")
 ANKI_CONFIG_VAR_U32(SceneMinGpuSceneFogDensityVolumes, 512, 8, 100 * 1024,
 					"The min number fog density volumes stored in the GPU scene")
+ANKI_CONFIG_VAR_U32(SceneMinGpuSceneRenderables, 10 * 1024, 8, 100 * 1024,
+					"The min number of renderables stored in the GPU scene")

+ 3 - 1
AnKi/Scene/ContiguousArrayAllocator.cpp

@@ -108,7 +108,9 @@ void AllGpuSceneContiguousArrays::init()
 		cfg.getSceneMinGpuSceneReflectionProbes(),
 		cfg.getSceneMinGpuSceneGlobalIlluminationProbes(),
 		cfg.getSceneMinGpuSceneDecals(),
-		cfg.getSceneMinGpuSceneFogDensityVolumes()};
+		cfg.getSceneMinGpuSceneFogDensityVolumes(),
+		cfg.getSceneMinGpuSceneRenderables(),
+		cfg.getSceneMinGpuSceneRenderables()};
 
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	{

+ 6 - 2
AnKi/Scene/ContiguousArrayAllocator.h

@@ -24,6 +24,8 @@ enum class GpuSceneContiguousArrayType : U8
 	kGlobalIlluminationProbes,
 	kDecals,
 	kFogDensityVolumes,
+	kRenderablesGBuffer,
+	kRenderableBoundingVolumesGBuffer,
 
 	kCount,
 	kFirst = 0
@@ -140,7 +142,7 @@ private:
 	U8 m_frame = 0;
 
 	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentCount = {
-		2, kMaxLodCount, 1, 1, 1, 1, 1, 1, 1};
+		2, kMaxLodCount, 1, 1, 1, 1, 1, 1, 1, 1, 1};
 	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentSize = {
 		sizeof(Mat3x4),
 		sizeof(GpuSceneMeshLod),
@@ -150,7 +152,9 @@ private:
 		sizeof(GpuSceneReflectionProbe),
 		sizeof(GpuSceneGlobalIlluminationProbe),
 		sizeof(GpuSceneDecal),
-		sizeof(GpuSceneFogDensityVolume)};
+		sizeof(GpuSceneFogDensityVolume),
+		sizeof(GpuSceneRenderable),
+		sizeof(GpuSceneRenderableBoundingVolume)};
 };
 /// @}
 

+ 30 - 13
AnKi/Scene/RenderStateBucket.cpp

@@ -18,7 +18,7 @@ RenderStateBucketContainer::~RenderStateBucketContainer()
 	}
 }
 
-U32 RenderStateBucketContainer::addUser(const RenderStateInfo& state, RenderingTechnique technique)
+RenderStateBucketIndex RenderStateBucketContainer::addUser(const RenderStateInfo& state, RenderingTechnique technique)
 {
 	// Compute state gash
 	Array<U64, 3> toHash;
@@ -29,6 +29,11 @@ U32 RenderStateBucketContainer::addUser(const RenderStateInfo& state, RenderingT
 
 	SceneDynamicArray<ExtendedBucket>& buckets = m_buckets[technique];
 
+	RenderStateBucketIndex out;
+#if ANKI_ENABLE_ASSERTIONS
+	out.m_technique = technique;
+#endif
+
 	LockGuard lock(m_mtx);
 
 	// Search bucket
@@ -48,7 +53,8 @@ U32 RenderStateBucketContainer::addUser(const RenderStateInfo& state, RenderingT
 				ANKI_ASSERT(buckets[i].m_program.isCreated());
 			}
 
-			return i;
+			out.m_index = i;
+			return out;
 		}
 	}
 
@@ -60,25 +66,36 @@ U32 RenderStateBucketContainer::addUser(const RenderStateInfo& state, RenderingT
 	newBucket.m_program = state.m_program;
 	newBucket.m_userCount = 1;
 
-	return buckets.getSize() - 1;
+	out.m_index = buckets.getSize() - 1;
+	return out;
 }
 
-void RenderStateBucketContainer::removeUser(U32 bucketIndex, RenderingTechnique technique)
+void RenderStateBucketContainer::removeUser(RenderingTechnique technique, RenderStateBucketIndex& bucketIndex)
 {
-	LockGuard lock(m_mtx);
+	if(bucketIndex.m_index == kMaxU32)
+	{
+		return;
+	}
+
+	{
+		LockGuard lock(m_mtx);
 
-	ANKI_ASSERT(bucketIndex < m_buckets[technique].getSize());
+		ANKI_ASSERT(bucketIndex.m_index < m_buckets[technique].getSize());
+		ANKI_ASSERT(bucketIndex.m_technique == technique);
 
-	ExtendedBucket& bucket = m_buckets[technique][bucketIndex];
-	ANKI_ASSERT(bucket.m_userCount > 0 && bucket.m_program.isCreated());
+		ExtendedBucket& bucket = m_buckets[technique][bucketIndex.m_index];
+		ANKI_ASSERT(bucket.m_userCount > 0 && bucket.m_program.isCreated());
 
-	--bucket.m_userCount;
+		--bucket.m_userCount;
 
-	if(bucket.m_userCount == 0)
-	{
-		// No more users, make sure you release any references
-		bucket.m_program.reset(nullptr);
+		if(bucket.m_userCount == 0)
+		{
+			// No more users, make sure you release any references
+			bucket.m_program.reset(nullptr);
+		}
 	}
+
+	bucketIndex = {};
 }
 
 } // end namespace anki

+ 20 - 2
AnKi/Scene/RenderStateBucket.h

@@ -22,6 +22,24 @@ public:
 	Bool m_indexedDrawcall = true;
 };
 
+class RenderStateBucketIndex
+{
+	friend class RenderStateBucketContainer;
+
+public:
+	U32 get() const
+	{
+		ANKI_ASSERT(m_index != kMaxU32);
+		return m_index;
+	}
+
+private:
+	U32 m_index = kMaxU32;
+#if ANKI_ENABLE_ASSERTIONS
+	RenderingTechnique m_technique = RenderingTechnique::kCount;
+#endif
+};
+
 /// Holds an array of all render state buckets.
 class RenderStateBucketContainer
 {
@@ -29,10 +47,10 @@ public:
 	~RenderStateBucketContainer();
 
 	/// Add a new user for a specific render state and rendering technique.
-	U32 addUser(const RenderStateInfo& state, RenderingTechnique technique);
+	RenderStateBucketIndex addUser(const RenderStateInfo& state, RenderingTechnique technique);
 
 	/// Remove the user.
-	void removeUser(U32 bucketIndex, RenderingTechnique technique);
+	void removeUser(RenderingTechnique technique, RenderStateBucketIndex& bucketIndex);
 
 	template<typename TFunc>
 	void interateBuckets(RenderingTechnique technique, TFunc func) const

+ 8 - 0
AnKi/Scene/SceneGraph.h

@@ -8,6 +8,7 @@
 #include <AnKi/Scene/Common.h>
 #include <AnKi/Scene/SceneNode.h>
 #include <AnKi/Scene/ContiguousArrayAllocator.h>
+#include <AnKi/Scene/RenderStateBucket.h>
 #include <AnKi/Math.h>
 #include <AnKi/Util/HashMap.h>
 #include <AnKi/Scene/Events/EventManager.h>
@@ -158,6 +159,11 @@ public:
 		return m_gpuSceneAllocators;
 	}
 
+	ANKI_INTERNAL RenderStateBucketContainer& getRenderStateBuckets()
+	{
+		return m_renderStateBuckets;
+	}
+
 private:
 	class UpdateSceneNodesCtx;
 
@@ -195,6 +201,8 @@ private:
 
 	AllGpuSceneContiguousArrays m_gpuSceneAllocators;
 
+	RenderStateBucketContainer m_renderStateBuckets;
+
 	SceneGraph();
 
 	~SceneGraph();

+ 11 - 1
AnKi/Shaders/Include/GpuSceneTypes.h

@@ -14,13 +14,23 @@ struct GpuSceneRenderable
 {
 	U32 m_worldTransformsOffset; ///< First is the crnt transform and the 2nd the previous
 	U32 m_uniformsOffset;
-	U32 m_geometryOffset;
+	U32 m_geometryOffset; ///< Points to a GpuSceneMeshLod or a GpuSceneParticleEmitter
 	U32 m_boneTransformsOffset;
 };
 static_assert(sizeof(GpuSceneRenderable) == sizeof(Vec4) * 1);
 
 typedef UVec4 GpuSceneRenderablePacked;
 
+/// Used in visibility testing.
+struct GpuSceneRenderableBoundingVolume
+{
+	Vec3 m_aabbMin;
+	U32 m_renderableOffset; ///< Points to a GpuSceneRenderable
+
+	Vec3 m_aabbMax;
+	U32 m_renderStateBucket;
+};
+
 struct GpuSceneMeshLod
 {
 	U32 m_vertexOffsets[(U32)VertexStreamId::kMeshRelatedCount];