ソースを参照

[FEATURE] Add TextureView class on Vulkan

Panagiotis Christopoulos Charitos 8 年 前
コミット
4a56598d0a

+ 8 - 8
src/anki/collision/Frustum.cpp

@@ -211,17 +211,17 @@ Mat4 OrthographicFrustum::calculateProjectionMatrix() const
 void OrthographicFrustum::recalculate()
 {
 	// Planes
-	m_planesL[FrustumPlaneType::LEFT] = Plane(Vec4(1.0, 0.0, 0.0, 0.0), m_left);
-	m_planesL[FrustumPlaneType::RIGHT] = Plane(Vec4(-1.0, 0.0, 0.0, 0.0), -m_right);
+	m_planesL[FrustumPlaneType::LEFT] = Plane(Vec4(1.0f, 0.0f, 0.0f, 0.0f), m_left);
+	m_planesL[FrustumPlaneType::RIGHT] = Plane(Vec4(-1.0f, 0.0f, 0.0f, 0.0f), -m_right);
 
-	m_planesL[FrustumPlaneType::NEAR] = Plane(Vec4(0.0, 0.0, -1.0, 0.0), m_near);
-	m_planesL[FrustumPlaneType::FAR] = Plane(Vec4(0.0, 0.0, 1.0, 0.0), -m_far);
-	m_planesL[FrustumPlaneType::TOP] = Plane(Vec4(0.0, -1.0, 0.0, 0.0), -m_top);
-	m_planesL[FrustumPlaneType::BOTTOM] = Plane(Vec4(0.0, 1.0, 0.0, 0.0), m_bottom);
+	m_planesL[FrustumPlaneType::NEAR] = Plane(Vec4(0.0f, 0.0f, -1.0f, 0.0f), m_near);
+	m_planesL[FrustumPlaneType::FAR] = Plane(Vec4(0.0f, 0.0f, 1.0f, 0.0f), -m_far);
+	m_planesL[FrustumPlaneType::TOP] = Plane(Vec4(0.0f, -1.0f, 0.0f, 0.0f), -m_top);
+	m_planesL[FrustumPlaneType::BOTTOM] = Plane(Vec4(0.0f, 1.0f, 0.0f, 0.0f), m_bottom);
 
 	// OBB
-	Vec4 c((m_right + m_left) * 0.5, (m_top + m_bottom) * 0.5, -(m_far + m_near) * 0.5, 0.0);
-	Vec4 e = Vec4(m_right, m_top, -m_far, 0.0) - c;
+	Vec4 c((m_right + m_left) * 0.5f, (m_top + m_bottom) * 0.5f, -(m_far + m_near) * 0.5f, 0.0f);
+	Vec4 e = Vec4(m_right, m_top, -m_far, 0.0f) - c;
 	m_obbL = Obb(c, Mat3x4::getIdentity(), e);
 }
 

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

@@ -19,6 +19,7 @@ class GrObject;
 class GrManager;
 class GrManagerImpl;
 class TextureInitInfo;
+class TextureViewInitInfo;
 class SamplerInitInfo;
 class GrManagerInitInfo;
 class FramebufferInitInfo;
@@ -64,6 +65,7 @@ using GrObjectPtr = IntrusivePtr<T, DefaultPtrDeleter<T>>;
 
 ANKI_GR_CLASS(Buffer)
 ANKI_GR_CLASS(Texture)
+ANKI_GR_CLASS(TextureView)
 ANKI_GR_CLASS(Sampler)
 ANKI_GR_CLASS(CommandBuffer)
 ANKI_GR_CLASS(Shader)

+ 5 - 0
src/anki/gr/Enums.h

@@ -327,6 +327,11 @@ public:
 	{
 		return !(*this == b);
 	}
+
+	Bool isValid() const
+	{
+		return m_components != ComponentFormat::NONE && m_transform != TransformFormat::NONE;
+	}
 };
 
 static_assert(sizeof(PixelFormat) == 2, "Need it to be packed");

