Browse Source

Refactoring some texture related methods

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
ea2c1233db

+ 9 - 11
include/anki/gr/CommandBuffer.h

@@ -164,27 +164,25 @@ public:
 
 	void dispatchCompute(U32 groupCountX, U32 groupCountY, U32 groupCountZ);
 
-	void generateMipmaps(TexturePtr tex);
-
-	void generateMipmaps(TexturePtr tex, U surface);
+	void generateMipmaps(TexturePtr tex, U depth, U face);
 
 	void copyTextureToTexture(TexturePtr src,
-		U srcSlice,
-		U srcLevel,
+		const TextureSurfaceInfo& srcSurf,
 		TexturePtr dest,
-		U destSlice,
-		U destLevel);
+		const TextureSurfaceInfo& destSurf);
 
-	void clearTexture(
-		TexturePtr tex, U level, U depth, U face, const ClearValue& clearValue);
+	void clearTexture(TexturePtr tex,
+		const TextureSurfaceInfo& surf,
+		const ClearValue& clearValue);
 	/// @}
 
 	/// @name Resource upload
 	/// @{
 
 	/// Upload data to a texture.
-	void textureUpload(
-		TexturePtr tex, U32 mipmap, U32 slice, const DynamicBufferToken& token);
+	void textureUpload(TexturePtr tex,
+		const TextureSurfaceInfo& surf,
+		const DynamicBufferToken& token);
 
 	/// Write data to a buffer. It will copy the dynamic memory to the buffer
 	/// starting from offset to the range indicated by the allocation of the

+ 55 - 3
include/anki/gr/Common.h

@@ -63,6 +63,43 @@ anki_internal:
 	}
 };
 
+/// 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;
+	};
+};
+
+/// A way to identify a surface in a texture.
+class TextureSurfaceInfo
+{
+public:
+	TextureSurfaceInfo() = default;
+
+	TextureSurfaceInfo(const TextureSurfaceInfo&) = default;
+
+	TextureSurfaceInfo(U level, U depth, U face)
+		: m_level(level)
+		, m_depth(depth)
+		, m_face(face)
+	{
+	}
+
+	U32 m_level = 0;
+	U32 m_depth = 0;
+	U32 m_face = 0;
+};
+
 // Some constants
 // WARNING: If you change those update the shaders
 const U MAX_VERTEX_ATTRIBUTES = 8;
@@ -76,10 +113,25 @@ const U MAX_ATOMIC_BUFFER_BINDINGS = 1;
 const U MAX_FRAMES_IN_FLIGHT = 3;
 const U MAX_RESOURCE_GROUPS = 2;
 
-/// Compute max number of mipmaps for a 2D surface.
-inline U32 computeMaxMipmapCount(U32 w, U32 h)
+/// Compute max number of mipmaps for a 2D texture.
+inline U computeMaxMipmapCount(U w, U h)
+{
+	U s = (w < h) ? w : h;
+	U count = 0;
+	while(s)
+	{
+		s /= 2;
+		++count;
+	}
+
+	return count;
+}
+
+/// Compute max number of mipmaps for a 3D texture.
+inline U computeMaxMipmapCount(U w, U h, U d)
 {
-	U32 s = (w < h) ? w : h;
+	U s = (w < h) ? w : h;
+	s = (s < d) ? s : d;
 	U count = 0;
 	while(s)
 	{

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

@@ -366,23 +366,6 @@ 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

+ 7 - 15
include/anki/gr/gl/TextureImpl.h

@@ -42,30 +42,22 @@ public:
 	void init(const TextureInitInfo& init);
 
 	/// Write texture data.
-	void write(U32 mipmap, U32 slice, void* data, PtrSize dataSize);
+	void write(const TextureSurfaceInfo& surf, void* data, PtrSize dataSize);
 
 	/// Generate mipmaps.
-	void generateMipmaps(U surface);
+	void generateMipmaps(U depth, U face);
 
-	/// Copy a single slice from one texture to another.
+	/// Copy a single surface from one texture to another.
 	static void copy(const TextureImpl& src,
-		U srcSlice,
-		U srcLevel,
+		const TextureSurfaceInfo& srcSurf,
 		const TextureImpl& dest,
-		U destSlice,
-		U destLevel);
+		const TextureSurfaceInfo& destSurf);
 
 	void bind();
 
-	void clear(U level, U depth, U face, const ClearValue& clearValue);
+	void clear(const TextureSurfaceInfo& surf, 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;
-	}
+	U computeSurfaceIdx(const TextureSurfaceInfo& surf) const;
 };
 /// @}
 

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

