فهرست منبع

Optimize calculation of average luminance

Panagiotis Christopoulos Charitos 7 سال پیش
والد
کامیت
9688b10fe8

+ 6 - 6
programs/TonemappingAverageLuminance.ankiprog

@@ -39,9 +39,9 @@ void main()
 	float avgLum = 0.0;
 	float avgLum = 0.0;
 	uint yStart = gl_LocalInvocationID.y * PIXEL_READ_Y;
 	uint yStart = gl_LocalInvocationID.y * PIXEL_READ_Y;
 	uint xStart = gl_LocalInvocationID.x * PIXEL_READ_X;
 	uint xStart = gl_LocalInvocationID.x * PIXEL_READ_X;
-	for(uint y = 0; y < PIXEL_READ_Y; ++y)
+	ANKI_LOOP for(uint y = 0; y < PIXEL_READ_Y; ++y)
 	{
 	{
-		for(uint x = 0; x < PIXEL_READ_X; ++x)
+		ANKI_UNROLL for(uint x = 0; x < PIXEL_READ_X; ++x)
 		{
 		{
 			ivec2 uv = ivec2(xStart, yStart) + ivec2(x, y);
 			ivec2 uv = ivec2(xStart, yStart) + ivec2(x, y);
 			vec3 color = texelFetch(u_tex, uv, 0).rgb;
 			vec3 color = texelFetch(u_tex, uv, 0).rgb;
@@ -60,7 +60,7 @@ void main()
 	barrier();
 	barrier();
 
 
 	// Gather the results into one
 	// Gather the results into one
-	for(uint s = WORKGROUP_SIZE / 2u; s > 0u; s >>= 1u)
+	ANKI_LOOP for(uint s = WORKGROUP_SIZE / 2u; s > 0u; s >>= 1u)
 	{
 	{
 		if(gl_LocalInvocationIndex < s)
 		if(gl_LocalInvocationIndex < s)
 		{
 		{
@@ -72,12 +72,12 @@ void main()
 	}
 	}
 
 
 	// Write the result
 	// Write the result
-	if(gl_LocalInvocationIndex == 0)
+	ANKI_BRANCH if(gl_LocalInvocationIndex == 0)
 	{
 	{
 #if LOG_AVG
 #if LOG_AVG
-		float crntLum = exp(s_avgLum[0] / float(INPUT_TEX_SIZE.x * INPUT_TEX_SIZE.y));
+		float crntLum = exp(s_avgLum[0] * (1.0 / float(INPUT_TEX_SIZE.x * INPUT_TEX_SIZE.y)));
 #else
 #else
-		float crntLum = s_avgLum[0] / float(INPUT_TEX_SIZE.x * INPUT_TEX_SIZE.y);
+		float crntLum = s_avgLum[0] * (1.0 / float(INPUT_TEX_SIZE.x * INPUT_TEX_SIZE.y));
 #endif
 #endif
 
 
 #if 1
 #if 1

+ 2 - 2
src/anki/gr/RenderGraph.cpp

@@ -477,7 +477,7 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 				{
 				{
 					for(const RenderPassDependency& producer : b.m_producers)
 					for(const RenderPassDependency& producer : b.m_producers)
 					{
 					{
-						if(overlappingDependency<true>(producer, consumer))
+						if(producer.m_isTexture && overlappingDependency<true>(producer, consumer))
 						{
 						{
 							return true;
 							return true;
 						}
 						}
@@ -506,7 +506,7 @@ Bool RenderGraph::passADependsOnB(const RenderPassDescriptionBase& a, const Rend
 				{
 				{
 					for(const RenderPassDependency& producer : b.m_producers)
 					for(const RenderPassDependency& producer : b.m_producers)
 					{
 					{
-						if(overlappingDependency<false>(producer, consumer))
+						if(!producer.m_isTexture && overlappingDependency<false>(producer, consumer))
 						{
 						{
 							return true;
 							return true;
 						}
 						}

+ 2 - 1
src/anki/renderer/Renderer.cpp

@@ -262,8 +262,10 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 
 
 	// Import RTs first
 	// Import RTs first
 	m_downscale->importRenderTargets(ctx);
 	m_downscale->importRenderTargets(ctx);
+	m_tonemapping->importRenderTargets(ctx);
 
 
 	// Populate render graph. WARNING Watch the order
 	// Populate render graph. WARNING Watch the order
+	m_tonemapping->populateRenderGraph(ctx);
 	m_shadowMapping->populateRenderGraph(ctx);
 	m_shadowMapping->populateRenderGraph(ctx);
 	m_indirect->populateRenderGraph(ctx);
 	m_indirect->populateRenderGraph(ctx);
 	m_gbuffer->populateRenderGraph(ctx);
 	m_gbuffer->populateRenderGraph(ctx);
@@ -277,7 +279,6 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	m_lightShading->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);
 	m_temporalAA->populateRenderGraph(ctx);
 	m_temporalAA->populateRenderGraph(ctx);
 	m_downscale->populateRenderGraph(ctx);
 	m_downscale->populateRenderGraph(ctx);
-	m_tonemapping->populateRenderGraph(ctx);
 	m_bloom->populateRenderGraph(ctx);
 	m_bloom->populateRenderGraph(ctx);
 
 
 	if(m_dbg->getEnabled())
 	if(m_dbg->getEnabled())

+ 8 - 3
src/anki/renderer/Tonemapping.cpp

@@ -64,13 +64,18 @@ Error Tonemapping::initInternal(const ConfigSet& initializer)
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
+void Tonemapping::importRenderTargets(RenderingContext& ctx)
+{
+	// Computation of the AVG luminance will run first in the frame and it will use the m_luminanceBuff as storage
+	// read/write. To skip the barrier import it as read/write as well.
+	m_runCtx.m_buffHandle =
+		ctx.m_renderGraphDescr.importBuffer("Avg lum", m_luminanceBuff, BufferUsageBit::STORAGE_COMPUTE_READ_WRITE);
+}
+
 void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 {
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
-	// Create buffer
-	m_runCtx.m_buffHandle = rgraph.importBuffer("Avg lum", m_luminanceBuff, BufferUsageBit::NONE);
-
 	// Create the pass
 	// Create the pass
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Avg lum");
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Avg lum");
 
 

+ 2 - 0
src/anki/renderer/Tonemapping.h

@@ -24,6 +24,8 @@ anki_internal:
 
 
 	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
 	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
 
 
+	void importRenderTargets(RenderingContext& ctx);
+
 	/// Populate the rendergraph.
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);