瀏覽代碼

[REFACTOR] Minor improvements to texture views

Panagiotis Christopoulos Charitos 8 年之前
父節點
當前提交
744248d80c

+ 8 - 2
src/anki/gr/Common.h

@@ -231,15 +231,21 @@ public:
 	{
 	}
 
-	TextureSubresourceInfo(const TextureVolumeInfo& vol)
+	TextureSubresourceInfo(const TextureVolumeInfo& vol, DepthStencilAspectBit aspect = DepthStencilAspectBit::NONE)
 		: m_baseMipmap(vol.m_level)
 		, m_mipmapCount(1)
 		, m_baseLayer(0)
 		, m_layerCount(1)
 		, m_baseFace(0)
 		, m_faceCount(1)
-		, m_depthStencilAspect(DepthStencilAspectBit::NONE)
+		, m_depthStencilAspect(aspect)
+	{
+	}
+
+	U64 computeHash() const
 	{
+		static_assert(sizeof(*this) == sizeof(U32) * 4 + sizeof(U8) * 4, "Should be hashable");
+		return anki::computeHash(this, sizeof(*this));
 	}
 };
 

+ 5 - 3
src/anki/gr/vulkan/CommandBufferImpl.cpp

@@ -302,7 +302,7 @@ void CommandBufferImpl::generateMipmaps2d(TextureViewPtr texView)
 	const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*texView);
 	const TextureImpl& tex = static_cast<const TextureImpl&>(*view.m_tex);
 	ANKI_ASSERT(tex.getTextureType() != TextureType::_3D && "Not for 3D");
-	ANKI_ASSERT(tex.isSubresourceGoodForMipmapGeneration(view.m_subresource));
+	ANKI_ASSERT(tex.isSubresourceGoodForMipmapGeneration(view.getSubresource()));
 
 	const DepthStencilAspectBit aspect = view.getDepthStencilAspect();
 	const U face = view.getBaseFace();