@@ -60,7 +60,7 @@ anki_internal:
 
 	void generateMipmaps(CommandBufferPtr& cmdb)
 	{
-		cmdb->generateMipmaps(m_rt);
+		cmdb->generateMipmaps(m_rt, 0, 0);
 	}
 
 	DynamicBufferToken getCommonVarsToken() const

+ 4 - 4
src/core/Trace.cpp

@@ -66,7 +66,7 @@ TraceManager::~TraceManager()
 	{
 		Error err = m_traceFile.writeText(
 			"{\"name\": \"dummy\", "
-			"\"cat\": \"PERF\", \"ph\": \"X\", \"pid\": 666, \"tid\": %llu, "
+			"\"cat\": \"PERF\", \"ph\": \"X\", \"pid\": 1, \"tid\": %llu, "
 			"\"ts\": 0, \"dur\": 1}]}",
 			Thread::getCurrentThreadId());
 
@@ -176,7 +176,7 @@ Error TraceManager::flushCounters()
 	F32 fps = 1.0 / time;
 	ANKI_CHECK(m_traceFile.writeText(
 		"{\"name\": \"FPS\", \"cat\": \"PERF\", \"ph\": \"C\", "
-		"\"pid\": 666, \"ts\": %llu, \"args\": {\"val\": %f}},\n",
+		"\"pid\": 1, \"ts\": %llu, \"args\": {\"val\": %f}},\n",
 		U64(m_startFrameTime * 1000000.0),
 		fps));
 
@@ -188,7 +188,7 @@ Error TraceManager::flushCounters()
 
 		ANKI_CHECK(m_traceFile.writeText(
 			"{\"name\": \"%s\", \"cat\": \"PERF\", \"ph\": \"C\", "
-			"\"pid\": 666, \"ts\": %llu, \"args\": {\"val\": %llu}},\n",
+			"\"pid\": 1, \"ts\": %llu, \"args\": {\"val\": %llu}},\n",
 			counterNames[i],
 			U64(m_startFrameTime * 1000000.0),
 			count));
@@ -217,7 +217,7 @@ Error TraceManager::flushEvents()
 
 		ANKI_CHECK(m_traceFile.writeText(
 			"{\"name\": \"%s\", \"cat\": \"PERF\", \"ph\": \"X\", "
-			"\"pid\": 666, \"tid\": %llu, \"ts\": %llu, \"dur\": %llu},\n",
+			"\"pid\": 1, \"tid\": %llu, \"ts\": %llu, \"dur\": %llu},\n",
 			eventNames[e.m_event],
 			e.m_tid,
 			U64(e.m_timestamp * 1000000.0),

+ 35 - 76
src/gr/gl/CommandBuffer.cpp

@@ -462,17 +462,14 @@ class TexUploadCommand final : public GlCommand
 {
 public:
 	TexturePtr m_handle;
-	U32 m_mipmap;
-	U32 m_slice;
+	TextureSurfaceInfo m_surf;
 	DynamicBufferToken m_token;
 
 	TexUploadCommand(const TexturePtr& handle,
-		U32 mipmap,
-		U32 slice,
+		TextureSurfaceInfo surf,
 		const DynamicBufferToken& token)
 		: m_handle(handle)
-		, m_mipmap(mipmap)
-		, m_slice(slice)
+		, m_surf(surf)
 		, m_token(token)
 	{
 	}
@@ -482,20 +479,19 @@ public:
 		U8* data = state.m_dynamicBuffers[BufferUsage::TRANSFER].m_address
 			+ m_token.m_offset;
 
-		m_handle->getImplementation().write(
-			m_mipmap, m_slice, data, m_token.m_range);
-
+		m_handle->getImplementation().write(m_surf, data, m_token.m_range);
 		return ErrorCode::NONE;
 	}
 };
 
-void CommandBuffer::textureUpload(
-	TexturePtr tex, U32 mipmap, U32 slice, const DynamicBufferToken& token)
+void CommandBuffer::textureUpload(TexturePtr tex,
+	const TextureSurfaceInfo& surf,
+	const DynamicBufferToken& token)
 {
 	ANKI_ASSERT(!m_impl->m_dbg.m_insideRenderPass);
 	ANKI_ASSERT(token.m_range > 0);
 
-	m_impl->pushBackNewCommand<TexUploadCommand>(tex, mipmap, slice, token);
+	m_impl->pushBackNewCommand<TexUploadCommand>(tex, surf, token);
 }
 
 //==============================================================================
@@ -538,49 +534,27 @@ class GenMipsCommand final : public GlCommand
 {
 public:
 	TexturePtr m_tex;
+	U32 m_depth;
+	U8 m_face;
 
-	GenMipsCommand(const TexturePtr& tex)
-		: m_tex(tex)
-	{
-	}
-
-	Error operator()(GlState&)
-	{
-		m_tex->getImplementation().generateMipmaps(0);
-		return ErrorCode::NONE;
-	}
-};
-
-void CommandBuffer::generateMipmaps(TexturePtr tex)
-{
-	ANKI_ASSERT(!m_impl->m_dbg.m_insideRenderPass);
-	m_impl->pushBackNewCommand<GenMipsCommand>(tex);
-}
-
-//==============================================================================
-class GenMipsCommand1 final : public GlCommand
-{
-public:
-	TexturePtr m_tex;
-	U32 m_surface;
-
-	GenMipsCommand1(const TexturePtr& tex, U surface)
+	GenMipsCommand(const TexturePtr& tex, U depth, U face)
 		: m_tex(tex)
-		, m_surface(surface)
+		, m_depth(depth)
+		, m_face(face)
 	{
 	}
 
 	Error operator()(GlState&)
 	{
-		m_tex->getImplementation().generateMipmaps(m_surface);
+		m_tex->getImplementation().generateMipmaps(m_depth, m_face);
 		return ErrorCode::NONE;
 	}
 };
 
-void CommandBuffer::generateMipmaps(TexturePtr tex, U surface)
+void CommandBuffer::generateMipmaps(TexturePtr tex, U depth, U face)
 {
 	ANKI_ASSERT(!m_impl->m_dbg.m_insideRenderPass);
-	m_impl->pushBackNewCommand<GenMipsCommand1>(tex, surface);
+	m_impl->pushBackNewCommand<GenMipsCommand>(tex, depth, face);
 }
 
 //==============================================================================
@@ -622,49 +596,38 @@ class CopyTexCommand final : public GlCommand
 {
 public:
 	TexturePtr m_src;
-	U16 m_srcSlice;
-	U16 m_srcLevel;
+	TextureSurfaceInfo m_srcSurf;
 	TexturePtr m_dest;
-	U16 m_destSlice;
-	U16 m_destLevel;
+	TextureSurfaceInfo m_destSurf;
 
 	CopyTexCommand(TexturePtr src,
-		U srcSlice,
-		U srcLevel,
+		const TextureSurfaceInfo& srcSurf,
 		TexturePtr dest,
-		U destSlice,
-		U destLevel)
+		const TextureSurfaceInfo& destSurf)
 		: m_src(src)
-		, m_srcSlice(srcSlice)
-		, m_srcLevel(srcLevel)
+		, m_srcSurf(srcSurf)
 		, m_dest(dest)
-		, m_destSlice(destSlice)
-		, m_destLevel(destLevel)
+		, m_destSurf(destSurf)
 	{
 	}
 
 	Error operator()(GlState&)
 	{
 		TextureImpl::copy(m_src->getImplementation(),
-			m_srcSlice,
-			m_srcLevel,
+			m_srcSurf,
 			m_dest->getImplementation(),
-			m_destSlice,
-			m_destLevel);
+			m_destSurf);
 		return ErrorCode::NONE;
 	}
 };
 
 void CommandBuffer::copyTextureToTexture(TexturePtr src,
-	U srcSlice,
-	U srcLevel,
+	const TextureSurfaceInfo& srcSurf,
 	TexturePtr dest,
-	U destSlice,
-	U destLevel)
+	const TextureSurfaceInfo& destSurf)
 {
 	ANKI_ASSERT(!m_impl->m_dbg.m_insideRenderPass);
-	m_impl->pushBackNewCommand<CopyTexCommand>(
-		src, srcSlice, srcLevel, dest, destSlice, destLevel);
+	m_impl->pushBackNewCommand<CopyTexCommand>(src, srcSurf, dest, destSurf);
 }
 
 //==============================================================================
