Browse Source

Add array index to lights and probes

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
fe68396bbd

+ 5 - 5
AnKi/Renderer/PrimaryNonRenderableVisibility.cpp

@@ -55,18 +55,18 @@ void PrimaryNonRenderableVisibility::populateRenderGraph(RenderingContext& ctx)
 		const GpuSceneNonRenderableObjectTypeWithFeedback feedbackType = toGpuSceneNonRenderableObjectTypeWithFeedback(type);
 		const GpuSceneNonRenderableObjectTypeWithFeedback feedbackType = toGpuSceneNonRenderableObjectTypeWithFeedback(type);
 		if(feedbackType != GpuSceneNonRenderableObjectTypeWithFeedback::kCount)
 		if(feedbackType != GpuSceneNonRenderableObjectTypeWithFeedback::kCount)
 		{
 		{
-			// Read feedback UUIDs from the GPU
+			// Read feedback from the GPU
 			DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> readbackData(ctx.m_tempPool);
 			DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> readbackData(ctx.m_tempPool);
 			getRenderer().getReadbackManager().readMostRecentData(m_readbacks[feedbackType], readbackData);
 			getRenderer().getReadbackManager().readMostRecentData(m_readbacks[feedbackType], readbackData);
 
 
 			if(readbackData.getSize())
 			if(readbackData.getSize())
 			{
 			{
 				ANKI_ASSERT(readbackData.getSize() > 1);
 				ANKI_ASSERT(readbackData.getSize() > 1);
-				const U32 uuidCount = readbackData[0];
+				const U32 pairCount = readbackData[0];
 
 
-				if(uuidCount)
+				if(pairCount)
 				{
 				{
-					m_runCtx.m_uuids[feedbackType] = WeakArray<U32>(&readbackData[1], readbackData[0]);
+					m_runCtx.m_uuidArrayIndexPairs[feedbackType] = WeakArray<UVec2>(reinterpret_cast<UVec2*>(&readbackData[1]), pairCount);
 
 
 					// Transfer ownership
 					// Transfer ownership
 					WeakArray<U32> dummy;
 					WeakArray<U32> dummy;
@@ -75,7 +75,7 @@ void PrimaryNonRenderableVisibility::populateRenderGraph(RenderingContext& ctx)
 			}
 			}
 
 
 			// Allocate feedback buffer for this frame
 			// Allocate feedback buffer for this frame
-			in.m_cpuFeedbackBuffer.m_range = (objCount + 1) * sizeof(U32);
+			in.m_cpuFeedbackBuffer.m_range = (objCount * 2 + 1) * sizeof(U32);
 			getRenderer().getReadbackManager().allocateData(m_readbacks[feedbackType], in.m_cpuFeedbackBuffer.m_range,
 			getRenderer().getReadbackManager().allocateData(m_readbacks[feedbackType], in.m_cpuFeedbackBuffer.m_range,
 															in.m_cpuFeedbackBuffer.m_buffer, in.m_cpuFeedbackBuffer.m_offset);
 															in.m_cpuFeedbackBuffer.m_buffer, in.m_cpuFeedbackBuffer.m_offset);
 		}
 		}

+ 3 - 1
AnKi/Renderer/PrimaryNonRenderableVisibility.h

@@ -33,7 +33,9 @@ private:
 	{
 	{
 	public:
 	public:
 		Array<BufferHandle, U32(GpuSceneNonRenderableObjectType::kCount)> m_visOutBufferHandle;
 		Array<BufferHandle, U32(GpuSceneNonRenderableObjectType::kCount)> m_visOutBufferHandle;
-		Array<WeakArray<U32>, U32(GpuSceneNonRenderableObjectTypeWithFeedback::kCount)> m_uuids;
+
+		/// Feedback from the GPU. It's an array of object UUID and array index.
+		Array<WeakArray<UVec2>, U32(GpuSceneNonRenderableObjectTypeWithFeedback::kCount)> m_uuidArrayIndexPairs;
 	} m_runCtx;
 	} m_runCtx;
 };
 };
 /// @}
 /// @}

+ 1 - 1
AnKi/Renderer/Utils/GpuVisibility.cpp

