Просмотр исходного кода

[REFACTOR] The Framebuffer is now using TextureViews

Panagiotis Christopoulos Charitos 8 лет назад
Родитель
Сommit
2bc68b85c3

+ 10 - 7
src/anki/gr/Framebuffer.h

@@ -6,8 +6,7 @@
 #pragma once
 
 #include <anki/gr/GrObject.h>
-#include <anki/gr/Texture.h>
-#include <cstring>
+#include <anki/gr/TextureView.h>
 
 namespace anki
 {
@@ -19,16 +18,15 @@ namespace anki
 class FramebufferAttachmentInfo
 {
 public:
-	TexturePtr m_texture;
-	TextureSurfaceInfo m_surface;
+	TextureViewPtr m_textureView;
+
 	AttachmentLoadOperation m_loadOperation = AttachmentLoadOperation::CLEAR;
 	AttachmentStoreOperation m_storeOperation = AttachmentStoreOperation::STORE;
-	ClearValue m_clearValue;
 
 	AttachmentLoadOperation m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
 	AttachmentStoreOperation m_stencilStoreOperation = AttachmentStoreOperation::STORE;
 
-	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::NONE; ///< Relevant only for depth stencil textures.
+	ClearValue m_clearValue;
 };
 
 /// Framebuffer initializer. If you require the default framebuffer then set m_colorAttachmentCount to 1 and don't set a
@@ -74,7 +72,12 @@ public:
 
 	Bool refersToDefaultFramebuffer() const
 	{
-		return m_colorAttachmentCount == 1 && !m_colorAttachments[0].m_texture.isCreated();
+		return m_colorAttachmentCount == 1 && !m_colorAttachments[0].m_textureView.isCreated();
+	}
+
+	Bool isValid() const
+	{
+		return m_colorAttachmentCount != 0 || m_depthStencilAttachment.m_textureView.isCreated();
 	}
 };
 

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

@@ -147,45 +147,15 @@ void FramebufferDescription::bake()
 	ANKI_ASSERT(m_hash == 0 && "Already baked");
 	if(m_defaultFb)
 	{
-		m_fbInitInfo.m_colorAttachmentCount = 1;
 		m_hash = 1;
 		return;
 	}
 
-	// Populate the FB init info
-	m_fbInitInfo.m_colorAttachmentCount = m_colorAttachmentCount;
-	for(U i = 0; i < m_colorAttachmentCount; ++i)
-	{
-		FramebufferAttachmentInfo& out = m_fbInitInfo.m_colorAttachments[i];
-		const FramebufferDescriptionAttachment& in = m_colorAttachments[i];
-
-		out.m_surface = in.m_surface;
-		out.m_clearValue = in.m_clearValue;
-		out.m_loadOperation = in.m_loadOperation;
-		out.m_storeOperation = in.m_storeOperation;
-	}
-
-	if(!!m_depthStencilAttachment.m_aspect)
-	{
-		FramebufferAttachmentInfo& out = m_fbInitInfo.m_depthStencilAttachment;
-		const FramebufferDescriptionAttachment& in = m_depthStencilAttachment;
-
-		out.m_surface = in.m_surface;
-		out.m_loadOperation = in.m_loadOperation;
-		out.m_storeOperation = in.m_storeOperation;
-		out.m_clearValue = in.m_clearValue;
-
-		out.m_stencilLoadOperation = in.m_stencilLoadOperation;
-		out.m_stencilStoreOperation = in.m_stencilStoreOperation;
-
-		out.m_aspect = in.m_aspect;
-	}
-
 	m_hash = 0;
-	ANKI_ASSERT(m_fbInitInfo.m_colorAttachmentCount > 0 || !!m_fbInitInfo.m_depthStencilAttachment.m_aspect);
+	ANKI_ASSERT(m_colorAttachmentCount > 0 || !!m_depthStencilAttachment.m_aspect);
 
 	// First the depth attachments
