Browse Source

Fixing a bug that prevented lens flare from showing. Vulkanize some parts of the renderer

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
69e45d613a

+ 15 - 2
include/anki/renderer/Fs.h

@@ -26,8 +26,6 @@ anki_internal:
 
 
 	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
 
 
-	void prepareBuildCommandBuffers(RenderingContext& ctx);
-
 	ANKI_USE_RESULT Error buildCommandBuffers(
 	ANKI_USE_RESULT Error buildCommandBuffers(
 		RenderingContext& ctx, U threadId, U threadCount) const;
 		RenderingContext& ctx, U threadId, U threadCount) const;
 
 
@@ -42,6 +40,21 @@ anki_internal:
 		return m_rt;
 		return m_rt;
 	}
 	}
 
 
+	U getWidth() const
+	{
+		return m_width;
+	}
+
+	U getHeight() const
+	{
+		return m_height;
+	}
+
+	FramebufferPtr getFramebuffer() const
+	{
+		return m_fb;
+	}
+
 private:
 private:
 	U m_width;
 	U m_width;
 	U m_height;
 	U m_height;

+ 1 - 1
include/anki/renderer/Lf.h

@@ -31,7 +31,7 @@ anki_internal:
 
 
 	void runOcclusionTests(RenderingContext& ctx, CommandBufferPtr cmdb);
 	void runOcclusionTests(RenderingContext& ctx, CommandBufferPtr cmdb);
 
 
-	void run(RenderingContext& ctx);
+	void run(RenderingContext& ctx, CommandBufferPtr cmdb);
 
 
 private:
 private:
 	// Occlusion query
 	// Occlusion query

+ 0 - 4
include/anki/renderer/Ms.h

@@ -27,10 +27,6 @@ anki_internal:
 
 
 	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
 
 
-	void prepareBuildCommandBuffers(RenderingContext& ctx)
-	{
-	}
-
 	ANKI_USE_RESULT Error buildCommandBuffers(
 	ANKI_USE_RESULT Error buildCommandBuffers(
 		RenderingContext& ctx, U threadId, U threadCount) const;
 		RenderingContext& ctx, U threadId, U threadCount) const;
 
 

+ 4 - 0
include/anki/renderer/Renderer.h

@@ -43,6 +43,7 @@ public:
 	{
 	{
 	public:
 	public:
 		Array<CommandBufferPtr, ThreadPool::MAX_THREADS> m_commandBuffers;
 		Array<CommandBufferPtr, ThreadPool::MAX_THREADS> m_commandBuffers;
+		U32 m_lastThreadWithWork = 0;
 	} m_ms;
 	} m_ms;
 	/// @}
 	/// @}
 
 
@@ -94,6 +95,7 @@ public:
 	{
 	{
 	public:
 	public:
 		Array<CommandBufferPtr, ThreadPool::MAX_THREADS> m_commandBuffers;
 		Array<CommandBufferPtr, ThreadPool::MAX_THREADS> m_commandBuffers;
+		U32 m_lastThreadWithWork = 0;
 	} m_fs;
 	} m_fs;
 	/// @}
 	/// @}
 
 
@@ -407,6 +409,8 @@ private:
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 
 
 	ANKI_USE_RESULT Error buildCommandBuffers(RenderingContext& ctx);
 	ANKI_USE_RESULT Error buildCommandBuffers(RenderingContext& ctx);
+	ANKI_USE_RESULT Error buildCommandBuffersInternal(
+		RenderingContext& ctx, U32 threadId, PtrSize threadCount);
 };
 };
 /// @}
 /// @}
 
 

+ 1 - 1
include/anki/renderer/Volumetric.h

@@ -33,7 +33,7 @@ anki_internal:
 
 
 	ANKI_USE_RESULT Error init(const ConfigSet& config);
 	ANKI_USE_RESULT Error init(const ConfigSet& config);
 
 
-	void run(RenderingContext& ctx);
+	void run(RenderingContext& ctx, CommandBufferPtr cmdb);
 
 
 private:
 private:
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_frag;

+ 2 - 1
include/anki/scene/LensFlareComponent.h

@@ -83,7 +83,8 @@ public:
 	/// @param[out] q The returned query.
 	/// @param[out] q The returned query.
 	/// @param[out] queryInvalid It's true if the query has an old result that
 	/// @param[out] queryInvalid It's true if the query has an old result that
 	///             cannot be used.
 	///             cannot be used.
-	void getOcclusionQueryToCheck(OcclusionQueryPtr& q, Bool& queryInvalid);
+	void getOcclusionQueryToCheck(
+		OcclusionQueryPtr& q, Bool& queryInvalid) const;
 
 
 	/// @name SceneComponent virtuals
 	/// @name SceneComponent virtuals
 	/// @{
 	/// @{