+ 1 - 0
src/anki/gr/GrManager.h

@@ -55,6 +55,7 @@ public:
 	/// @{
 	ANKI_USE_RESULT BufferPtr newBuffer(const BufferInitInfo& init);
 	ANKI_USE_RESULT TexturePtr newTexture(const TextureInitInfo& init);
+	ANKI_USE_RESULT TextureViewPtr newTextureView(const TextureViewInitInfo& init);
 	ANKI_USE_RESULT SamplerPtr newSampler(const SamplerInitInfo& init);
 	ANKI_USE_RESULT ShaderPtr newShader(const ShaderInitInfo& init);
 	ANKI_USE_RESULT ShaderProgramPtr newShaderProgram(const ShaderProgramInitInfo& init);

+ 1 - 0
src/anki/gr/GrObject.h

@@ -25,6 +25,7 @@ enum GrObjectType : U16
 	SAMPLER,
 	SHADER,
 	TEXTURE,
+	TEXTURE_VIEW,
 	SHADER_PROGRAM,
 	FENCE,
 	RENDER_GRAPH,

+ 2 - 1
src/anki/gr/Texture.h

@@ -78,7 +78,7 @@ public:
 		return m_depth;
 	}
 
-	U32 getLayercount() const
+	U32 getLayerCount() const
 	{
 		ANKI_ASSERT(m_layerCount);
 		return m_layerCount;
@@ -104,6 +104,7 @@ public:
 
 	const PixelFormat& getPixelFormat() const
 	{
+		ANKI_ASSERT(m_format.isValid());
 		return m_format;
 	}
 

+ 158 - 0
src/anki/gr/TextureView.h

@@ -0,0 +1,158 @@
+// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/gr/GrObject.h>
+#include <anki/gr/Texture.h>
+
+namespace anki
+{
+
+/// @addtogroup graphics
+/// @{
+
+/// TextureView init info.
+class TextureViewInitInfo : public GrBaseInitInfo
+{
+public:
+	TexturePtr m_texture;
+
+	U32 m_baseMipmap = MAX_U32;
+	U32 m_mipmapCount = MAX_U32;
+
+	U32 m_baseLayer = MAX_U32;
+	U32 m_layerCount = MAX_U32;
+
+	U8 m_baseFace = MAX_U8;
+	U8 m_faceCount = MAX_U8;
+
+	DepthStencilAspectBit m_depthStencilAspect = DepthStencilAspectBit::NONE;
+
+	TextureViewInitInfo(TexturePtr tex, CString name = {})
+		: GrBaseInitInfo(name)
+		, m_texture(tex)
+	{
+		m_baseMipmap = 0;
+		m_mipmapCount = tex->getMipmapCount();
+		m_baseLayer = 0;
+		m_layerCount = tex->getLayerCount();
+		m_baseFace = 0;
+		m_faceCount =
+			(tex->getTextureType() == TextureType::CUBE_ARRAY || tex->getTextureType() == TextureType::CUBE) ? 6 : 1;
+		// TODO: m_depthStencilAspect = ?
+	}
+
+	TextureViewInitInfo(CString name = {})
+		: GrBaseInitInfo(name)
+	{
+	}
+
+	Bool isValid() const
+	{
+#define ANKI_TEX_VIEW_ASSERT(x_) \
+	if(!(x_))                    \
+	{                            \
+		return false;            \
+	}
+		ANKI_TEX_VIEW_ASSERT(m_texture.isCreated());
+		const TextureType type = m_texture->getTextureType();
+		const Bool cube = type == TextureType::CUBE_ARRAY || type == TextureType::CUBE;
+
+		// Mips
+		ANKI_TEX_VIEW_ASSERT(m_mipmapCount > 0);
+		ANKI_TEX_VIEW_ASSERT(m_baseMipmap + m_mipmapCount <= m_texture->getMipmapCount());
+
+		// Layers
+		ANKI_TEX_VIEW_ASSERT(m_layerCount > 0);
+		ANKI_TEX_VIEW_ASSERT(m_baseLayer + m_layerCount <= m_texture->getLayerCount());
+
+		// Faces
+		const U8 faceCount = (cube) ? 6 : 1;
+		ANKI_TEX_VIEW_ASSERT(m_faceCount > 0);
+		ANKI_TEX_VIEW_ASSERT(m_baseFace + m_faceCount <= faceCount);
+
+		// Misc
+		if(type == TextureType::CUBE_ARRAY && m_layerCount > 1)
+		{
+			ANKI_TEX_VIEW_ASSERT(m_faceCount == 6); // Because of the way surfaces are arranged in cube arrays
+		}
+
+#undef ANKI_TEX_VIEW_VALID
+		return true;
+	}
+};
+
+/// GPU texture view.
+class TextureView : public GrObject
+{
+	ANKI_GR_OBJECT
+
+public:
+	static const GrObjectType CLASS_TYPE = GrObjectType::TEXTURE_VIEW;
+
+	TextureType getTextureType() const
+	{
+		ANKI_ASSERT(initialized());
+		return m_texType;
+	}
+
+	DepthStencilAspectBit getDepthStencilAspect() const
+	{
+		ANKI_ASSERT(initialized());
+		return m_aspect;
+	}
+
+	Bool isSingleSurface() const
+	{
+		ANKI_ASSERT(initialized());
+		ANKI_ASSERT(m_texType != TextureType::_3D);
+		return m_mipCount == 1 && m_layerCount == 1 && m_faceCount == 1;
+	}
+
+	Bool isSingleVolume() const
+	{
+		ANKI_ASSERT(initialized());
+		ANKI_ASSERT(m_texType == TextureType::_3D);
+		return m_mipCount == 1;
+	}
+
+protected:
+	TextureType m_texType = TextureType::COUNT;
+	DepthStencilAspectBit m_aspect = DepthStencilAspectBit::NONE;
+
+	U32 m_baseMip = MAX_U32;
+	U32 m_mipCount = MAX_U32;
+
+	U32 m_baseLayer = MAX_U32;
+	U32 m_layerCount = MAX_U32;
+
+	U8 m_baseFace = MAX_U8;
+	U8 m_faceCount = MAX_U8;
+
+	/// Construct.
+	TextureView(GrManager* manager)
+		: GrObject(manager, CLASS_TYPE)
+	{
+	}
+
+	/// Destroy.
+	~TextureView()
+	{
+	}
+
+	Bool initialized() const
+	{
+		return m_texType != TextureType::COUNT && m_baseMip < MAX_U32 && m_mipCount < MAX_U32 && m_baseLayer < MAX_U32
+			&& m_layerCount < MAX_U32 && m_baseFace < MAX_U8 && m_faceCount < MAX_U8;
+	}
+
+private:
+	/// Allocate and initialize new instance.
+	static ANKI_USE_RESULT TextureView* newInstance(GrManager* manager, const TextureViewInitInfo& init);
+};
+/// @}
+
+} // end namespace anki

+ 6 - 0
src/anki/gr/vulkan/GrManager.cpp

@@ -8,6 +8,7 @@
 
 #include <anki/gr/Buffer.h>
 #include <anki/gr/Texture.h>
+#include <anki/gr/TextureView.h>
 #include <anki/gr/Sampler.h>
 #include <anki/gr/Shader.h>
 #include <anki/gr/ShaderProgram.h>
@@ -88,6 +89,11 @@ TexturePtr GrManager::newTexture(const TextureInitInfo& init)
 	return TexturePtr(Texture::newInstance(this, init));
 }
 