@@ -738,32 +701,28 @@ class ClearTextCommand final : public GlCommand
 public:
 	TexturePtr m_tex;
 	ClearValue m_val;
-	U16 m_level;
-	U16 m_depth;
-	U8 m_face;
+	TextureSurfaceInfo m_surf;
 
 	ClearTextCommand(
-		TexturePtr tex, U level, U depth, U face, const ClearValue& val)
+		TexturePtr tex, const TextureSurfaceInfo& surf, const ClearValue& val)
 		: m_tex(tex)
 		, m_val(val)
-		, m_level(level)
-		, m_depth(depth)
-		, m_face(face)
+		, m_surf(surf)
 	{
 	}
 
 	Error operator()(GlState&)
 	{
-		m_tex->getImplementation().clear(m_level, m_depth, m_face, m_val);
+		m_tex->getImplementation().clear(m_surf, m_val);
 		return ErrorCode::NONE;
 	}
 };
 
-void CommandBuffer::clearTexture(
-	TexturePtr tex, U level, U depth, U face, const ClearValue& clearValue)
+void CommandBuffer::clearTexture(TexturePtr tex,
+	const TextureSurfaceInfo& surf,
+	const ClearValue& clearValue)
 {
-	m_impl->pushBackNewCommand<ClearTextCommand>(
-		tex, level, depth, face, clearValue);
+	m_impl->pushBackNewCommand<ClearTextCommand>(tex, surf, clearValue);
 }
 
 } // end namespace anki