-	if(m_fbInitInfo.m_colorAttachmentCount)
+	if(m_colorAttachmentCount)
 	{
 		ANKI_BEGIN_PACKED_STRUCT
 		struct ColorAttachment
@@ -199,20 +169,20 @@ void FramebufferDescription::bake()
 		static_assert(sizeof(ColorAttachment) == 4 * (4 + 1 + 1 + 4), "Wrong size");
 
 		Array<ColorAttachment, MAX_COLOR_ATTACHMENTS> colorAttachments;
-		for(U i = 0; i < m_fbInitInfo.m_colorAttachmentCount; ++i)
+		for(U i = 0; i < m_colorAttachmentCount; ++i)
 		{
-			const FramebufferAttachmentInfo& inAtt = m_fbInitInfo.m_colorAttachments[i];
+			const FramebufferDescriptionAttachment& inAtt = m_colorAttachments[i];
 			colorAttachments[i].m_surf = inAtt.m_surface;
 			colorAttachments[i].m_loadOp = static_cast<U32>(inAtt.m_loadOperation);
 			colorAttachments[i].m_storeOp = static_cast<U32>(inAtt.m_storeOperation);
 			memcpy(&colorAttachments[i].m_clearColor[0], &inAtt.m_clearValue.m_coloru[0], sizeof(U32) * 4);
 		}
 
-		m_hash = computeHash(&colorAttachments[0], sizeof(ColorAttachment) * m_fbInitInfo.m_colorAttachmentCount);
+		m_hash = computeHash(&colorAttachments[0], sizeof(ColorAttachment) * m_colorAttachmentCount);
 	}
 
 	// DS attachment
-	if(!!m_fbInitInfo.m_depthStencilAttachment.m_aspect)
+	if(!!m_depthStencilAttachment.m_aspect)
 	{
 		ANKI_BEGIN_PACKED_STRUCT
 		struct DSAttachment
@@ -228,7 +198,7 @@ void FramebufferDescription::bake()
 		} outAtt;
 		ANKI_END_PACKED_STRUCT
 
-		const FramebufferAttachmentInfo& inAtt = m_fbInitInfo.m_depthStencilAttachment;
+		const FramebufferDescriptionAttachment& inAtt = m_depthStencilAttachment;
 		const Bool hasDepth = !!(inAtt.m_aspect & DepthStencilAspectBit::DEPTH);
 		const Bool hasStencil = !!(inAtt.m_aspect & DepthStencilAspectBit::STENCIL);
 