@@ -271,7 +271,7 @@ void GpuVisibilityNonRenderables::populateRenderGraph(GpuVisibilityNonRenderable
 
 
 	if(in.m_cpuFeedbackBuffer.m_buffer)
 	if(in.m_cpuFeedbackBuffer.m_buffer)
 	{
 	{
-		ANKI_ASSERT(in.m_cpuFeedbackBuffer.m_range == sizeof(U32) * (objCount + 1));
+		ANKI_ASSERT(in.m_cpuFeedbackBuffer.m_range == sizeof(U32) * (objCount * 2 + 1));
 	}
 	}
 
 
 	const Bool firstRunInFrame = m_lastFrameIdx != getRenderer().getFrameCount();
 	const Bool firstRunInFrame = m_lastFrameIdx != getRenderer().getFrameCount();

+ 1 - 0
AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp

@@ -118,6 +118,7 @@ Error GlobalIlluminationProbeComponent::update(SceneComponentUpdateInfo& info, B
 		gpuProbe.m_halfTexelSizeU = 1.0f / (F32(m_cellCounts.y()) * 6.0f) / 2.0f;
 		gpuProbe.m_halfTexelSizeU = 1.0f / (F32(m_cellCounts.y()) * 6.0f) / 2.0f;
 		gpuProbe.m_fadeDistance = m_fadeDistance;
 		gpuProbe.m_fadeDistance = m_fadeDistance;
 		gpuProbe.m_uuid = m_uuid;
 		gpuProbe.m_uuid = m_uuid;
+		gpuProbe.m_arrayIndex = getArrayIndex();
 		m_gpuSceneProbe.uploadToGpuScene(gpuProbe);
 		m_gpuSceneProbe.uploadToGpuScene(gpuProbe);
 	}
 	}
 
 

+ 7 - 4
AnKi/Scene/Components/LightComponent.cpp

@@ -138,8 +138,10 @@ Error LightComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		gpuLight.m_radius = m_point.m_radius;
 		gpuLight.m_radius = m_point.m_radius;
 		gpuLight.m_diffuseColor = m_diffColor.xyz();
 		gpuLight.m_diffuseColor = m_diffColor.xyz();
 		gpuLight.m_squareRadiusOverOne = 1.0f / (m_point.m_radius * m_point.m_radius);
 		gpuLight.m_squareRadiusOverOne = 1.0f / (m_point.m_radius * m_point.m_radius);
-		gpuLight.m_shadow = m_shadow;
-		gpuLight.m_uuid = (m_shadow) ? m_uuid : 0;
+		gpuLight.m_flags = GpuSceneLightFlag::kPointLight;
+		gpuLight.m_flags |= (m_shadow) ? GpuSceneLightFlag::kShadow : GpuSceneLightFlag::kNone;
+		gpuLight.m_arrayIndex = getArrayIndex();
+		gpuLight.m_uuid = m_uuid;
 		if(!m_gpuSceneLight.isValid())
 		if(!m_gpuSceneLight.isValid())
 		{
 		{
 			m_gpuSceneLight.allocate();
 			m_gpuSceneLight.allocate();
@@ -214,10 +216,11 @@ Error LightComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		gpuLight.m_radius = m_spot.m_distance;
 		gpuLight.m_radius = m_spot.m_distance;
 		gpuLight.m_direction = -m_worldTransform.getRotation().getZAxis();
 		gpuLight.m_direction = -m_worldTransform.getRotation().getZAxis();
 		gpuLight.m_squareRadiusOverOne = 1.0f / (m_spot.m_distance * m_spot.m_distance);
 		gpuLight.m_squareRadiusOverOne = 1.0f / (m_spot.m_distance * m_spot.m_distance);
-		gpuLight.m_shadow = m_shadow;
+		gpuLight.m_flags = GpuSceneLightFlag::kSpotLight;
+		gpuLight.m_flags |= (m_shadow) ? GpuSceneLightFlag::kShadow : GpuSceneLightFlag::kNone;
 		gpuLight.m_outerCos = cos(m_spot.m_outerAngle / 2.0f);
 		gpuLight.m_outerCos = cos(m_spot.m_outerAngle / 2.0f);
 		gpuLight.m_innerCos = cos(m_spot.m_innerAngle / 2.0f);
 		gpuLight.m_innerCos = cos(m_spot.m_innerAngle / 2.0f);
-		gpuLight.m_uuid = (m_shadow) ? m_uuid : 0;
+		gpuLight.m_uuid = m_uuid;
 		if(!m_gpuSceneLight.isValid())
 		if(!m_gpuSceneLight.isValid())
 		{
 		{
 			m_gpuSceneLight.allocate();
 			m_gpuSceneLight.allocate();

+ 1 - 0
AnKi/Scene/Components/ReflectionProbeComponent.cpp

@@ -102,6 +102,7 @@ Error ReflectionProbeComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 		gpuProbe.m_aabbMin = aabbWorld.getMin().xyz();
 		gpuProbe.m_aabbMin = aabbWorld.getMin().xyz();
 		gpuProbe.m_aabbMax = aabbWorld.getMax().xyz();
 		gpuProbe.m_aabbMax = aabbWorld.getMax().xyz();
 		gpuProbe.m_uuid = m_uuid;
 		gpuProbe.m_uuid = m_uuid;
+		gpuProbe.m_arrayIndex = getArrayIndex();
 		m_gpuSceneProbe.uploadToGpuScene(gpuProbe);
 		m_gpuSceneProbe.uploadToGpuScene(gpuProbe);
 	}
 	}
 
 

+ 3 - 2
AnKi/Shaders/GpuVisibilityNonRenderables.ankiprog

@@ -39,7 +39,7 @@ constexpr U32 kFeedbackCounterIdx = 2;
 [[vk::binding(2)]] globallycoherent RWStructuredBuffer<U32> g_counterBuffer; // 2 counters per dispatch with an optional 3rd for feedback
 [[vk::binding(2)]] globallycoherent RWStructuredBuffer<U32> g_counterBuffer; // 2 counters per dispatch with an optional 3rd for feedback
 
 
 #if CPU_FEEDBACK
 #if CPU_FEEDBACK
-// 1st element is a count. What follows is an array of UUIDs.
+// 1st element is a count. What follows is an array pairs of UUIDs and array index.
 [[vk::binding(3)]] RWStructuredBuffer<U32> g_cpuFeedbackBuffer;
 [[vk::binding(3)]] RWStructuredBuffer<U32> g_cpuFeedbackBuffer;
 #endif
 #endif
 
 
@@ -116,7 +116,8 @@ Vec4 getSphere(GpuSceneGlobalIlluminationProbe l)
 		U32 idx;
 		U32 idx;
 		InterlockedAdd(g_counterBuffer[kFeedbackCounterIdx], 1, idx);
 		InterlockedAdd(g_counterBuffer[kFeedbackCounterIdx], 1, idx);
 
 
-		g_cpuFeedbackBuffer[idx + 1] = g_objects[svDispatchThreadId].m_uuid;
+		g_cpuFeedbackBuffer[idx * 2 + 1] = g_objects[svDispatchThreadId].m_uuid;
+		g_cpuFeedbackBuffer[idx * 2 + 2] = g_objects[svDispatchThreadId].m_arrayIndex;
 	}
 	}
 #endif
 #endif
 
 

