2
0
Эх сурвалжийг харах

Simple cluster merging optimization

Panagiotis Christopoulos Charitos 10 жил өмнө
parent
commit
56c0f3d7df

+ 18 - 2
shaders/IsLp.frag.glsl

@@ -368,10 +368,26 @@ void main()
 #endif
 
 #if 0
-	if(pointLightsCount != 0)
+	if(pointLightsCount == 0)
 	{
-		out_color = vec3(1.0);
 	}
+	else if(pointLightsCount == 1)
+	{
+		out_color += vec3(0.0, 1.0, 0.0);
+	}
+	else if(pointLightsCount == 2)
+	{
+		out_color += vec3(0.0, 0.0, 1.0);
+	}
+	else if(pointLightsCount == 3)
+	{
+		out_color += vec3(1.0, 0.0, 1.0);
+	}
+	else
+	{
+		out_color += vec3(1.0, 0.0, 0.0);
+	}
+
 
 	/*uint x = in_instanceId % 60;
 	uint y = in_instanceId / 60;

+ 66 - 1
src/renderer/Is.cpp

@@ -70,6 +70,55 @@ public:
 
 	Array<Lid, MAX_TYPED_LIGHTS_PER_CLUSTER> m_pointIds;
 	Array<Lid, MAX_TYPED_LIGHTS_PER_CLUSTER> m_spotIds;
+
+	void sortLightIds()
+	{
+		const U pointCount = m_pointCount.load();
+		const U spotCount = m_spotCount.load();
+
+		if(pointCount > 1)
+		{
+			std::sort(&m_pointIds[0], &m_pointIds[0] + pointCount);
+		}
+
+		if(spotCount > 1)
+		{
+			std::sort(&m_spotIds[0], &m_spotIds[0] + spotCount);
+		}
+	}
+
+	Bool operator==(const ClusterData& b) const
+	{
+		const U pointCount = m_pointCount.load();
+		const U spotCount = m_spotCount.load();
+		const U pointCount2 = b.m_pointCount.load();
+		const U spotCount2 = b.m_spotCount.load();
+
+		if(pointCount != pointCount2 || spotCount != spotCount2)
+		{
+			return false;
+		}
+
+		if(pointCount > 0)
+		{
+			if(memcmp(&m_pointIds[0], &b.m_pointIds[0],
+				sizeof(Lid) * pointCount) != 0)
+			{
+				return false;
+			}
+		}
+
+		if(spotCount > 0)
+		{
+			if(memcmp(&m_spotIds[0], &b.m_spotIds[0],
+				sizeof(Lid) * spotCount) != 0)
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
 };
 
 /// Common data for all tasks.
@@ -520,7 +569,7 @@ void Is::binLights(U32 threadId, PtrSize threadsCount, TaskCommonData& task)
 	// Run per tile
 	for(U i = start; i < end; ++i)
 	{
-		const auto& cluster = task.m_tempClusters[i];
+		auto& cluster = task.m_tempClusters[i];
 
 		const U countP = cluster.m_pointCount.load();
 		const U countS = cluster.m_spotCount.load();
@@ -529,11 +578,27 @@ void Is::binLights(U32 threadId, PtrSize threadsCount, TaskCommonData& task)
 		auto& c = task.m_clusters[i];
 		c.m_combo = 0;
 
+		// Early exit
 		if(ANKI_UNLIKELY(count == 0))
 		{
 			continue;
 		}
 
+		// Check if the previous cluster contains the same lights as this one
+		// and if yes then merge them. This will avoid allocating new IDs (and
+		// thrashing GPU caches).
+		cluster.sortLightIds();
+		if(i != start)
+		{
+			const auto& clusterB = task.m_tempClusters[i - 1];
+
+			if(cluster == clusterB)
+			{
+				c.m_combo = task.m_clusters[i - 1].m_combo;
+				continue;
+			}
+		}
+
 		const U offset = task.m_lightIdsCount.fetchAdd(count);
 
 		if(offset + count <= m_maxLightIds)

+ 1 - 1
testapp/Main.cpp

@@ -43,7 +43,7 @@ App* app;
 ModelNode* horse;
 PerspectiveCamera* cam;
 
-#define PLAYER 1
+#define PLAYER 0
 #define MOUSE 1
 
 Bool profile = false;