@@ -354,9 +324,10 @@ TexturePtr RenderGraph::getOrCreateRenderTarget(const TextureInitInfo& initInf,
 }
 
 FramebufferPtr RenderGraph::getOrCreateFramebuffer(
-	const FramebufferInitInfo& fbInit_, const RenderTargetHandle* rtHandles, U64 hash)
+	const FramebufferDescription& fbDescr, const RenderTargetHandle* rtHandles)
 {
 	ANKI_ASSERT(rtHandles);
+	U64 hash = fbDescr.m_hash;
 	ANKI_ASSERT(hash > 0);
 
 	const Bool defaultFb = hash == 1;
@@ -366,12 +337,12 @@ FramebufferPtr RenderGraph::getOrCreateFramebuffer(
 		// Create a hash that includes the render targets
 		Array<U64, MAX_COLOR_ATTACHMENTS + 1> uuids;
 		U count = 0;
-		for(U i = 0; i < fbInit_.m_colorAttachmentCount; ++i)
+		for(U i = 0; i < fbDescr.m_colorAttachmentCount; ++i)
 		{
 			uuids[count++] = m_ctx->m_rts[rtHandles[i].m_idx].m_texture->getUuid();
 		}
 
-		if(!!fbInit_.m_depthStencilAttachment.m_aspect)
+		if(!!fbDescr.m_depthStencilAttachment.m_aspect)
 		{
 			uuids[count++] = m_ctx->m_rts[rtHandles[MAX_COLOR_ATTACHMENTS].m_idx].m_texture->getUuid();
 		}
@@ -388,22 +359,52 @@ FramebufferPtr RenderGraph::getOrCreateFramebuffer(
 	else
 	{
 		// Create a complete fb init info
-		FramebufferInitInfo fbInit = fbInit_;
+		FramebufferInitInfo fbInit("RenderGraph");
 		if(!defaultFb)
 		{
+			fbInit.m_colorAttachmentCount = fbDescr.m_colorAttachmentCount;
 			for(U i = 0; i < fbInit.m_colorAttachmentCount; ++i)
 			{
-				fbInit.m_colorAttachments[i].m_texture = m_ctx->m_rts[rtHandles[i].m_idx].m_texture;
-				ANKI_ASSERT(fbInit.m_colorAttachments[i].m_texture.isCreated());
+				FramebufferAttachmentInfo& outAtt = fbInit.m_colorAttachments[i];
+				const FramebufferDescriptionAttachment& inAtt = fbDescr.m_colorAttachments[i];
+
+				outAtt.m_clearValue = inAtt.m_clearValue;
+				outAtt.m_loadOperation = inAtt.m_loadOperation;
+				outAtt.m_storeOperation = inAtt.m_storeOperation;
+
+				// Create texture view
+				TextureViewInitInfo viewInit(m_ctx->m_rts[rtHandles[i].m_idx].m_texture,
+					TextureSubresourceInfo::newFromSurface(inAtt.m_surface),
+					"RenderGraph");
+				TextureViewPtr view = getManager().newTextureView(viewInit);
+
+				outAtt.m_textureView = view;
 			}
 
-			if(!!fbInit.m_depthStencilAttachment.m_aspect)
+			if(!!fbDescr.m_depthStencilAttachment.m_aspect)
 			{
-				fbInit.m_depthStencilAttachment.m_texture =
-					m_ctx->m_rts[rtHandles[MAX_COLOR_ATTACHMENTS].m_idx].m_texture;
-				ANKI_ASSERT(fbInit.m_depthStencilAttachment.m_texture.isCreated());
+				FramebufferAttachmentInfo& outAtt = fbInit.m_depthStencilAttachment;
+				const FramebufferDescriptionAttachment& inAtt = fbDescr.m_depthStencilAttachment;
+
+				outAtt.m_clearValue = inAtt.m_clearValue;
+				outAtt.m_loadOperation = inAtt.m_loadOperation;
+				outAtt.m_storeOperation = inAtt.m_storeOperation;
+				outAtt.m_stencilLoadOperation = inAtt.m_stencilLoadOperation;
+				outAtt.m_stencilStoreOperation = inAtt.m_stencilStoreOperation;
+
+				// Create texture view
+				TextureViewInitInfo viewInit(m_ctx->m_rts[rtHandles[MAX_COLOR_ATTACHMENTS].m_idx].m_texture,
+					TextureSubresourceInfo::newFromSurface(inAtt.m_surface, inAtt.m_aspect),
+					"RenderGraph");
+				TextureViewPtr view = getManager().newTextureView(viewInit);
+
+				outAtt.m_textureView = view;
 			}
 		}
+		else
+		{
+			fbInit.m_colorAttachmentCount = 1;
+		}
 
 		fb = getManager().newFramebuffer(fbInit);
 
@@ -616,32 +617,31 @@ void RenderGraph::initRenderPassesAndSetDeps(const RenderGraphDescription& descr
 
 			if(graphicsPass.hasFramebuffer())
 			{
-				outPass.fb() = getOrCreateFramebuffer(
-					graphicsPass.m_fbInitInfo, &graphicsPass.m_rtHandles[0], graphicsPass.m_fbHash);
+				outPass.fb() = getOrCreateFramebuffer(graphicsPass.m_fbDescr, &graphicsPass.m_rtHandles[0]);
 
 				outPass.m_fbRenderArea = graphicsPass.m_fbRenderArea;
 
 				// Init the usage bits
-				if(graphicsPass.m_fbHash != 1)
+				if(graphicsPass.m_fbDescr.m_hash != 1)
 				{
 					TextureUsageBit usage;
 
-					for(U i = 0; i < graphicsPass.m_fbInitInfo.m_colorAttachmentCount; ++i)
+					for(U i = 0; i < graphicsPass.m_fbDescr.m_colorAttachmentCount; ++i)
 					{
 						getCrntUsage(graphicsPass.m_rtHandles[i],
 							passIdx,
 							TextureSubresourceInfo::newFromSurface(
-								graphicsPass.m_fbInitInfo.m_colorAttachments[i].m_surface),
+								graphicsPass.m_fbDescr.m_colorAttachments[i].m_surface),
 							usage);
 
 						outPass.m_colorUsages[i] = usage;
 					}
 
-					if(!!graphicsPass.m_fbInitInfo.m_depthStencilAttachment.m_aspect)
+					if(!!graphicsPass.m_fbDescr.m_depthStencilAttachment.m_aspect)
 					{
 						TextureSubresourceInfo subresource = TextureSubresourceInfo::newFromSurface(
-							graphicsPass.m_fbInitInfo.m_depthStencilAttachment.m_surface,
-							graphicsPass.m_fbInitInfo.m_depthStencilAttachment.m_aspect);
+							graphicsPass.m_fbDescr.m_depthStencilAttachment.m_surface,
+							graphicsPass.m_fbDescr.m_depthStencilAttachment.m_aspect);
 
 						getCrntUsage(graphicsPass.m_rtHandles[MAX_COLOR_ATTACHMENTS], passIdx, subresource, usage);
 

+ 6 - 14
src/anki/gr/RenderGraph.h

@@ -324,6 +324,7 @@ public:
 class FramebufferDescription
 {
 	friend class GraphicsRenderPassDescription;
+	friend class RenderGraph;
 
 public:
 	Array<FramebufferDescriptionAttachment, MAX_COLOR_ATTACHMENTS> m_colorAttachments;
@@ -344,7 +345,6 @@ public:
 	}
 
 private:
-	FramebufferInitInfo m_fbInitInfo;
 	Bool8 m_defaultFb = false;
 
 	U64 m_hash = 0;
@@ -391,26 +391,19 @@ public:
 		}
 #endif
 
-		if(fbInfo.m_defaultFb)
-		{
-			m_fbInitInfo.m_colorAttachmentCount = 1;
-		}
-		else
+		m_fbDescr = fbInfo;
+		if(!fbInfo.m_defaultFb)
 		{
-			m_fbInitInfo = fbInfo.m_fbInitInfo;
 			memcpy(&m_rtHandles[0], &colorRenderTargetHandles[0], sizeof(colorRenderTargetHandles));
 			m_rtHandles[MAX_COLOR_ATTACHMENTS] = depthStencilRenderTargetHandle;
 		}
-		m_fbInitInfo.setName(m_name.toCString());
-		m_fbHash = fbInfo.m_hash;
 		m_fbRenderArea = {{minx, miny, maxx, maxy}};
 	}
 
 private:
 	Array<RenderTargetHandle, MAX_COLOR_ATTACHMENTS + 1> m_rtHandles;
-	FramebufferInitInfo m_fbInitInfo;
+	FramebufferDescription m_fbDescr;
 	Array<U32, 4> m_fbRenderArea = {};
-	U64 m_fbHash = 0;
 
 	GraphicsRenderPassDescription(RenderGraphDescription* descr)
 		: RenderPassDescriptionBase(Type::GRAPHICS, descr)
@@ -420,7 +413,7 @@ private:
 
 	Bool hasFramebuffer() const
 	{
-		return m_fbHash != 0;
+		return m_fbDescr.m_hash != 0;
 	}
 };
 
@@ -644,8 +637,7 @@ private:
 	void setBatchBarriers(const RenderGraphDescription& descr);
 
 	TexturePtr getOrCreateRenderTarget(const TextureInitInfo& initInf, U64 hash);
-	FramebufferPtr getOrCreateFramebuffer(
-		const FramebufferInitInfo& fbInit, const RenderTargetHandle* rtHandles, U64 hash);
+	FramebufferPtr getOrCreateFramebuffer(const FramebufferDescription& fbDescr, const RenderTargetHandle* rtHandles);
 
 	ANKI_HOT Bool passADependsOnB(const RenderPassDescriptionBase& a, const RenderPassDescriptionBase& b) const;
 

+ 0 - 5
src/anki/gr/common/Misc.cpp

@@ -89,11 +89,6 @@ Bool textureInitInfoValid(const TextureInitInfo& inf)
 #undef ANKI_CHECK_VAL_VALIDITY
 }
 
-Bool framebufferInitInfoValid(const FramebufferInitInfo& inf)
-{
-	return inf.m_colorAttachmentCount != 0 || inf.m_depthStencilAttachment.m_texture.isCreated();
-}
-
 void getFormatInfo(const PixelFormat& fmt, U& texelComponents, U& texelBytes, U& blockSize, U& blockBytes)
 {
 	blockSize = 0;

+ 0 - 2
src/anki/gr/common/Misc.h

@@ -41,8 +41,6 @@ inline void checkTextureSurface(TextureType type, U depth, U mipCount, U layerCo
 /// Check the validity of the structure.
 Bool textureInitInfoValid(const TextureInitInfo& inf);
 
-Bool framebufferInitInfoValid(const FramebufferInitInfo& inf);
-
 /// Compute the size of a single surface.
 void getFormatInfo(const PixelFormat& fmt, U& texelComponents, U& texelBytes, U& blockSize, U& blockBytes);
 

+ 10 - 10
src/anki/gr/vulkan/CommandBufferImpl.cpp

@@ -76,16 +76,16 @@ void CommandBufferImpl::beginRecording()
 		Array<VkImageLayout, MAX_COLOR_ATTACHMENTS> colAttLayouts;
 		for(U i = 0; i < impl.getColorAttachmentCount(); ++i)
 		{
-			colAttLayouts[i] = static_cast<const TextureImpl&>(
-				*impl.getColorAttachment(
-					i)).computeLayout(m_colorAttachmentUsages[i], 0);
+			const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*impl.getColorAttachment(i));
+			colAttLayouts[i] =
+				static_cast<const TextureImpl&>(*view.m_tex).computeLayout(m_colorAttachmentUsages[i], 0);
 		}
 
 		VkImageLayout dsAttLayout = VK_IMAGE_LAYOUT_MAX_ENUM;
 		if(impl.hasDepthStencil())
 		{
-			dsAttLayout = static_cast<const TextureImpl&>(*impl.getDepthStencilAttachment())
-							  .computeLayout(m_depthStencilAttachmentUsage, 0);
+			const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*impl.getDepthStencilAttachment());
+			dsAttLayout = static_cast<const TextureImpl&>(*view.m_tex).computeLayout(m_depthStencilAttachmentUsage, 0);
 		}
 
 		inheritance.renderPass = impl.getRenderPassHandle(colAttLayouts, dsAttLayout);
@@ -178,16 +178,16 @@ void CommandBufferImpl::beginRenderPassInternal()
 		Array<VkImageLayout, MAX_COLOR_ATTACHMENTS> colAttLayouts;
 		for(U i = 0; i < impl.getColorAttachmentCount(); ++i)
 		{
-			colAttLayouts[i] = static_cast<const TextureImpl&>(
-				*impl.getColorAttachment(
-					i)).computeLayout(m_colorAttachmentUsages[i], 0);
+			const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*impl.getColorAttachment(i));
+			colAttLayouts[i] =
+				static_cast<const TextureImpl&>(*view.m_tex).computeLayout(m_colorAttachmentUsages[i], 0);
 		}
 
 		VkImageLayout dsAttLayout = VK_IMAGE_LAYOUT_MAX_ENUM;
 		if(impl.hasDepthStencil())
 		{
-			dsAttLayout = static_cast<const TextureImpl&>(*impl.getDepthStencilAttachment())
-							  .computeLayout(m_depthStencilAttachmentUsage, 0);
+			const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*impl.getDepthStencilAttachment());
+			dsAttLayout = static_cast<const TextureImpl&>(*view.m_tex).computeLayout(m_depthStencilAttachmentUsage, 0);
 		}
 
 		bi.renderPass = impl.getRenderPassHandle(colAttLayouts, dsAttLayout);