@@ -314,7 +314,8 @@ void CommandBufferImpl::generateMipmaps2d(TextureViewPtr texView)
 		if(i > 0)
 		{
 			VkImageSubresourceRange range;
-			tex.computeSubResourceRange(TextureSurfaceInfo(i, 0, face, layer), aspect, range);
+			tex.computeVkImageSubresourceRange(
+				TextureSubresourceInfo(TextureSurfaceInfo(i, 0, face, layer), aspect), range);
 
 			setImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
 				VK_ACCESS_TRANSFER_WRITE_BIT,
@@ -329,7 +330,8 @@ void CommandBufferImpl::generateMipmaps2d(TextureViewPtr texView)
 		// Transition destination
 		{
 			VkImageSubresourceRange range;
-			tex.computeSubResourceRange(TextureSurfaceInfo(i + 1, 0, face, layer), aspect, range);
+			tex.computeVkImageSubresourceRange(
+				TextureSubresourceInfo(TextureSurfaceInfo(i + 1, 0, face, layer), aspect), range);
 
 			setImageBarrier(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
 				0,

+ 1 - 1
src/anki/gr/vulkan/CommandBufferImpl.h

@@ -226,7 +226,7 @@ public:
 		const U realBinding = binding;
 		const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*texView);
 		const TextureImpl& tex = static_cast<const TextureImpl&>(*view.m_tex);
-		ANKI_ASSERT(tex.isSubresourceGoodForSampling(view.m_subresource));
+		ANKI_ASSERT(tex.isSubresourceGoodForSampling(view.getSubresource()));
 		const VkImageLayout lay = tex.computeLayout(usage, 0);
 
 		m_dsetState[set].bindTextureAndSampler(realBinding, &view, sampler.get(), lay);

+ 6 - 6
src/anki/gr/vulkan/CommandBufferImpl.inl.h

@@ -167,7 +167,7 @@ inline void CommandBufferImpl::setTextureBarrier(
 	ANKI_ASSERT(tex->isSubresourceValid(subresource));
 
 	VkImageSubresourceRange range;
-	impl.computeSubresourceRange(subresource, range);
+	impl.computeVkImageSubresourceRange(subresource, range);
 	setTextureBarrierRange(tex, prevUsage, nextUsage, range);
 }
 
@@ -184,7 +184,7 @@ inline void CommandBufferImpl::setTextureSurfaceBarrier(
 	impl.checkSurfaceOrVolume(surf);
 
 	VkImageSubresourceRange range;
-	impl.computeSubResourceRange(surf, impl.getDepthStencilAspect(), range);
+	impl.computeVkImageSubresourceRange(TextureSubresourceInfo(surf, impl.getDepthStencilAspect()), range);
 	setTextureBarrierRange(tex, prevUsage, nextUsage, range);
 }
 
@@ -201,7 +201,7 @@ inline void CommandBufferImpl::setTextureVolumeBarrier(
 	impl.checkSurfaceOrVolume(vol);
 
 	VkImageSubresourceRange range;
-	impl.computeSubResourceRange(vol, impl.getDepthStencilAspect(), range);
+	impl.computeVkImageSubresourceRange(TextureSubresourceInfo(vol, impl.getDepthStencilAspect()), range);
 	setTextureBarrierRange(tex, prevUsage, nextUsage, range);
 }
 
@@ -411,9 +411,9 @@ inline void CommandBufferImpl::clearTextureView(TextureViewPtr texView, const Cl
 
 	if(!view.getDepthStencilAspect())
 	{
-		ANKI_CMD(
-			vkCmdClearColorImage(
-				m_handle, tex.m_imageHandle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &vclear, 1, &view.m_vkSubresource),
+		VkImageSubresourceRange vkRange = view.getVkImageSubresourceRange();
+		ANKI_CMD(vkCmdClearColorImage(
+					 m_handle, tex.m_imageHandle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &vclear, 1, &vkRange),
 			ANY_OTHER_COMMAND);
 	}
 	else

+ 2 - 2
src/anki/gr/vulkan/DescriptorSet.h

@@ -109,7 +109,7 @@ public:
 	void bindTextureAndSampler(U binding, const TextureView* texView, const Sampler* sampler, VkImageLayout layout)
 	{
 		const TextureViewImpl& viewImpl = static_cast<const TextureViewImpl&>(*texView);
-		ANKI_ASSERT(viewImpl.m_tex->isSubresourceGoodForSampling(viewImpl.m_subresource));
+		ANKI_ASSERT(viewImpl.m_tex->isSubresourceGoodForSampling(viewImpl.getSubresource()));
 
 		AnyBinding& b = m_bindings[binding];
 		b = {};
@@ -158,7 +158,7 @@ public:
 	{
 		ANKI_ASSERT(texView);
 		const TextureViewImpl* impl = static_cast<const TextureViewImpl*>(texView);
-		ANKI_ASSERT(impl->m_tex->isSubresourceGoodForImageLoadStore(impl->m_subresource));
+		ANKI_ASSERT(impl->m_tex->isSubresourceGoodForImageLoadStore(impl->getSubresource()));
 
 		AnyBinding& b = m_bindings[binding];
 		b = {};

+ 11 - 12
src/anki/gr/vulkan/TextureImpl.cpp

@@ -655,31 +655,30 @@ VkImageLayout TextureImpl::computeLayout(TextureUsageBit usage, U level) const
 	return out;
 }
 
-VkImageView TextureImpl::getOrCreateResourceGroupView(DepthStencilAspectBit aspect) const
-{
-	VkImageViewCreateInfo ci = m_viewCreateInfoTemplate;
-	ci.subresourceRange.aspectMask = convertImageAspect(aspect);
-
-	return getOrCreateView(ci);
-}
-
-VkImageView TextureImpl::getOrCreateView(const VkImageViewCreateInfo& ci) const
+VkImageView TextureImpl::getOrCreateView(const TextureSubresourceInfo& subresource, TextureType& newTexType) const
 {
 	LockGuard<Mutex> lock(m_viewsMapMtx);
-	auto it = m_viewsMap.find(ci);
+	auto it = m_viewsMap.find(subresource);
 
 	if(it != m_viewsMap.getEnd())
 	{
+		// Fixup the image view type
+		newTexType = computeNewTexTypeOfSubresource(subresource);
+
 		return *it;
 	}
 	else
 	{
+		// Compute the VkImageViewCreateInfo
+		VkImageViewCreateInfo viewCi;
+		computeVkImageViewCreateInfo(subresource, viewCi, newTexType);
+
 		VkImageView view = VK_NULL_HANDLE;
-		ANKI_VK_CHECKF(vkCreateImageView(getDevice(), &ci, nullptr, &view));
+		ANKI_VK_CHECKF(vkCreateImageView(getDevice(), &viewCi, nullptr, &view));
 		getGrManagerImpl().trySetVulkanHandleName(
 			(m_name[0]) ? &m_name[0] : CString(), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, ptrToNumber(view));
 
-		m_viewsMap.emplace(getAllocator(), ci, view);
+		m_viewsMap.emplace(getAllocator(), subresource, view);
 
 		return view;
 	}

+ 26 - 28
src/anki/gr/vulkan/TextureImpl.h

@@ -71,12 +71,6 @@ public:
 		ANKI_ASSERT(vol.m_level < m_mipCount);
 	}
 
-	void computeSubResourceRange(
-		const TextureSurfaceInfo& surf, DepthStencilAspectBit aspect, VkImageSubresourceRange& range) const;
-
-	void computeSubResourceRange(
-		const TextureVolumeInfo& vol, DepthStencilAspectBit aspect, VkImageSubresourceRange& range) const;
-
 	/// Compute the layer as defined by Vulkan.
 	U computeVkArrayLayer(const TextureSurfaceInfo& surf) const;
 
@@ -90,9 +84,6 @@ public:
 		return (usage & m_usage) == usage;
 	}
 
-	/// That view will be used in descriptor sets.
-	VkImageView getOrCreateResourceGroupView(DepthStencilAspectBit aspect) const;
-
 	/// By knowing the previous and new texture usage calculate the relavant info for a ppline barrier.
 	void computeBarrierInfo(TextureUsageBit before,
 		TextureUsageBit after,
@@ -105,19 +96,11 @@ public:
 	/// Predict the image layout.
 	VkImageLayout computeLayout(TextureUsageBit usage, U level) const;
 
-	void checkSubresourceRange(const VkImageSubresourceRange& range) const
-	{
-		ANKI_ASSERT(range.baseArrayLayer < m_layerCount);
-		ANKI_ASSERT(range.baseArrayLayer + range.layerCount <= m_layerCount);
-		ANKI_ASSERT(range.levelCount < m_mipCount);
-		ANKI_ASSERT(range.baseMipLevel + range.levelCount <= m_mipCount);
-	}
-
-	void computeSubresourceRange(const TextureSubresourceInfo& in, VkImageSubresourceRange& range) const
+	void computeVkImageSubresourceRange(const TextureSubresourceInfo& in, VkImageSubresourceRange& range) const
 	{
 		ANKI_ASSERT(isSubresourceValid(in));
 
-		range.aspectMask = convertImageAspect(in.m_depthStencilAspect & m_aspect);
+		range.aspectMask = convertImageAspect(in.m_depthStencilAspect);
 		range.baseMipLevel = in.m_baseMipmap;
 		range.levelCount = in.m_mipmapCount;
 
@@ -126,19 +109,27 @@ public:
 		range.layerCount = in.m_layerCount * in.m_faceCount;
 	}
 
-	VkImageView getOrCreateView(const VkImageViewCreateInfo& ci) const;
-
-private:
-	class ViewHasher
+	void computeVkImageViewCreateInfo(
+		const TextureSubresourceInfo& subresource, VkImageViewCreateInfo& viewCi, TextureType& newTextureType) const
 	{
-	public:
-		U64 operator()(const VkImageViewCreateInfo& b) const
+		ANKI_ASSERT(isSubresourceValid(subresource));
+
+		viewCi = m_viewCreateInfoTemplate;
+		computeVkImageSubresourceRange(subresource, viewCi.subresourceRange);
+
+		// Fixup the image view type
+		newTextureType = computeNewTexTypeOfSubresource(subresource);
+		if(newTextureType == TextureType::_2D)
 		{
-			return computeHash(&b, sizeof(b));
+			// Change that anyway
+			viewCi.viewType = VK_IMAGE_VIEW_TYPE_2D;
 		}
-	};
+	}
+
+	VkImageView getOrCreateView(const TextureSubresourceInfo& subresource, TextureType& newTexType) const;
 
-	mutable HashMap<VkImageViewCreateInfo, VkImageView, ViewHasher> m_viewsMap;
+private:
+	mutable HashMap<TextureSubresourceInfo, VkImageView> m_viewsMap;
 	mutable Mutex m_viewsMapMtx;
 
 	VkDeviceMemory m_dedicatedMem = VK_NULL_HANDLE;
@@ -166,6 +157,13 @@ private:
 		const TextureInfo& surfOrVol, TextureUsageBit usage, StackAllocator<U8>& alloc, TextureUsageState& state) const;
 
 	void updateUsageState(TextureUsageBit usage, StackAllocator<U8>& alloc, TextureUsageState& state) const;
+
+	/// Compute the new type of a texture view.
+	TextureType computeNewTexTypeOfSubresource(const TextureSubresourceInfo& subresource) const
+	{
+		ANKI_ASSERT(isSubresourceValid(subresource));
+		return (textureTypeIsCube(m_texType) && subresource.m_faceCount != 6) ? TextureType::_2D : m_texType;
+	}
 };
 /// @}
 

+ 0 - 42
src/anki/gr/vulkan/TextureImpl.inl.h

@@ -8,48 +8,6 @@
 namespace anki
 {
 
-inline void TextureImpl::computeSubResourceRange(
-	const TextureSurfaceInfo& surf, DepthStencilAspectBit aspect, VkImageSubresourceRange& range) const
-{
-	checkSurfaceOrVolume(surf);
-	range.aspectMask = convertImageAspect(m_aspect);
-	range.baseMipLevel = surf.m_level;
-	range.levelCount = 1;
-	switch(m_texType)
-	{
-	case TextureType::_2D:
-		range.baseArrayLayer = 0;
-		break;
-	case TextureType::_3D:
-		range.baseArrayLayer = 0;
-		break;
-	case TextureType::CUBE:
-		range.baseArrayLayer = surf.m_face;
-		break;
-	case TextureType::_2D_ARRAY:
-		range.baseArrayLayer = surf.m_layer;
-		break;
-	case TextureType::CUBE_ARRAY:
-		range.baseArrayLayer = surf.m_layer * 6 + surf.m_face;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		range.baseArrayLayer = 0;
-	}
-	range.layerCount = 1;
-}
-
-inline void TextureImpl::computeSubResourceRange(
-	const TextureVolumeInfo& vol, DepthStencilAspectBit aspect, VkImageSubresourceRange& range) const
-{
-	checkSurfaceOrVolume(vol);
-	range.aspectMask = convertImageAspect(m_aspect);
-	range.baseMipLevel = vol.m_level;
-	range.levelCount = 1;
-	range.baseArrayLayer = 0;
-	range.layerCount = 1;
-}
-
 inline U TextureImpl::computeVkArrayLayer(const TextureSurfaceInfo& surf) const
 {
 	checkSurfaceOrVolume(surf);

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

@@ -25,7 +25,6 @@ Error TextureViewImpl::init(const TextureViewInitInfo& inf)
 	m_layerCount = inf.m_layerCount;
 	m_baseFace = inf.m_baseFace;
 	m_faceCount = inf.m_faceCount;
-	m_subresource = inf;
 
 	m_tex = inf.m_texture;
 	const TextureImpl& tex = static_cast<const TextureImpl&>(*m_tex);
@@ -33,32 +32,13 @@ Error TextureViewImpl::init(const TextureViewInitInfo& 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;
-
-	// 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(viewCi);
+	m_handle = tex.getOrCreateView(inf, m_texType);
 
 	// Create the hash
 	Array<U64, 2> toHash = {{tex.getUuid(), ptrToNumber(m_handle)}};
 	m_hash = computeHash(&toHash[0], sizeof(toHash));
 
-	m_vkSubresource = viewCi.subresourceRange;
 	return Error::NONE;
 }
 

+ 21 - 2
src/anki/gr/vulkan/TextureViewImpl.h

@@ -7,6 +7,7 @@
 
 #include <anki/gr/TextureView.h>
 #include <anki/gr/vulkan/VulkanObject.h>
+#include <anki/gr/vulkan/TextureImpl.h>
 
 namespace anki
 {
@@ -20,8 +21,6 @@ class TextureViewImpl final : public TextureView, public VulkanObject<TextureVie
 public:
 	VkImageView m_handle = {};
 	TexturePtr m_tex; ///< Hold a reference.
-	TextureSubresourceInfo m_subresource;
-	VkImageSubresourceRange m_vkSubresource;
 
 	/// This is a hash that depends on the Texture and the VkImageView. It's used as a replacement of
 	/// TextureView::m_uuid since it creates less unique IDs.
@@ -35,6 +34,26 @@ public:
 	~TextureViewImpl();
 
 	ANKI_USE_RESULT Error init(const TextureViewInitInfo& inf);
+
+	TextureSubresourceInfo getSubresource() const
+	{
+		TextureSubresourceInfo out;
+		out.m_baseMipmap = m_baseMip;
+		out.m_mipmapCount = m_mipCount;
+		out.m_baseLayer = m_baseLayer;
+		out.m_layerCount = m_layerCount;
+		out.m_baseFace = m_baseFace;
+		out.m_faceCount = m_faceCount;
+		out.m_depthStencilAspect = m_aspect;
+		return out;
+	}
+
+	VkImageSubresourceRange getVkImageSubresourceRange() const
+	{
+		VkImageSubresourceRange out;
+		static_cast<const TextureImpl&>(*m_tex).computeVkImageSubresourceRange(getSubresource(), out);
+		return out;
+	}
 };
 /// @}