Browse Source

Adding support for clearing textures. Needed for IR

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
488585af67

+ 3 - 0
include/anki/gr/CommandBuffer.h

@@ -174,6 +174,9 @@ public:
 		TexturePtr dest,
 		U destSlice,
 		U destLevel);
+
+	void clearTexture(
+		TexturePtr tex, U level, U depth, U face, const ClearValue& clearValue);
 	/// @}
 
 	/// @name Resource upload

+ 18 - 0
include/anki/gr/Enums.h

@@ -7,6 +7,7 @@
 
 #include <anki/util/StdTypes.h>
 #include <anki/util/Enum.h>
+#include <anki/util/Array.h>
 
 namespace anki
 {
@@ -365,6 +366,23 @@ enum class ResourceAccessBit : U16
 	TRANSFER_WRITE = 1 << 9
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ResourceAccessBit, inline)
+
+/// Clear values for textures or attachments.
+class ClearValue
+{
+public:
+	union
+	{
+		Array<F32, 4> m_colorf = {{0.0, 0.0, 0.0, 0.0}};
+		Array<I32, 4> m_colori;
+		Array<U32, 4> m_coloru;
+		struct
+		{
+			F32 m_depth;
+			I32 m_stencil;
+		} m_depthStencil;
+	};
+};
 /// @}
 
 } // end namespace anki

+ 1 - 11
include/anki/gr/Framebuffer.h

@@ -27,17 +27,7 @@ public:
 	PixelFormat m_format;
 	AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::CLEAR;
 	AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::STORE;
-	union
-	{
-		Array<F32, 4> m_colorf = {{0.0, 0.0, 0.0, 0.0}};
-		Array<I32, 4> m_colori;
-		Array<U32, 4> m_coloru;
-		struct
-		{
-			F32 m_depth;
-			I32 m_stencil;
-		} m_depthStencil;
-	} m_clearValue;
+	ClearValue m_clearValue;
 
 	Attachment() = default;
 

+ 11 - 0
include/anki/gr/gl/TextureImpl.h

@@ -27,6 +27,7 @@ public:
 	U32 m_depth = 0;
 	U32 m_surfaceCount = 0;
 	U8 m_mipsCount = 0;
+	U8 m_faceCount = 0; ///< 6 for cubes and 1 for the rest
 	Bool8 m_compressed = false;
 	DArray<GLuint> m_texViews; ///< Temp views for gen mips.
 
@@ -55,6 +56,16 @@ public:
 		U destLevel);
 
 	void bind();
+
+	void clear(U level, U depth, U face, const ClearValue& clearValue);
+
+	U computeSurfaceIdx(U depth, U face) const
+	{
+		ANKI_ASSERT(m_target != GL_TEXTURE_3D && "TODO");
+		ANKI_ASSERT(face < m_faceCount);
+		ANKI_ASSERT(depth < m_depth);
+		return m_faceCount * depth + face;
+	}
 };
 /// @}
 

+ 34 - 0
src/gr/gl/CommandBuffer.cpp

@@ -732,4 +732,38 @@ void CommandBuffer::setBufferMemoryBarrier(
 	m_impl->pushBackNewCommand<SetBufferMemBarrierCommand>(d);
 }
 
+//==============================================================================
+class ClearTextCommand final : public GlCommand
+{
+public:
+	TexturePtr m_tex;
+	ClearValue m_val;
+	U16 m_level;
+	U16 m_depth;
+	U8 m_face;
+
+	ClearTextCommand(
+		TexturePtr tex, U level, U depth, U face, const ClearValue& val)
+		: m_tex(tex)
+		, m_val(val)
+		, m_level(level)
+		, m_depth(depth)
+		, m_face(face)
+	{
+	}
+
+	Error operator()(GlState&)
+	{
+		m_tex->getImplementation().clear(m_level, m_depth, m_face, m_val);
+		return ErrorCode::NONE;
+	}
+};
+
+void CommandBuffer::clearTexture(
+	TexturePtr tex, U level, U depth, U face, const ClearValue& clearValue)
+{
+	m_impl->pushBackNewCommand<ClearTextCommand>(
+		tex, level, depth, face, clearValue);
+}
+
 } // end namespace anki

+ 27 - 0
src/gr/gl/TextureImpl.cpp

@@ -344,16 +344,20 @@ void TextureImpl::init(const TextureInitInfo& init)
 	case GL_TEXTURE_2D:
 	case GL_TEXTURE_2D_MULTISAMPLE:
 		m_surfaceCount = 1;