+ 19 - 31
src/anki/gr/vulkan/FramebufferImpl.cpp

@@ -35,6 +35,8 @@ FramebufferImpl::~FramebufferImpl()
 
 Error FramebufferImpl::init(const FramebufferInitInfo& init)
 {
+	ANKI_ASSERT(init.isValid());
+
 	// Init common
 	m_defaultFb = init.refersToDefaultFramebuffer();
 	strcpy(&m_name[0], (init.getName()) ? init.getName().cstr() : "");
@@ -45,27 +47,9 @@ Error FramebufferImpl::init(const FramebufferInitInfo& init)
 		m_colorAttCount = i + 1;
 	}
 
-	if(!m_defaultFb && init.m_depthStencilAttachment.m_texture)
+	if(!m_defaultFb && init.m_depthStencilAttachment.m_textureView)
 	{
-		const TextureImpl& tex = static_cast<const TextureImpl&>(*init.m_depthStencilAttachment.m_texture);
-
-		if(!!(tex.m_workarounds & TextureImplWorkaround::S8_TO_D24S8))
-		{
-			m_aspect = DepthStencilAspectBit::STENCIL;
-		}
-		else if(tex.m_aspect == DepthStencilAspectBit::DEPTH)
-		{
-			m_aspect = DepthStencilAspectBit::DEPTH;
-		}
-		else if(tex.m_aspect == DepthStencilAspectBit::STENCIL)
-		{
-			m_aspect = DepthStencilAspectBit::STENCIL;
-		}
-		else
-		{
-			ANKI_ASSERT(!!init.m_depthStencilAttachment.m_aspect);
-			m_aspect = init.m_depthStencilAttachment.m_aspect;
-		}
+		m_aspect = init.m_depthStencilAttachment.m_textureView->getDepthStencilAspect();
 	}
 
 	initClearValues(init);