+ 13 - 4
AnKi/Shaders/Include/GpuSceneTypes.h

@@ -58,6 +58,15 @@ struct GpuSceneParticleEmitter
 };
 };
 static_assert(sizeof(GpuSceneParticleEmitter) == sizeof(Vec4) * 2);
 static_assert(sizeof(GpuSceneParticleEmitter) == sizeof(Vec4) * 2);
 
 
+enum class GpuSceneLightFlag : U32
+{
+	kNone = 0,
+	kPointLight = 1 << 0,
+	kSpotLight = 1 << 1,
+	kShadow = 1 << 2
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(GpuSceneLightFlag)
+
 /// Point or spot light.
 /// Point or spot light.
 struct GpuSceneLight
 struct GpuSceneLight
 {
 {
@@ -67,8 +76,8 @@ struct GpuSceneLight
 	RVec3 m_diffuseColor;
 	RVec3 m_diffuseColor;
 	RF32 m_squareRadiusOverOne; ///< 1/(radius^2).
 	RF32 m_squareRadiusOverOne; ///< 1/(radius^2).
 
 
-	U32 m_type; ///< 0: point, 1: spot.
-	U32 m_shadow;
+	GpuSceneLightFlag m_flags;
+	U32 m_arrayIndex; ///< Array in the CPU scene.
 	U32 m_uuid;
 	U32 m_uuid;
 	F32 m_innerCos; ///< Only for spot light.
 	F32 m_innerCos; ///< Only for spot light.
 
 
@@ -88,7 +97,7 @@ struct GpuSceneReflectionProbe
 	U32 m_uuid;
 	U32 m_uuid;
 
 
 	Vec3 m_aabbMax ANKI_CPP_CODE(= Vec3(kSomeFarDistance));
 	Vec3 m_aabbMax ANKI_CPP_CODE(= Vec3(kSomeFarDistance));
-	F32 m_padding1;
+	U32 m_arrayIndex; ///< Array in the CPU scene.
 };
 };
 constexpr U32 kSizeof_GpuSceneReflectionProbe = 3u * sizeof(Vec4);
 constexpr U32 kSizeof_GpuSceneReflectionProbe = 3u * sizeof(Vec4);
 static_assert(sizeof(GpuSceneReflectionProbe) == kSizeof_GpuSceneReflectionProbe);
 static_assert(sizeof(GpuSceneReflectionProbe) == kSizeof_GpuSceneReflectionProbe);
@@ -100,7 +109,7 @@ struct GpuSceneGlobalIlluminationProbe
 	U32 m_uuid;
 	U32 m_uuid;
 
 
 	Vec3 m_aabbMax ANKI_CPP_CODE(= Vec3(kSomeFarDistance));
 	Vec3 m_aabbMax ANKI_CPP_CODE(= Vec3(kSomeFarDistance));
-	F32 m_padding1;
+	U32 m_arrayIndex; ///< Array in the CPU scene.
 
 
 	U32 m_volumeTexture; ///< Bindless index of the irradiance volume texture.
 	U32 m_volumeTexture; ///< Bindless index of the irradiance volume texture.
 	F32 m_halfTexelSizeU; ///< (1.0 / textureSize(texArr[textureIndex]).x) / 2.0
 	F32 m_halfTexelSizeU; ///< (1.0 / textureSize(texArr[textureIndex]).x) / 2.0

+ 2 - 2
AnKi/Shaders/PackVisibleClusteredObjects.ankiprog

@@ -68,7 +68,7 @@ struct Uniforms
 	output.m_radius = input.m_radius;
 	output.m_radius = input.m_radius;
 	output.m_diffuseColor = input.m_diffuseColor;
 	output.m_diffuseColor = input.m_diffuseColor;
 	output.m_squareRadiusOverOne = input.m_squareRadiusOverOne;
 	output.m_squareRadiusOverOne = input.m_squareRadiusOverOne;
-	output.m_shadowLayer = (input.m_shadow) ? extra.m_shadowLayer : kMaxU32;
+	output.m_shadowLayer = ((U32)input.m_flags & (U32)GpuSceneLightFlag::kShadow) ? extra.m_shadowLayer : kMaxU32;
 	output.m_shadowAtlasTileScale = extra.m_shadowAtlasTileScale;
 	output.m_shadowAtlasTileScale = extra.m_shadowAtlasTileScale;
 	output.m_shadowAtlasTileOffsets = extra.m_shadowAtlasTileOffsets;
 	output.m_shadowAtlasTileOffsets = extra.m_shadowAtlasTileOffsets;
 
 
@@ -84,7 +84,7 @@ struct Uniforms
 	output.m_radius = input.m_radius;
 	output.m_radius = input.m_radius;
 	output.m_direction = input.m_direction;
 	output.m_direction = input.m_direction;
 	output.m_squareRadiusOverOne = input.m_squareRadiusOverOne;
 	output.m_squareRadiusOverOne = input.m_squareRadiusOverOne;
-	output.m_shadowLayer = (input.m_shadow) ? extra.m_shadowLayer : kMaxU32;
+	output.m_shadowLayer = ((U32)input.m_flags & (U32)GpuSceneLightFlag::kShadow) ? extra.m_shadowLayer : kMaxU32;
 	output.m_outerCos = input.m_outerCos;
 	output.m_outerCos = input.m_outerCos;
 	output.m_innerCos = input.m_innerCos;
 	output.m_innerCos = input.m_innerCos;
 	output.m_textureMatrix = extra.m_textureMatrix;
 	output.m_textureMatrix = extra.m_textureMatrix;

+ 3 - 1
AnKi/Shaders/TraditionalDeferredShading.ankiprog

@@ -109,7 +109,9 @@ RVec3 main(Vec4 svPosition : SV_POSITION) : SV_TARGET0
 
 
 		const F32 att = computeAttenuationFactor(1.0f / (light.m_radius * light.m_radius), frag2Light);
 		const F32 att = computeAttenuationFactor(1.0f / (light.m_radius * light.m_radius), frag2Light);
 		const F32 lambert = nol;
 		const F32 lambert = nol;
-		const F32 spot = (light.m_type == 1) ? computeSpotFactor(l, light.m_outerCos, light.m_innerCos, light.m_direction) : 1.0f;
+		const F32 spot = ((U32)light.m_flags & (U32)GpuSceneLightFlag::kSpotLight)
+							 ? computeSpotFactor(l, light.m_outerCos, light.m_innerCos, light.m_direction)
+							 : 1.0f;
 		const F32 factor = att * spot * max(lambert, gbuffer.m_subsurface);
 		const F32 factor = att * spot * max(lambert, gbuffer.m_subsurface);
 
 
 #if SPECULAR == 1
 #if SPECULAR == 1