+ 64 - 26
src/gr/gl/TextureImpl.cpp

@@ -289,6 +289,7 @@ void TextureImpl::init(const TextureInitInfo& init)
 	m_width = init.m_width;
 	m_height = init.m_height;
 	m_depth = init.m_depth;
+	ANKI_ASSERT(m_depth > 0);
 	m_target = convertTextureType(init.m_type);
 
 	convertTextureInformation(
@@ -415,8 +416,12 @@ void TextureImpl::init(const TextureInitInfo& init)
 }
 
 //==============================================================================
-void TextureImpl::write(U32 mipmap, U32 slice, void* data, PtrSize dataSize)
+void TextureImpl::write(
+	const TextureSurfaceInfo& surf, void* data, PtrSize dataSize)
 {
+	U mipmap = surf.m_level;
+	U surfIdx = computeSurfaceIdx(surf);
+
 	ANKI_ASSERT(data);
 	ANKI_ASSERT(dataSize > 0);
 	ANKI_ASSERT(mipmap < m_mipsCount);
@@ -446,7 +451,7 @@ void TextureImpl::write(U32 mipmap, U32 slice, void* data, PtrSize dataSize)
 	case GL_TEXTURE_CUBE_MAP:
 		if(!m_compressed)
 		{
-			glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice,
+			glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + surfIdx,
 				mipmap,
 				0,
 				0,
@@ -458,7 +463,7 @@ void TextureImpl::write(U32 mipmap, U32 slice, void* data, PtrSize dataSize)
 		}
 		else
 		{
-			glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice,
+			glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + surfIdx,
 				mipmap,
 				0,
 				0,
@@ -472,12 +477,20 @@ void TextureImpl::write(U32 mipmap, U32 slice, void* data, PtrSize dataSize)
 	case GL_TEXTURE_2D_ARRAY:
 	case GL_TEXTURE_3D:
 		ANKI_ASSERT(m_depth > 0);
-		ANKI_ASSERT(slice < m_depth);
 
 		if(!m_compressed)
 		{
-			glTexSubImage3D(
-				m_target, mipmap, 0, 0, slice, w, h, 1, m_format, m_type, data);
+			glTexSubImage3D(m_target,
+				mipmap,
+				0,
+				0,
+				surfIdx,
+				w,
+				h,
+				1,
+				m_format,
+				m_type,
+				data);
 		}
 		else
 		{
@@ -485,7 +498,7 @@ void TextureImpl::write(U32 mipmap, U32 slice, void* data, PtrSize dataSize)
 				mipmap,
 				0,
 				0,
-				slice,
+				surfIdx,
 				w,
 				h,
 				1,
@@ -502,8 +515,9 @@ void TextureImpl::write(U32 mipmap, U32 slice, void* data, PtrSize dataSize)
 }
 
 //==============================================================================
-void TextureImpl::generateMipmaps(U surface)
+void TextureImpl::generateMipmaps(U depth, U face)
 {
+	U surface = computeSurfaceIdx(TextureSurfaceInfo(0, depth, face));
 	ANKI_ASSERT(surface < m_surfaceCount);
 	ANKI_ASSERT(!m_compressed);
 
@@ -554,52 +568,54 @@ void TextureImpl::generateMipmaps(U surface)
 
 //==============================================================================
 void TextureImpl::copy(const TextureImpl& src,
-	U srcSlice,
-	U srcLevel,
+	const TextureSurfaceInfo& srcSurf,
 	const TextureImpl& dest,
-	U destSlice,
-	U destLevel)
+	const TextureSurfaceInfo& destSurf)
 {
 	ANKI_ASSERT(src.m_internalFormat == dest.m_internalFormat);
 	ANKI_ASSERT(src.m_format == dest.m_format);
 	ANKI_ASSERT(src.m_type == dest.m_type);
 
-	U width = src.m_width >> srcLevel;
-	U height = src.m_height >> srcLevel;
+	U width = src.m_width >> srcSurf.m_level;
+	U height = src.m_height >> srcSurf.m_level;
 
 	ANKI_ASSERT(width > 0 && height > 0);
-	ANKI_ASSERT(width == (dest.m_width >> destLevel)
-		&& height == (dest.m_height >> destLevel));
+	ANKI_ASSERT(width == (dest.m_width >> destSurf.m_level)
+		&& height == (dest.m_height >> destSurf.m_level));
+
+	U srcSurfaceIdx = src.computeSurfaceIdx(srcSurf);
+	U destSurfaceIdx = dest.computeSurfaceIdx(destSurf);
 
 	glCopyImageSubData(src.getGlName(),
 		src.m_target,
-		srcLevel,
+		srcSurf.m_level,
 		0,
 		0,
-		srcSlice,
+		srcSurfaceIdx,
 		dest.getGlName(),
 		dest.m_target,
-		destLevel,
+		destSurf.m_level,
 		0,
 		0,
-		destSlice,
+		destSurfaceIdx,
 		width,
 		height,
 		1);
 }
 
 //==============================================================================
-void TextureImpl::clear(U level, U depth, U face, const ClearValue& clearValue)
+void TextureImpl::clear(
+	const TextureSurfaceInfo& surf, const ClearValue& clearValue)
 {
 	ANKI_ASSERT(isCreated());
-	ANKI_ASSERT(level < m_mipsCount);
+	ANKI_ASSERT(surf.m_level < m_mipsCount);
 
-	U surfaceIdx = computeSurfaceIdx(depth, face);
-	U width = m_width >> level;
-	U height = m_height >> level;
+	U surfaceIdx = computeSurfaceIdx(surf);
+	U width = m_width >> surf.m_level;
+	U height = m_height >> surf.m_level;
 
 	glClearTexSubImage(m_glName,
-		level,
+		surf.m_level,
 		0,
 		0,
 		surfaceIdx,
@@ -611,4 +627,26 @@ void TextureImpl::clear(U level, U depth, U face, const ClearValue& clearValue)
 		&clearValue.m_colorf[0]);
 }
 
+//==============================================================================
+U TextureImpl::computeSurfaceIdx(const TextureSurfaceInfo& surf) const
+{
+	ANKI_ASSERT(surf.m_face < m_faceCount);
+	ANKI_ASSERT(surf.m_depth < m_depth);
+	ANKI_ASSERT(surf.m_level < m_mipsCount);
+
+	if(m_target == GL_TEXTURE_3D)
+	{
+		// Check depth for this level
+		U depth = m_depth >> surf.m_level;
+		ANKI_ASSERT(surf.m_depth < depth);
+		(void)depth;
+
+		return surf.m_depth;
+	}
+	else
+	{
+		return m_faceCount * surf.m_depth + surf.m_face;
+	}
+}
+
 } // end namespace anki

+ 8 - 8
src/renderer/Ir.cpp

@@ -110,12 +110,14 @@ Error Ir::init(const ConfigSet& config)
 			for(U l = 0; l < m_cubemapArrMipCount; ++l)
 			{
 				// Do env
-				cmdb->clearTexture(m_envCubemapArr, l, i, f, clear);
+				cmdb->clearTexture(
+					m_envCubemapArr, TextureSurfaceInfo(l, i, f), clear);
 			}
 
 			for(U l = 0; l < irrMipCount; ++l)
 			{
-				cmdb->clearTexture(m_irradianceCubemapArr, l, i, f, clear);
+				cmdb->clearTexture(
+					m_irradianceCubemapArr, TextureSurfaceInfo(l, i, f), clear);
 			}
 		}
 	}