@@ -140,33 +124,37 @@ Error FramebufferImpl::initFbs(const FramebufferInitInfo& init)
 	for(U i = 0; i < init.m_colorAttachmentCount; ++i)
 	{
 		const FramebufferAttachmentInfo& att = init.m_colorAttachments[i];
-		const TextureImpl& tex = static_cast<const TextureImpl&>(*att.m_texture);
+		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*att.m_textureView);
+		ANKI_ASSERT(view.isSingleSurface());
+		const TextureImpl& tex = static_cast<const TextureImpl&>(*view.m_tex);
 
-		imgViews[count++] = tex.getOrCreateSingleSurfaceView(att.m_surface, att.m_aspect);
+		imgViews[count++] = view.m_handle;
 
 		if(m_noDflt.m_width == 0)
 		{
-			m_noDflt.m_width = tex.getWidth() >> att.m_surface.m_level;
-			m_noDflt.m_height = tex.getHeight() >> att.m_surface.m_level;
+			m_noDflt.m_width = tex.getWidth() >> view.getBaseMipmap();
+			m_noDflt.m_height = tex.getHeight() >> view.getBaseMipmap();
 		}
 
-		m_noDflt.m_refs[i] = att.m_texture;
+		m_noDflt.m_refs[i] = att.m_textureView;
 	}
 
 	if(hasDepthStencil())
 	{
 		const FramebufferAttachmentInfo& att = init.m_depthStencilAttachment;
-		const TextureImpl& tex = static_cast<const TextureImpl&>(*att.m_texture);
+		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*att.m_textureView);
+		ANKI_ASSERT(view.isSingleSurface());
+		const TextureImpl& tex = static_cast<const TextureImpl&>(*view.m_tex);
 