+ 7 - 7
src/gr/gl/ResourceGroupImpl.cpp

@@ -380,9 +380,10 @@ void ResourceGroupImpl::bind(
 		}
 		}
 		else
 		else
 		{
 		{
-			// Copy the offsets
 			Array<GLintptr, MAX_VERTEX_ATTRIBUTES> offsets = m_vertBuffOffsets;
 			Array<GLintptr, MAX_VERTEX_ATTRIBUTES> offsets = m_vertBuffOffsets;
 			Array<GLuint, MAX_VERTEX_ATTRIBUTES> names = m_vertBuffNames;
 			Array<GLuint, MAX_VERTEX_ATTRIBUTES> names = m_vertBuffNames;
+			const TransientMemoryManager& transManager =
+				getManager().getImplementation().getTransientMemoryManager();
 
 
 			for(U i = 0; i < MAX_VERTEX_ATTRIBUTES; ++i)
 			for(U i = 0; i < MAX_VERTEX_ATTRIBUTES; ++i)
 			{
 			{
@@ -391,10 +392,8 @@ void ResourceGroupImpl::bind(
 					// It's dynamic
 					// It's dynamic
 					ANKI_ASSERT(transientInfo.m_vertexBuffers[i].m_range != 0);
 					ANKI_ASSERT(transientInfo.m_vertexBuffers[i].m_range != 0);
 					offsets[i] = transientInfo.m_vertexBuffers[i].m_offset;
 					offsets[i] = transientInfo.m_vertexBuffers[i].m_offset;
-					names[i] = getManager()
-								   .getImplementation()
-								   .getTransientMemoryManager()
-								   .getGlName(transientInfo.m_vertexBuffers[i]);
+					names[i] = transManager.getGlName(
+						transientInfo.m_vertexBuffers[i]);
 				}
 				}
 				else
 				else
 				{
 				{
@@ -407,8 +406,9 @@ void ResourceGroupImpl::bind(
 				&offsets[0],
 				&offsets[0],
 				sizeof(offsets[0]) * m_vertBindingsCount);
 				sizeof(offsets[0]) * m_vertBindingsCount);
 
 
-			memcpy(
-				&names[0], &names[0], sizeof(names[0]) * m_vertBindingsCount);
+			memcpy(&state.m_vertBuffNames[0],
+				&names[0],
+				sizeof(names[0]) * m_vertBindingsCount);
 		}
 		}
 
 
 		state.m_vertBindingCount = m_vertBindingsCount;
 		state.m_vertBindingCount = m_vertBindingsCount;

+ 2 - 0
src/renderer/Fs.cpp

@@ -158,6 +158,8 @@ void Fs::run(RenderingContext& ctx)
 			cmdb->pushSecondLevelCommandBuffer(ctx.m_fs.m_commandBuffers[i]);
 			cmdb->pushSecondLevelCommandBuffer(ctx.m_fs.m_commandBuffers[i]);
 		}
 		}
 	}
 	}
+
+	cmdb->endRenderPass();
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 2 - 3
src/renderer/Lf.cpp

@@ -220,11 +220,10 @@ void Lf::runOcclusionTests(RenderingContext& ctx, CommandBufferPtr cmdb)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Lf::run(RenderingContext& ctx)
+void Lf::run(RenderingContext& ctx, CommandBufferPtr cmdb)
 {
 {
 	// Retrieve some things
 	// Retrieve some things
 	FrustumComponent& camFr = *ctx.m_frustumComponent;
 	FrustumComponent& camFr = *ctx.m_frustumComponent;
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	VisibilityTestResults& vi = camFr.getVisibilityTestResults();
 	VisibilityTestResults& vi = camFr.getVisibilityTestResults();
 
 
 	U totalCount =
 	U totalCount =
@@ -239,7 +238,7 @@ void Lf::run(RenderingContext& ctx)
 		auto end = vi.getBegin(VisibilityGroupType::FLARES) + totalCount;
 		auto end = vi.getBegin(VisibilityGroupType::FLARES) + totalCount;
 		for(; it != end; ++it)
 		for(; it != end; ++it)
 		{
 		{
-			LensFlareComponent& lf =
+			const LensFlareComponent& lf =
 				(it->m_node)->getComponent<LensFlareComponent>();
 				(it->m_node)->getComponent<LensFlareComponent>();
 
 
 			// Compute position
 			// Compute position

+ 89 - 22
src/renderer/Renderer.cpp

@@ -42,6 +42,23 @@ public:
 	Mat4 m_projectionMatrix;
 	Mat4 m_projectionMatrix;
 };
 };
 
 
+//==============================================================================
+static Bool threadWillDoWork(const RenderingContext& ctx,
+	VisibilityGroupType typeOfWork,
+	U32 threadId,
+	PtrSize threadCount)
+{
+	const VisibilityTestResults& vis =
+		ctx.m_frustumComponent->getVisibilityTestResults();
+
+	U problemSize = vis.getCount(typeOfWork);
+	PtrSize start, end;
+	ThreadPoolTask::choseStartEnd(
+		threadId, threadCount, problemSize, start, end);
+
+	return start != end;
+}
+
 //==============================================================================
 //==============================================================================
 // Renderer                                                                    =
 // Renderer                                                                    =
 //==============================================================================
 //==============================================================================
@@ -271,9 +288,6 @@ Error Renderer::render(RenderingContext& ctx)
 	}
 	}
 
 
 	m_fs->run(ctx);
 	m_fs->run(ctx);