@@ -264,14 +266,12 @@ Error Ir::renderReflection(RenderingContext& ctx,
 
 		// Copy env texture
 		cmdb->copyTextureToTexture(m_nestedR.getIs().getRt(),
-			0,
-			0,
+			TextureSurfaceInfo(0, 0, 0),
 			m_envCubemapArr,
-			6 * cubemapIdx + i,
-			0);
+			TextureSurfaceInfo(0, cubemapIdx, i));
 
 		// Gen mips of env tex
-		cmdb->generateMipmaps(m_envCubemapArr, 6 * cubemapIdx + i);
+		cmdb->generateMipmaps(m_envCubemapArr, cubemapIdx, i);
 	}
 
 	// Compute irradiance
@@ -302,7 +302,7 @@ Error Ir::renderReflection(RenderingContext& ctx,
 		m_r->drawQuad(cmdb);
 		cmdb->endRenderPass();
 
-		cmdb->generateMipmaps(m_irradianceCubemapArr, 6 * cubemapIdx + i);
+		cmdb->generateMipmaps(m_irradianceCubemapArr, cubemapIdx, i);
 	}
 
 	return ErrorCode::NONE;

+ 3 - 3
src/renderer/Renderer.cpp

@@ -262,8 +262,8 @@ Error Renderer::render(RenderingContext& ctx)
 
 	m_is->run(ctx);
 