-		imgViews[count++] = tex.getOrCreateSingleSurfaceView(att.m_surface, m_aspect);
+		imgViews[count++] = view.m_handle;
 
 		if(m_noDflt.m_width == 0)
 		{
-			m_noDflt.m_width = tex.getWidth() >> att.m_surface.m_level;
-			m_noDflt.m_height = tex.getHeight() >> att.m_surface.m_level;
+			m_noDflt.m_width = tex.getWidth() >> view.getBaseMipmap();
+			m_noDflt.m_height = tex.getHeight() >> view.getBaseMipmap();
 		}
 
-		m_noDflt.m_refs[MAX_COLOR_ATTACHMENTS] = att.m_texture;
+		m_noDflt.m_refs[MAX_COLOR_ATTACHMENTS] = att.m_textureView;
 	}
 
 	ci.width = m_noDflt.m_width;
@@ -186,7 +174,7 @@ void FramebufferImpl::setupAttachmentDescriptor(
 	const FramebufferAttachmentInfo& att, VkAttachmentDescription& desc, VkImageLayout layout) const
 {
 	desc = {};
-	desc.format = convertFormat(att.m_texture->getPixelFormat());
+	desc.format = convertFormat(static_cast<const TextureViewImpl&>(*att.m_textureView).m_tex->getPixelFormat());
 	desc.samples = VK_SAMPLE_COUNT_1_BIT;
 	desc.loadOp = convertLoadOp(att.m_loadOperation);
 	desc.storeOp = convertStoreOp(att.m_storeOperation);

+ 3 - 3
src/anki/gr/vulkan/FramebufferImpl.h

@@ -89,13 +89,13 @@ public:
 		return m_colorAttCount + (hasDepthStencil() ? 1 : 0);
 	}
 
-	TexturePtr getColorAttachment(U att) const
+	TextureViewPtr getColorAttachment(U att) const
 	{
 		ANKI_ASSERT(m_noDflt.m_refs[att].get());
 		return m_noDflt.m_refs[att];
 	}
 