+TextureViewPtr GrManager::newTextureView(const TextureViewInitInfo& init)
+{
+	return TextureViewPtr(TextureView::newInstance(this, init));
+}
+
 SamplerPtr GrManager::newSampler(const SamplerInitInfo& init)
 {
 	return SamplerPtr(Sampler::newInstance(this, init));

+ 7 - 0
src/anki/gr/vulkan/TextureImpl.h

@@ -115,6 +115,13 @@ 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);
+	}
+
 private:
 	class ViewHasher
 	{

+ 18 - 0
src/anki/gr/vulkan/TextureView.cpp

@@ -0,0 +1,18 @@
+// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/gr/TextureView.h>
+#include <anki/gr/vulkan/TextureViewImpl.h>
+#include <anki/gr/GrManager.h>
+
+namespace anki
+{
+
+TextureView* TextureView::newInstance(GrManager* manager, const TextureViewInitInfo& init)
+{
+	return TextureViewImpl::newInstanceHelper(manager, init);
+}
+
+} // end namespace anki

+ 51 - 0
src/anki/gr/vulkan/TextureViewImpl.cpp

@@ -0,0 +1,51 @@
+// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/gr/vulkan/TextureViewImpl.h>
+#include <anki/gr/vulkan/TextureImpl.h>
+
+namespace anki
+{
+
+TextureViewImpl::~TextureViewImpl()
+{
+}
+
+Error TextureViewImpl::init(const TextureViewInitInfo& inf)
+{
+	ANKI_ASSERT(inf.isValid());
+
+	// Store some stuff
+	m_aspect = inf.m_depthStencilAspect;
+	m_baseMip = inf.m_baseMipmap;
+	m_mipCount = inf.m_mipmapCount;
+	m_baseLayer = inf.m_baseLayer;
+	m_layerCount = inf.m_layerCount;
+	m_baseFace = inf.m_baseFace;
+	m_faceCount = inf.m_faceCount;
+	// TODO Set m_texType
+
+	m_tex = inf.m_texture;
+
+	const TextureImpl& tex = static_cast<const TextureImpl&>(*m_tex);
+
+	// Compute the VK range
+	VkImageSubresourceRange range;
+	range.aspectMask = tex.convertAspect(m_aspect);
+	range.baseMipLevel = m_baseMip;
+	range.levelCount = m_mipCount;
+
+	const TextureType type = tex.getTextureType();
+	const U32 faceCount = type == TextureType::CUBE_ARRAY || type == TextureType::CUBE;
+	range.baseArrayLayer = m_baseLayer * faceCount + m_baseFace;
+	range.layerCount = m_layerCount * m_faceCount;
+
+	// Ask the texture for a view
+	m_handle = tex.getOrCreateView(range);
+
+	return Error::NONE;
+}
+
+} // end namespace anki

+ 35 - 0
src/anki/gr/vulkan/TextureViewImpl.h

@@ -0,0 +1,35 @@
+// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/gr/TextureView.h>
+#include <anki/gr/vulkan/VulkanObject.h>
+
+namespace anki
+{
+
+/// @addtogroup vulkan
+/// @{
+
+/// Texture view implementation.
+class TextureViewImpl final : public TextureView, public VulkanObject<TextureView, TextureViewImpl>
+{
+public:
+	VkImageView m_handle = {};
+	TexturePtr m_tex; ///< Hold a reference.
+
+	TextureViewImpl(GrManager* manager)
+		: TextureView(manager)
+	{
+	}
+
+	~TextureViewImpl();
+
+	ANKI_USE_RESULT Error init(const TextureViewInitInfo& inf);
+};
+/// @}
+
+} // end namespace anki

+ 1 - 1
src/anki/math/Mat3x4.h

@@ -206,7 +206,7 @@ public:
 
 	static const TMat3x4& getIdentity()
 	{
-		static const TMat3x4 ident(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+		static const TMat3x4 ident(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
 		return ident;
 	}
 	/// @}