-	m_lf->run(ctx);
-	m_vol->run(ctx);
-	cmdb->endRenderPass();
 
 
 	m_ssao->run(ctx);
 	m_ssao->run(ctx);
 
 
@@ -400,18 +414,86 @@ void Renderer::createDrawQuadPipeline(
 	ppline = m_gr->newInstance<Pipeline>(init);
 	ppline = m_gr->newInstance<Pipeline>(init);
 }
 }
 
 
+//==============================================================================
+Error Renderer::buildCommandBuffersInternal(
+	RenderingContext& ctx, U32 threadId, PtrSize threadCount)
+{
+	ANKI_CHECK(m_ms->buildCommandBuffers(ctx, threadId, threadCount));
+
+	// Append to the last MS's cmdb the occlusion tests
+	if(ctx.m_ms.m_lastThreadWithWork == threadId)
+	{
+		m_lf->runOcclusionTests(ctx, ctx.m_ms.m_commandBuffers[threadId]);
+	}
+
+	ANKI_CHECK(m_sm->buildCommandBuffers(ctx, threadId, threadCount));
+
+	ANKI_CHECK(m_fs->buildCommandBuffers(ctx, threadId, threadCount));
+
+	// Append to the last FB's cmdb the other passes
+	if(ctx.m_fs.m_lastThreadWithWork == threadId)
+	{
+		m_lf->run(ctx, ctx.m_fs.m_commandBuffers[threadId]);
+		m_vol->run(ctx, ctx.m_fs.m_commandBuffers[threadId]);
+	}
+	else if(threadId == threadCount - 1
+		&& ctx.m_fs.m_lastThreadWithWork == MAX_U32)
+	{
+		// There is no FS work. Create a cmdb just for LF & VOL
+
+		CommandBufferInitInfo init;
+		init.m_flags = CommandBufferFlag::GRAPHICS_WORK
+			| CommandBufferFlag::SECOND_LEVEL | CommandBufferFlag::SMALL_BATCH;
+		init.m_framebuffer = m_fs->getFramebuffer();
+		CommandBufferPtr cmdb = getGrManager().newInstance<CommandBuffer>(init);
+		cmdb->setViewport(0, 0, m_fs->getWidth(), m_fs->getHeight());
+		cmdb->setPolygonOffset(0.0, 0.0);
+
+		m_lf->run(ctx, cmdb);
+		m_vol->run(ctx, cmdb);
+
+		ctx.m_fs.m_commandBuffers[threadId] = cmdb;
+	}
+
+	return ErrorCode::NONE;
+}
+
 //==============================================================================
 //==============================================================================
 Error Renderer::buildCommandBuffers(RenderingContext& ctx)
 Error Renderer::buildCommandBuffers(RenderingContext& ctx)
 {
 {
 	ANKI_TRACE_START_EVENT(RENDERER_COMMAND_BUFFER_BUILDING);
 	ANKI_TRACE_START_EVENT(RENDERER_COMMAND_BUFFER_BUILDING);
+	ThreadPool& threadPool = getThreadPool();
 
 
 	// Prepare
 	// Prepare
-	m_ms->prepareBuildCommandBuffers(ctx);
 	if(m_sm)
 	if(m_sm)
 	{
 	{
 		m_sm->prepareBuildCommandBuffers(ctx);
 		m_sm->prepareBuildCommandBuffers(ctx);
 	}
 	}
 
 
+	// Find the last jobs for MS and FS
+	U32 lastMsJob = MAX_U32;
+	U32 lastFsJob = MAX_U32;
+	U threadCount = threadPool.getThreadsCount();
+	for(U i = threadCount - 1; i != 0; --i)
+	{
+		if(threadWillDoWork(
+			   ctx, VisibilityGroupType::RENDERABLES_MS, i, threadCount)
+			&& lastMsJob == MAX_U32)
+		{
+			lastMsJob = i;
+		}
+
+		if(threadWillDoWork(
+			   ctx, VisibilityGroupType::RENDERABLES_FS, i, threadCount)
+			&& lastFsJob == MAX_U32)
+		{
+			lastFsJob = i;
+		}
+	}
+
+	ctx.m_ms.m_lastThreadWithWork = lastMsJob;
+	ctx.m_fs.m_lastThreadWithWork = lastFsJob;
+
 	// Build
 	// Build
 	class Task : public ThreadPoolTask
 	class Task : public ThreadPoolTask
 	{
 	{
@@ -419,28 +501,13 @@ Error Renderer::buildCommandBuffers(RenderingContext& ctx)
 		Renderer* m_r ANKI_DBG_NULLIFY_PTR;
 		Renderer* m_r ANKI_DBG_NULLIFY_PTR;
 		RenderingContext* m_ctx ANKI_DBG_NULLIFY_PTR;
 		RenderingContext* m_ctx ANKI_DBG_NULLIFY_PTR;
 
 
-		Error operator()(U32 threadId, PtrSize threadsCount)
+		Error operator()(U32 threadId, PtrSize threadCount)
 		{
 		{
-			ANKI_CHECK(m_r->getMs().buildCommandBuffers(
-				*m_ctx, threadId, threadsCount));
-
-			if(threadId == threadsCount - 1)
-			{
-				m_r->m_lf->runOcclusionTests(
-					*m_ctx, m_ctx->m_ms.m_commandBuffers[threadId]);
-			}
-
-			ANKI_CHECK(m_r->getSm().buildCommandBuffers(
-				*m_ctx, threadId, threadsCount));
-
-			ANKI_CHECK(m_r->getFs().buildCommandBuffers(
-				*m_ctx, threadId, threadsCount));
-
-			return ErrorCode::NONE;
+			return m_r->buildCommandBuffersInternal(
+				*m_ctx, threadId, threadCount);
 		}
 		}
 	};
 	};
 
 
-	ThreadPool& threadPool = getThreadPool();
 	Task task;
 	Task task;
 	task.m_r = this;
 	task.m_r = this;
 	task.m_ctx = &ctx;
 	task.m_ctx = &ctx;

+ 1 - 2
src/renderer/Volumetric.cpp

@@ -45,10 +45,9 @@ Error Volumetric::init(const ConfigSet& config)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Volumetric::run(RenderingContext& ctx)
+void Volumetric::run(RenderingContext& ctx, CommandBufferPtr cmdb)
 {
 {
 	const Frustum& frc = ctx.m_frustumComponent->getFrustum();
 	const Frustum& frc = ctx.m_frustumComponent->getFrustum();
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 
 
 	// Update uniforms
 	// Update uniforms
 	TransientMemoryInfo dyn;
 	TransientMemoryInfo dyn;

+ 1 - 1
src/scene/LensFlareComponent.cpp

@@ -63,7 +63,7 @@ OcclusionQueryPtr& LensFlareComponent::getOcclusionQueryToTest()
 
 
 //==============================================================================
 //==============================================================================
 void LensFlareComponent::getOcclusionQueryToCheck(
 void LensFlareComponent::getOcclusionQueryToCheck(
-	OcclusionQueryPtr& q, Bool& queryInvalid)
+	OcclusionQueryPtr& q, Bool& queryInvalid) const
 {
 {
 	U idx = (m_crntQueryIndex + 1) % m_queries.getSize();
 	U idx = (m_crntQueryIndex + 1) % m_queries.getSize();
 
 

+ 2 - 2
src/util/ThreadPosix.cpp

@@ -141,7 +141,7 @@ Thread::Id Thread::getCurrentThreadId()
 Mutex::Mutex()
 Mutex::Mutex()
 {
 {
 	pthread_mutex_t* mtx =
 	pthread_mutex_t* mtx =
-		reinterpret_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
+		static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
 	if(mtx == nullptr)
 	if(mtx == nullptr)
 	{
 	{
 		ANKI_LOGF("Out of memory");
 		ANKI_LOGF("Out of memory");
@@ -211,7 +211,7 @@ void Mutex::unlock()
 ConditionVariable::ConditionVariable()
 ConditionVariable::ConditionVariable()
 {
 {
 	pthread_cond_t* cond =
 	pthread_cond_t* cond =
-		reinterpret_cast<pthread_cond_t*>(malloc(sizeof(pthread_cond_t)));
+		static_cast<pthread_cond_t*>(malloc(sizeof(pthread_cond_t)));
 	if(cond == nullptr)
 	if(cond == nullptr)
 	{
 	{
 		ANKI_LOGF("Out of memory");
 		ANKI_LOGF("Out of memory");