+		m_faceCount = 1;
 		break;
 	case GL_TEXTURE_CUBE_MAP:
 		m_surfaceCount = 6;
+		m_faceCount = 6;
 		break;
 	case GL_TEXTURE_CUBE_MAP_ARRAY:
 		m_surfaceCount = init.m_depth * 6;
+		m_faceCount = 6;
 		break;
 	case GL_TEXTURE_2D_ARRAY:
 	case GL_TEXTURE_3D:
 		m_surfaceCount = init.m_depth;
+		m_faceCount = 1;
 		break;
 	default:
 		ANKI_ASSERT(0);
@@ -584,4 +588,27 @@ void TextureImpl::copy(const TextureImpl& src,
 		1);
 }
 
+//==============================================================================
+void TextureImpl::clear(U level, U depth, U face, const ClearValue& clearValue)
+{
+	ANKI_ASSERT(isCreated());
+	ANKI_ASSERT(level < m_mipsCount);
+
+	U surfaceIdx = computeSurfaceIdx(depth, face);
+	U width = m_width >> level;
+	U height = m_height >> level;
+
+	glClearTexSubImage(m_glName,
+		level,
+		0,
+		0,
+		surfaceIdx,
+		width,
+		height,
+		1,
+		m_format,
+		m_type,
+		&clearValue.m_colorf[0]);
+}
+
 } // end namespace anki

+ 23 - 0
src/renderer/Ir.cpp

@@ -98,6 +98,29 @@ Error Ir::init(const ConfigSet& config)
 	// Create irradiance stuff
 	ANKI_CHECK(initIrradiance());
 
+	// Clear the textures
+	CommandBufferInitInfo cinf;
+	CommandBufferPtr cmdb = getGrManager().newInstance<CommandBuffer>(cinf);
+	U irrMipCount = computeMaxMipmapCount(IRRADIANCE_SIZE, IRRADIANCE_SIZE);
+	ClearValue clear;
+	for(U i = 0; i < m_cubemapArrSize; ++i)
+	{
+		for(U f = 0; f < 6; ++f)
+		{
+			for(U l = 0; l < m_cubemapArrMipCount; ++l)
+			{
+				// Do env
+				cmdb->clearTexture(m_envCubemapArr, l, i, f, clear);
+			}
+
+			for(U l = 0; l < irrMipCount; ++l)
+			{
+				cmdb->clearTexture(m_irradianceCubemapArr, l, i, f, clear);
+			}
+		}
+	}
+	cmdb->flush();
+
 	// Load split sum integration LUT
 	ANKI_CHECK(getResourceManager().loadResource(
 		"engine_data/SplitSumIntegration.ankitex", m_integrationLut));

+ 1 - 1
src/scene/Sector.cpp

@@ -682,7 +682,7 @@ void SectorGroup::findVisibleNodes(const FrustumComponent& frc,
 			}
 		}
 	}
-		
+
 	// Update the context
 	ctx.m_visibleNodes = SArray<SceneNode*>(visibleNodesMem, nodesCount);
 }

+ 4 - 7
src/scene/Visibility.cpp

@@ -136,7 +136,7 @@ public:
 					}
 					else
 					{
-						testInfo = m_ctx->m_pendingTests.getFront();	
+						testInfo = m_ctx->m_pendingTests.getFront();
 					}
 				}
 				else
@@ -466,9 +466,8 @@ void VisibilityTestTask::test(
 				// Do that outside the lock
 				if(t)
 				{
-					m_ctx->m_scene->getSectorGroup().findVisibleNodes(frc,
-						testId,
-						t->m_sectorsCtx);
+					m_ctx->m_scene->getSectorGroup().findVisibleNodes(
+						frc, testId, t->m_sectorsCtx);
 				}
 				return ErrorCode::NONE;
 			});
@@ -621,9 +620,7 @@ Error doVisibilityTests(SceneNode& fsn, SceneGraph& scene, const Renderer& r)
 		&fsn.getComponent<FrustumComponent>());
 	ctx.m_pendingTests.pushBack(t);
 	scene.getSectorGroup().findVisibleNodes(
-		fsn.getComponent<FrustumComponent>(),
-		0,
-		t->m_sectorsCtx);
+		fsn.getComponent<FrustumComponent>(), 0, t->m_sectorsCtx);
 
 	Array<VisibilityTestTask, ThreadPool::MAX_THREADS> tasks;
 	for(U i = 0; i < threadPool.getThreadsCount(); i++)