-	cmdb->generateMipmaps(m_ms->getDepthRt());
-	cmdb->generateMipmaps(m_ms->getRt2());
+	cmdb->generateMipmaps(m_ms->getDepthRt(), 0, 0);
+	cmdb->generateMipmaps(m_ms->getRt2(), 0, 0);
 
 	m_fs->run(ctx);
 	m_lf->run(ctx);
@@ -354,7 +354,7 @@ void Renderer::createRenderTarget(U32 w,
 
 	init.m_width = w;
 	init.m_height = h;
-	init.m_depth = 0;
+	init.m_depth = 1;
 	init.m_type = TextureType::_2D;
 	init.m_format = format;
 	init.m_mipmapsCount = mipsCount;

+ 2 - 1
src/renderer/Ssao.cpp

@@ -107,6 +107,7 @@ Error Ssao::initInternal(const ConfigSet& config)
 	TextureInitInfo tinit;
 
 	tinit.m_width = tinit.m_height = NOISE_TEX_SIZE;
+	tinit.m_depth = 1;
 	tinit.m_type = TextureType::_2D;
 	tinit.m_format =
 		PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT);
@@ -127,7 +128,7 @@ Error Ssao::initInternal(const ConfigSet& config)
 
 	genNoise(noise, noise + NOISE_TEX_SIZE * NOISE_TEX_SIZE);
 
-	cmdb->textureUpload(m_noiseTex, 0, 0, token);
+	cmdb->textureUpload(m_noiseTex, TextureSurfaceInfo(0, 0, 0), token);
 	cmdb->flush();
 
 	//

+ 33 - 20
src/resource/TextureResource.cpp

@@ -21,16 +21,19 @@ public:
 	UniquePtr<ImageLoader> m_loader;
 	TexturePtr m_tex;
 	GrManager* m_gr ANKI_DBG_NULLIFY_PTR;
-	U32 m_layerCount = 0;
+	U32 m_depth = 0;
+	U8 m_faces = 0;
 
 	TexUploadTask(UniquePtr<ImageLoader>& loader,
 		TexturePtr tex,
 		GrManager* gr,
-		U32 layerCount)
+		U depth,
+		U faces)
 		: m_loader(std::move(loader))
 		, m_tex(tex)
 		, m_gr(gr)
-		, m_layerCount(layerCount)
+		, m_depth(depth)
+		, m_faces(faces)
 	{
 	}
 
@@ -44,18 +47,23 @@ Error TexUploadTask::operator()()
 		m_gr->newInstance<CommandBuffer>(CommandBufferInitInfo());
 
 	// Upload the data
