Browse Source

Some more vulkan ppline work

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
6cf3a445b1

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

@@ -239,6 +239,11 @@ public:
 		return m_components == b.m_components && m_transform == b.m_transform
 			&& m_srgb == b.m_srgb;
 	}
+
+	Bool operator!=(const PixelFormat& b) const
+	{
+		return !(*this == b);
+	}
 };
 
 /// Occlusion query result bit.

+ 4 - 1
include/anki/gr/vulkan/Common.h

@@ -31,13 +31,16 @@ namespace anki
 
 /// Debug initialize a vulkan structure
 #if ANKI_DEBUG
-#define ANKI_VK_MEMSET_DBG(struct_) memset(&struct_, 0xCC, sizeof(struct_));
+#define ANKI_VK_MEMSET_DBG(struct_) memset(&struct_, 0xCC, sizeof(struct_))
 #else
 #define ANKI_VK_MEMSET_DBG(struct_) ((void)0)
 #endif
 
 /// Convert compare op.
 VkCompareOp convertCompareOp(CompareOperation ak);
+
+/// Convert format.
+VkFormat convertFormat(PixelFormat ak);
 /// @}
 
 } // end namespace anki

+ 8 - 0
include/anki/gr/vulkan/GrManagerImpl.h

@@ -29,8 +29,16 @@ public:
 
 	~GrManagerImpl();
 
+	/// Get or create a compatible render pass for a pipeline.
+	VkRenderPass getOrCreateCompatibleRenderPass(const PipelineInitInfo& init);
+
 private:
 	GrManager* m_manager = nullptr;
+	GrAllocator<U8> m_alloc;
+
+	/// Map for compatible render passes.
+	class CompatibleRenderPassHashMap;
+	CompatibleRenderPassHashMap* m_renderPasses = nullptr;
 };
 /// @}
 

+ 224 - 0
src/gr/vulkan/Common.cpp

@@ -45,4 +45,228 @@ VkCompareOp convertCompareOp(CompareOperation ak)
 	return out;
 }
 