-	TexturePtr getDepthStencilAttachment() const
+	TextureViewPtr getDepthStencilAttachment() const
 	{
 		ANKI_ASSERT(m_noDflt.m_refs[MAX_COLOR_ATTACHMENTS].get());
 		return m_noDflt.m_refs[MAX_COLOR_ATTACHMENTS];
@@ -150,7 +150,7 @@ private:
 		U32 m_width = 0;
 		U32 m_height = 0;
 
-		Array<TexturePtr, MAX_COLOR_ATTACHMENTS + 1> m_refs; ///< @note The pos of every attachment is fixed.
+		Array<TextureViewPtr, MAX_COLOR_ATTACHMENTS + 1> m_refs; ///< @note The pos of every attachment is fixed.
 
 		// RenderPass create info
 		VkRenderPassCreateInfo m_rpassCi = {};

+ 5 - 0
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -564,6 +564,11 @@ Error GrManagerImpl::initMemory(const ConfigSet& cfg)
 void* GrManagerImpl::allocateCallback(
 	void* userData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
 {
+	if(ANKI_UNLIKELY(size == 0))
+	{
+		return nullptr;
+	}
+
 	ANKI_ASSERT(userData);
 	ANKI_ASSERT(size);
 	ANKI_ASSERT(isPowerOfTwo(alignment));

+ 0 - 24
src/anki/gr/vulkan/TextureImpl.cpp

@@ -650,30 +650,6 @@ VkImageLayout TextureImpl::computeLayout(TextureUsageBit usage, U level) const
 	return out;
 }
 
-VkImageView TextureImpl::getOrCreateSingleLevelView(U32 mip, DepthStencilAspectBit aspect) const
-{
-	ANKI_ASSERT(mip < m_mipCount);
-
-	VkImageViewCreateInfo ci = m_viewCreateInfoTemplate;
-	ci.subresourceRange.baseMipLevel = mip;
-	ci.subresourceRange.levelCount = 1;
-	ci.subresourceRange.aspectMask = convertImageAspect(aspect);
-
-	return getOrCreateView(ci);
-}
-
-VkImageView TextureImpl::getOrCreateSingleSurfaceView(
-	const TextureSurfaceInfo& surf, DepthStencilAspectBit aspect) const
-{
-	checkSurfaceOrVolume(surf);
-
-	VkImageViewCreateInfo ci = m_viewCreateInfoTemplate;
-	ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
-	computeSubResourceRange(surf, aspect, ci.subresourceRange);
-
-	return getOrCreateView(ci);
-}
-
 VkImageView TextureImpl::getOrCreateResourceGroupView(DepthStencilAspectBit aspect) const
 {
 	VkImageViewCreateInfo ci = m_viewCreateInfoTemplate;

+ 4 - 15
src/anki/gr/vulkan/TextureImpl.h

@@ -45,6 +45,8 @@ public:
 
 	TextureImplWorkaround m_workarounds = TextureImplWorkaround::NONE;
 
+	VkImageViewCreateInfo m_viewCreateInfoTemplate;
+
 	TextureImpl(GrManager* manager)
 		: Texture(manager)
 	{
@@ -89,11 +91,6 @@ public:
 		return (usage & m_usage) == usage;
 	}
 
-	/// For image load/store.
-	VkImageView getOrCreateSingleLevelView(U32 mip, DepthStencilAspectBit aspect) const;
-
-	VkImageView getOrCreateSingleSurfaceView(const TextureSurfaceInfo& surf, DepthStencilAspectBit aspect) const;
-
 	/// That view will be used in descriptor sets.
 	VkImageView getOrCreateResourceGroupView(DepthStencilAspectBit aspect) const;
 
@@ -117,13 +114,6 @@ public:
 		ANKI_ASSERT(range.baseMipLevel + range.levelCount <= m_mipCount);
 	}
 
-	VkImageView getOrCreateView(const VkImageSubresourceRange& range) const
-	{
-		VkImageViewCreateInfo viewCi = m_viewCreateInfoTemplate;
-		viewCi.subresourceRange = range;
-		return getOrCreateView(viewCi);
-	}
-
 	void computeSubresourceRange(const TextureSubresourceInfo& in, VkImageSubresourceRange& range) const
 	{
 		ANKI_ASSERT(isSubresourceValid(in));
@@ -137,6 +127,8 @@ public:
 		range.layerCount = in.m_layerCount * in.m_faceCount;
 	}
 
+	VkImageView getOrCreateView(const VkImageViewCreateInfo& ci) const;
+
 private:
 	class ViewHasher
 	{
@@ -149,7 +141,6 @@ private:
 
 	mutable HashMap<VkImageViewCreateInfo, VkImageView, ViewHasher> m_viewsMap;
 	mutable Mutex m_viewsMapMtx;
-	VkImageViewCreateInfo m_viewCreateInfoTemplate;
 
 	VkDeviceMemory m_dedicatedMem = VK_NULL_HANDLE;
 
@@ -163,8 +154,6 @@ private:
 
 	ANKI_USE_RESULT Error initImage(const TextureInitInfo& init);
 
-	VkImageView getOrCreateView(const VkImageViewCreateInfo& ci) const;
-
 	U computeSubresourceIdx(const TextureSurfaceInfo& surf) const;
 
 	U computeSubresourceIdx(const TextureVolumeInfo& vol) const

+ 21 - 6
src/anki/gr/vulkan/TextureViewImpl.cpp

@@ -26,18 +26,33 @@ Error TextureViewImpl::init(const TextureViewInitInfo& inf)
 	m_baseFace = inf.m_baseFace;
 	m_faceCount = inf.m_faceCount;
 	m_subresource = inf;
-	// TODO Set m_texType
 
 	m_tex = inf.m_texture;
-
 	const TextureImpl& tex = static_cast<const TextureImpl&>(*m_tex);
+	ANKI_ASSERT(tex.isSubresourceValid(inf));
+
+	m_texType = tex.getTextureType();
+
+	// Compute the VkImageViewCreateInfo
+	VkImageViewCreateInfo viewCi;
+	memcpy(&viewCi, &tex.m_viewCreateInfoTemplate, sizeof(viewCi)); // Memcpy because it will be hashed
+	viewCi.subresourceRange.aspectMask = convertImageAspect(m_aspect);
+	viewCi.subresourceRange.baseMipLevel = inf.m_baseMipmap;
+	viewCi.subresourceRange.levelCount = inf.m_mipmapCount;
+
+	const U faceCount = textureTypeIsCube(tex.getTextureType()) ? 6 : 1;
+	viewCi.subresourceRange.baseArrayLayer = inf.m_baseLayer * faceCount + inf.m_baseFace;
+	viewCi.subresourceRange.layerCount = inf.m_layerCount * inf.m_faceCount;
 
-	// Compute the VK range
-	VkImageSubresourceRange range;
-	tex.computeSubresourceRange(inf, range);
+	// Fixup the image view type
+	if(textureTypeIsCube(m_texType) && inf.m_faceCount != 6)
+	{
+		m_texType = TextureType::_2D;
+		viewCi.viewType = VK_IMAGE_VIEW_TYPE_2D;
+	}
 
 	// Ask the texture for a view
-	m_handle = tex.getOrCreateView(range);
+	m_handle = tex.getOrCreateView(viewCi);
 
 	// Create the hash
 	Array<U64, 2> toHash = {{tex.getUuid(), ptrToNumber(m_handle)}};

+ 20 - 8
src/anki/renderer/Renderer.cpp

@@ -364,23 +364,35 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, cons
 				Array<TextureUsageBit, MAX_COLOR_ATTACHMENTS> colUsage = {};
 				TextureUsageBit dsUsage = TextureUsageBit::NONE;
 
-				if(inf.m_format.m_components >= ComponentFormat::FIRST_DEPTH_STENCIL
-					&& inf.m_format.m_components <= ComponentFormat::LAST_DEPTH_STENCIL)
+				if(componentFormatIsDepthStencil(inf.m_format.m_components))
 				{
-					fbInit.m_depthStencilAttachment.m_texture = tex;
-					fbInit.m_depthStencilAttachment.m_surface = surf;
-					fbInit.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH_STENCIL;
+					DepthStencilAspectBit aspect = DepthStencilAspectBit::NONE;
+					if(componentFormatIsDepth(inf.m_format.m_components))
+					{
+						aspect |= DepthStencilAspectBit::DEPTH;
+					}
+
+					if(componentFormatIsStencil(inf.m_format.m_components))
+					{
+						aspect |= DepthStencilAspectBit::STENCIL;
+					}
+
+					TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf, aspect));
+
+					fbInit.m_depthStencilAttachment.m_textureView = view;
 					fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::CLEAR;
+					fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
+					fbInit.m_depthStencilAttachment.m_clearValue = clearVal;
 
 					dsUsage = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
 				}
 				else
 				{
+					TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
+
 					fbInit.m_colorAttachmentCount = 1;
-					fbInit.m_colorAttachments[0].m_texture = tex;
-					fbInit.m_colorAttachments[0].m_surface = surf;
+					fbInit.m_colorAttachments[0].m_textureView = view;
 					fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
-					fbInit.m_colorAttachments[0].m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
 					fbInit.m_colorAttachments[0].m_clearValue = clearVal;
 
 					colUsage[0] = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;