-	for(U layer = 0; layer < m_layerCount; layer++)
+	for(U depth = 0; depth < m_depth; depth++)
 	{
-		for(U level = 0; level < m_loader->getMipLevelsCount(); level++)
+		for(U face = 0; face < m_faces; face++)
 		{
-			const auto& surf = m_loader->getSurface(level, layer);
-
-			DynamicBufferToken token;
-			void* data = m_gr->allocateFrameHostVisibleMemory(
-				surf.m_data.getSize(), BufferUsage::TRANSFER, token);
-			memcpy(data, &surf.m_data[0], surf.m_data.getSize());
-
-			cmdb->textureUpload(m_tex, level, layer, token);
+			for(U level = 0; level < m_loader->getMipLevelsCount(); level++)
+			{
+				U surfIdx = max(depth, face);
+				const auto& surf = m_loader->getSurface(level, surfIdx);
+
+				DynamicBufferToken token;
+				void* data = m_gr->allocateFrameHostVisibleMemory(
+					surf.m_data.getSize(), BufferUsage::TRANSFER, token);
+				memcpy(data, &surf.m_data[0], surf.m_data.getSize());
+
+				cmdb->textureUpload(
+					m_tex, TextureSurfaceInfo(level, depth, face), token);
+			}
 		}
 	}
 
@@ -84,7 +92,8 @@ Error TextureResource::load(const ResourceFilename& filename)
 		gr.newInstance<CommandBuffer>(CommandBufferInitInfo());
 
 	TextureInitInfo init;
-	U layers = 0;
+	U depth = 0;
+	U faces = 0;
 
 	// Load image
 	UniquePtr<ImageLoader> img;
@@ -108,7 +117,7 @@ Error TextureResource::load(const ResourceFilename& filename)
 	}
 	else
 	{
-		init.m_depth = 0;
+		init.m_depth = 1;
 	}
 
 	// target
@@ -116,19 +125,23 @@ Error TextureResource::load(const ResourceFilename& filename)
 	{
 	case ImageLoader::TextureType::_2D:
 		init.m_type = TextureType::_2D;
-		layers = 1;
+		depth = 1;
+		faces = 1;
 		break;
 	case ImageLoader::TextureType::CUBE:
 		init.m_type = TextureType::CUBE;
-		layers = 6;
+		depth = 1;
+		faces = 6;
 		break;
 	case ImageLoader::TextureType::_2D_ARRAY:
 		init.m_type = TextureType::_2D_ARRAY;
-		layers = init.m_depth;
+		depth = init.m_depth;
+		faces = 1;
 		break;
 	case ImageLoader::TextureType::_3D:
 		init.m_type = TextureType::_3D;
-		layers = init.m_depth;
+		depth = init.m_depth;
+		faces = 1;
 		break;
 	default:
 		ANKI_ASSERT(0);
@@ -201,7 +214,7 @@ Error TextureResource::load(const ResourceFilename& filename)
 
 	// Upload the data asynchronously
 	getManager().getAsyncLoader().newTask<TexUploadTask>(
-		img, m_tex, &gr, layers);
+		img, m_tex, &gr, depth, faces);
 
 	m_size = UVec3(init.m_width, init.m_height, init.m_depth);
 

+ 2 - 2
src/ui/UiInterfaceImpl.cpp

@@ -223,10 +223,10 @@ Error UiInterfaceImpl::createR8Image(
 	void* loadData = m_gr->allocateFrameHostVisibleMemory(
 		data.getSize(), BufferUsage::TRANSFER, token);
 	memcpy(loadData, &data[0], data.getSize());
-	cmdb->textureUpload(tex, 0, 0, token);
+	cmdb->textureUpload(tex, TextureSurfaceInfo(0, 0, 0), token);
 
 	// Gen mips
-	cmdb->generateMipmaps(tex);
+	cmdb->generateMipmaps(tex, 0, 0);
 	cmdb->flush();
 
 	// Create the UiImage

+ 1 - 1
tests/script/LuaBinder.cpp

@@ -26,7 +26,7 @@ ANKI_TEST(Script, LuaBinder)
 {
 	ScriptManager sm;
 
-	ANKI_TEST_EXPECT_NO_ERR(sm.create(allocAligned, nullptr, nullptr));
+	ANKI_TEST_EXPECT_NO_ERR(sm.init(allocAligned, nullptr, nullptr, nullptr));
 	Vec4 v4(2.0, 3.0, 4.0, 5.0);
 	Vec3 v3(1.1, 2.2, 3.3);