+//==============================================================================
+class ConvertFormat
+{
+public:
+	PixelFormat m_ak;
+	VkFormat m_vk;
+
+	ConvertFormat(const PixelFormat& ak, VkFormat vk)
+		: m_ak(ak)
+		, m_vk(vk)
+	{
+	}
+};
+
+#define ANKI_FMT(fmt, trf, vk)                                                 \
+	ConvertFormat(PixelFormat(ComponentFormat::fmt, TransformFormat::trf), vk)
+
+static const ConvertFormat CONVERT_FORMAT_TABLE[] = {
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R4G4_UNORM_PACK8),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R4G4B4A4_UNORM_PACK16),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B4G4R4A4_UNORM_PACK16),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R5G6B5_UNORM_PACK16),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B5G6R5_UNORM_PACK16),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R5G5B5A1_UNORM_PACK16),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B5G5R5A1_UNORM_PACK16),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A1R5G5B5_UNORM_PACK16),
+	ANKI_FMT(R8, UNORM, VK_FORMAT_R8_UNORM),
+	ANKI_FMT(R8, SNORM, VK_FORMAT_R8_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8_SSCALED),
+	ANKI_FMT(R8, UINT, VK_FORMAT_R8_UINT),
+	ANKI_FMT(R8, SINT, VK_FORMAT_R8_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8_SRGB),
+	ANKI_FMT(R8G8, UNORM, VK_FORMAT_R8G8_UNORM),
+	ANKI_FMT(R8G8, SNORM, VK_FORMAT_R8G8_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8_SSCALED),
+	ANKI_FMT(R8G8, UINT, VK_FORMAT_R8G8_UINT),
+	ANKI_FMT(R8G8, SINT, VK_FORMAT_R8G8_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8_SRGB),
+	ANKI_FMT(R8G8B8, UNORM, VK_FORMAT_R8G8B8_UNORM),
+	ANKI_FMT(R8G8B8, SNORM, VK_FORMAT_R8G8B8_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8B8_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8B8_SSCALED),
+	ANKI_FMT(R8G8B8, UINT, VK_FORMAT_R8G8B8_UINT),
+	ANKI_FMT(R8G8B8, SINT, VK_FORMAT_R8G8B8_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8B8_SRGB),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_UNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_SSCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8_SRGB),
+	ANKI_FMT(R8G8B8A8, UNORM, VK_FORMAT_R8G8B8A8_UNORM),
+	ANKI_FMT(R8G8B8A8, SNORM, VK_FORMAT_R8G8B8A8_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8B8A8_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8B8A8_SSCALED),
+	ANKI_FMT(R8G8B8A8, UINT, VK_FORMAT_R8G8B8A8_UINT),
+	ANKI_FMT(R8G8B8A8, SINT, VK_FORMAT_R8G8B8A8_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R8G8B8A8_SRGB),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_UNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_SSCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_B8G8R8A8_SRGB),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_UNORM_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_SNORM_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_USCALED_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_SSCALED_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_UINT_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_SINT_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A8B8G8R8_SRGB_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2R10G10B10_UNORM_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2R10G10B10_SNORM_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2R10G10B10_USCALED_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2R10G10B10_SSCALED_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2R10G10B10_UINT_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2R10G10B10_SINT_PACK32),
+	ANKI_FMT(R10G10B10A2, UNORM, VK_FORMAT_A2B10G10R10_UNORM_PACK32),
+	ANKI_FMT(R10G10B10A2, SNORM, VK_FORMAT_A2B10G10R10_SNORM_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2B10G10R10_USCALED_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_A2B10G10R10_SSCALED_PACK32),
+	ANKI_FMT(R10G10B10A2, UINT, VK_FORMAT_A2B10G10R10_UINT_PACK32),
+	ANKI_FMT(R10G10B10A2, SINT, VK_FORMAT_A2B10G10R10_SINT_PACK32),
+	ANKI_FMT(R16, UNORM, VK_FORMAT_R16_UNORM),
+	ANKI_FMT(R16, SNORM, VK_FORMAT_R16_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16_SSCALED),
+	ANKI_FMT(R16, UINT, VK_FORMAT_R16_UINT),
+	ANKI_FMT(R16, SINT, VK_FORMAT_R16_SINT),
+	ANKI_FMT(R16, FLOAT, VK_FORMAT_R16_SFLOAT),
+	ANKI_FMT(R16G16, UNORM, VK_FORMAT_R16G16_UNORM),
+	ANKI_FMT(R16G16, SNORM, VK_FORMAT_R16G16_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16G16_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16G16_SSCALED),
+	ANKI_FMT(R16G16, UINT, VK_FORMAT_R16G16_UINT),
+	ANKI_FMT(R16G16, SINT, VK_FORMAT_R16G16_SINT),
+	ANKI_FMT(R16G16, FLOAT, VK_FORMAT_R16G16_SFLOAT),
+	ANKI_FMT(R16G16B16, UNORM, VK_FORMAT_R16G16B16_UNORM),
+	ANKI_FMT(R16G16B16, SNORM, VK_FORMAT_R16G16B16_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16G16B16_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16G16B16_SSCALED),
+	ANKI_FMT(R16G16B16, UINT, VK_FORMAT_R16G16B16_UINT),
+	ANKI_FMT(R16G16B16, SINT, VK_FORMAT_R16G16B16_SINT),
+	ANKI_FMT(R16G16B16, FLOAT, VK_FORMAT_R16G16B16_SFLOAT),
+	ANKI_FMT(R16G16B16A16, UNORM, VK_FORMAT_R16G16B16A16_UNORM),
+	ANKI_FMT(R16G16B16A16, SNORM, VK_FORMAT_R16G16B16A16_SNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16G16B16A16_USCALED),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R16G16B16A16_SSCALED),
+	ANKI_FMT(R16G16B16A16, UINT, VK_FORMAT_R16G16B16A16_UINT),
+	ANKI_FMT(R16G16B16A16, SINT, VK_FORMAT_R16G16B16A16_SINT),
+	ANKI_FMT(R16G16B16A16, FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT),
+	ANKI_FMT(R32, UINT, VK_FORMAT_R32_UINT),
+	ANKI_FMT(R32, SINT, VK_FORMAT_R32_SINT),
+	ANKI_FMT(R32, FLOAT, VK_FORMAT_R32_SFLOAT),
+	ANKI_FMT(R32G32, UINT, VK_FORMAT_R32G32_UINT),
+	ANKI_FMT(R32G32, SINT, VK_FORMAT_R32G32_SINT),
+	ANKI_FMT(R32G32, FLOAT, VK_FORMAT_R32G32_SFLOAT),
+	ANKI_FMT(R32G32B32, UINT, VK_FORMAT_R32G32B32_UINT),
+	ANKI_FMT(R32G32B32, SINT, VK_FORMAT_R32G32B32_SINT),
+	ANKI_FMT(R32G32B32, FLOAT, VK_FORMAT_R32G32B32_SFLOAT),
+	ANKI_FMT(R32G32B32A32, UINT, VK_FORMAT_R32G32B32A32_UINT),
+	ANKI_FMT(R32G32B32A32, SINT, VK_FORMAT_R32G32B32A32_SINT),
+	ANKI_FMT(R32G32B32A32, FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64_SFLOAT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64_SFLOAT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64B64_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64B64_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64B64_SFLOAT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64B64A64_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64B64A64_SINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_R64G64B64A64_SFLOAT),
+	ANKI_FMT(R11G11B10, FLOAT, VK_FORMAT_B10G11R11_UFLOAT_PACK32),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32),
+	ANKI_FMT(D16, UNORM, VK_FORMAT_D16_UNORM),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_X8_D24_UNORM_PACK32),
+	ANKI_FMT(D32, FLOAT, VK_FORMAT_D32_SFLOAT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_S8_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_D16_UNORM_S8_UINT),
+	ANKI_FMT(D24, UNORM, VK_FORMAT_D24_UNORM_S8_UINT),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_D32_SFLOAT_S8_UINT),
+	ANKI_FMT(R8G8B8_S3TC, NONE, VK_FORMAT_BC1_RGB_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC1_RGB_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC1_RGBA_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC1_RGBA_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC2_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC2_SRGB_BLOCK),
+	ANKI_FMT(R8G8B8A8_S3TC, NONE, VK_FORMAT_BC3_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC3_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC4_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC4_SNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC5_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC5_SNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC6H_UFLOAT_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC6H_SFLOAT_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC7_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_BC7_SRGB_BLOCK),
+	ANKI_FMT(R8G8B8_ETC2, NONE, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK),
+	ANKI_FMT(R8G8B8A8_ETC2, NONE, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_EAC_R11_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_EAC_R11_SNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_EAC_R11G11_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_EAC_R11G11_SNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_4x4_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_4x4_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_5x4_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_5x4_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_5x5_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_5x5_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_6x5_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_6x5_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_6x6_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_6x6_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_8x5_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_8x5_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_8x6_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_8x6_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_8x8_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_8x8_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x5_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x5_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x6_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x6_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x8_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x8_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x10_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_10x10_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_12x10_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_12x10_SRGB_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_12x12_UNORM_BLOCK),
+	ANKI_FMT(NONE, NONE, VK_FORMAT_ASTC_12x12_SRGB_BLOCK)};
+
+#undef ANKI_FMT
+
+const U CONVERT_FORMAT_TABLE_SIZE = 
+	sizeof(CONVERT_FORMAT_TABLE) / sizeof(CONVERT_FORMAT_TABLE[0]);
+
+VkFormat convertFormat(PixelFormat ak)
+{
+	VkFormat out = VK_FORMAT_UNDEFINED;
+	for(U i = 0; i < CONVERT_FORMAT_TABLE_SIZE; ++i)
+	{
+		const ConvertFormat& entry = CONVERT_FORMAT_TABLE[i];
+		if(ak == entry.m_ak)
+		{
+			out = entry.m_vk;
+		}
+	}
+
+	ANKI_ASSERT(out != VK_FORMAT_UNDEFINED && "No format in the table");
+	return out;
+}
+
 } // end namespace anki

+ 182 - 0
src/gr/vulkan/GrManagerImpl.cpp

@@ -0,0 +1,182 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/gr/vulkan/GrManagerImpl.h>
+#include <anki/gr/Pipeline.h>
+#include <anki/util/HashMap.h>
+#include <anki/util/Hash.h>
+
+namespace anki
+{
+
+//==============================================================================
+// GrManagerImpl::CompatibleRenderPassHashMap                                  =
+//==============================================================================
+
+class RenderPassKey
+{
+public:
+	Array<PixelFormat, MAX_COLOR_ATTACHMENTS> m_colorAttachments;
+	PixelFormat m_depthStencilAttachment;
+
+	RenderPassKey()
+	{
+		// Zero because we compute hashes
+		memset(this, 0, sizeof(*this));
+	}
+
+	RenderPassKey& operator=(const RenderPassKey& b) = default;
+};
+
+class RenderPassHasher
+{
+public:
+	U64 operator()(const RenderPassKey& b) const
+	{
+		return computeHash(&b, sizeof(b));
+	}
+};
+
+class RenderPassCompare
+{
+public:
+	Bool operator()(
+		const RenderPassKey& a, const RenderPassKey& b) const
+	{
+		for(U i = 0; i < a.m_colorAttachments.getSize(); ++i)
+		{
+			if(a.m_colorAttachments[i] != b.m_colorAttachments[i])
+			{
+				return false;
+			}
+		}
+
+		return a.m_depthStencilAttachment == b.m_depthStencilAttachment;
+	}
+};
+	
+class GrManagerImpl::CompatibleRenderPassHashMap
+{
+public:
+	Mutex m_mtx;
+	HashMap<RenderPassKey, VkRenderPass, RenderPassHasher, RenderPassCompare>
+		m_hashmap;
+};
+
+//==============================================================================
+// GrManagerImpl                                                               =
+//==============================================================================
+
+//==============================================================================
+VkRenderPass GrManagerImpl::getOrCreateCompatibleRenderPass(
+	const PipelineInitInfo& init)
+{
+	VkRenderPass out;
+	// Create the key
+	RenderPassKey key;
+	for(U i = 0; i < init.m_color.m_attachmentCount; ++i)
+	{
+		key.m_colorAttachments[i] = init.m_color.m_attachments[i].m_format;
+	}
+	key.m_depthStencilAttachment = init.m_depthStencil.m_format;
+
+	// Lock
+	LockGuard<Mutex> lock(m_renderPasses->m_mtx);
+
+	auto it = m_renderPasses->m_hashmap.find(key);
+	if(it != m_renderPasses->m_hashmap.getEnd())
+	{
+		// Found the key
+		out = *it;
+	}
+	else
+	{
+		// Not found, create one
+		VkRenderPassCreateInfo ci;
+		ANKI_VK_MEMSET_DBG(ci);
+		ci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+		ci.pNext = nullptr;
+		ci.flags = 0;
+
+		Array<VkAttachmentDescription, MAX_COLOR_ATTACHMENTS + 1>
+			attachmentDescriptions;
+		Array<VkAttachmentReference, MAX_COLOR_ATTACHMENTS> references;
+		for(U i = 0; i < init.m_color.m_attachmentCount; ++i)
+		{
+			// We only care about samples and format
+			VkAttachmentDescription& desc = attachmentDescriptions[i];
+			ANKI_VK_MEMSET_DBG(desc);
+			desc.flags = 0;
+			desc.format = convertFormat(init.m_color.m_attachments[i].m_format);
+			desc.samples = VK_SAMPLE_COUNT_1_BIT;
+			desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+			desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+			desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+			desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+			desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+			desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+			references[i].attachment = i;
+			references[i].layout = VK_IMAGE_LAYOUT_UNDEFINED;
+		}
+
+		ci.attachmentCount = init.m_color.m_attachmentCount;
+
+		Bool hasDepthStencil = 
+			init.m_depthStencil.m_format.m_components != ComponentFormat::NONE;
+		VkAttachmentReference dsReference = {0, VK_IMAGE_LAYOUT_UNDEFINED};
+		if(hasDepthStencil)
+		{
+			VkAttachmentDescription& desc = 
+				attachmentDescriptions[ci.attachmentCount];
+			ANKI_VK_MEMSET_DBG(desc);
+			desc.flags = 0;
+			desc.format = convertFormat(init.m_depthStencil.m_format);
+			desc.samples = VK_SAMPLE_COUNT_1_BIT;
+			desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+			desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+			desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+			desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+			desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+			desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+			dsReference.attachment = ci.attachmentCount;
+			dsReference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+			++ci.attachmentCount;
+		}
+
+		VkSubpassDescription desc;
+		ANKI_VK_MEMSET_DBG(desc);
+		desc.flags = 0;
+		desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+		desc.inputAttachmentCount = 0;
+		desc.pInputAttachments = nullptr;
+		desc.colorAttachmentCount = init.m_color.m_attachmentCount;
+		desc.pColorAttachments = (init.m_color.m_attachmentCount) 
+			? &references[0] : nullptr;
+		desc.pResolveAttachments = nullptr;
+		desc.pDepthStencilAttachment = (hasDepthStencil) 
+			? &dsReference : nullptr;
+		desc.preserveAttachmentCount = 0;
+		desc.pPreserveAttachments = nullptr;
+
+		ANKI_ASSERT(ci.attachmentCount);
+		ci.pAttachments = &attachmentDescriptions[0];
+		ci.subpassCount = 1;
+		ci.pSubpasses = &desc;
+		ci.dependencyCount = 0;
+		ci.pDependencies = nullptr;
+
+		VkRenderPass rpass;
+		ANKI_VK_CHECK(vkCreateRenderPass(m_device, &ci, nullptr, &rpass));
+
+		m_renderPasses->m_hashmap.pushBack(m_alloc, key, rpass);
+	}
+
+	return out;
+}
+
+} // end namespace anki

+ 3 - 3
src/gr/vulkan/PipelineImpl.cpp

@@ -169,7 +169,7 @@ VkPipelineVertexInputStateCreateInfo* PipelineImpl::initVertexStage(
 
 		vkAttrib.location = 0;
 		vkAttrib.binding = vertex.m_attributes[i].m_binding;
-		vkAttrib.format = VkFormat(0); // XXX
+		vkAttrib.format = convertFormat(vertex.m_attributes[i].m_format);
 		vkAttrib.offset = vertex.m_attributes[i].m_offset;
 	}
 
@@ -177,8 +177,8 @@ VkPipelineVertexInputStateCreateInfo* PipelineImpl::initVertexStage(
 }
 
 //==============================================================================
-VkPipelineInputAssemblyStateCreateInfo*
-PipelineImpl::initInputAssemblyState(const InputAssemblerStateInfo& ia,
+VkPipelineInputAssemblyStateCreateInfo* PipelineImpl::initInputAssemblyState(
+	const InputAssemblerStateInfo& ia,
 	VkPipelineInputAssemblyStateCreateInfo& ci)
 {
 	// TODO