2
0
Эх сурвалжийг харах

Modified vertex declaration creation so assigns identical ids to identical declarations

BearishSun 9 жил өмнө
parent
commit
d3f4c074ed

+ 1 - 1
Source/BansheeCore/Include/BsBlendState.h

@@ -190,7 +190,7 @@ namespace bs
 	public:
 	public:
 		friend class BlendStateRTTI;
 		friend class BlendStateRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;	
+		RTTITypeBase* getRTTI() const override;	
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 26 - 2
Source/BansheeCore/Include/BsHardwareBufferManager.h

@@ -137,6 +137,26 @@ namespace bs
 		friend class GpuBuffer;
 		friend class GpuBuffer;
 		friend class GpuBufferCore;
 		friend class GpuBufferCore;
 
 
+		/** Key for use in the vertex declaration map. */
+		struct VertexDeclarationKey
+		{
+			VertexDeclarationKey(const List<VertexElement>& elements);
+
+			class HashFunction
+			{
+			public:
+				size_t operator()(const VertexDeclarationKey& key) const;
+			};
+
+			class EqualFunction
+			{
+			public:
+				bool operator()(const VertexDeclarationKey& lhs, const VertexDeclarationKey& rhs) const;
+			};
+
+			List<VertexElement> elements;
+		};
+
 		/** @copydoc createVertexBuffer */
 		/** @copydoc createVertexBuffer */
 		virtual SPtr<VertexBufferCore> createVertexBufferInternal(const VERTEX_BUFFER_DESC& desc, 
 		virtual SPtr<VertexBufferCore> createVertexBufferInternal(const VERTEX_BUFFER_DESC& desc, 
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
@@ -160,8 +180,12 @@ namespace bs
 		/** @copydoc createGpuParams */
 		/** @copydoc createGpuParams */
 		virtual SPtr<GpuParamsCore> createGpuParamsInternal(const SPtr<GpuPipelineParamInfoCore>& paramInfo,
 		virtual SPtr<GpuParamsCore> createGpuParamsInternal(const SPtr<GpuPipelineParamInfoCore>& paramInfo,
 															GpuDeviceFlags deviceMask = GDF_DEFAULT);
 															GpuDeviceFlags deviceMask = GDF_DEFAULT);
+
+		typedef UnorderedMap<VertexDeclarationKey, SPtr<VertexDeclarationCore>, 
+			VertexDeclarationKey::HashFunction, VertexDeclarationKey::EqualFunction> DeclarationMap;
+
+		DeclarationMap mCachedDeclarations;
 	};
 	};
 
 
 	/** @} */
 	/** @} */
-}
-
+}

+ 2 - 0
Source/BansheeCore/Include/BsVertexDeclaration.h

@@ -110,6 +110,8 @@ namespace bs
 		/**	Gets packed color vertex element type used by the active render system. */
 		/**	Gets packed color vertex element type used by the active render system. */
 		static VertexElementType getBestColorVertexElementType();
 		static VertexElementType getBestColorVertexElementType();
 
 
+		/** Calculates a hash value for the provided vertex element. */
+		static size_t getHash(const VertexElement& element);
 	protected:
 	protected:
 		UINT16 mSource;
 		UINT16 mSource;
 		UINT32 mOffset;
 		UINT32 mOffset;

+ 44 - 3
Source/BansheeCore/Source/BsHardwareBufferManager.cpp

@@ -73,6 +73,41 @@ namespace bs
 		return paramsPtr;
 		return paramsPtr;
     }
     }
 
 
+	HardwareBufferCoreManager::VertexDeclarationKey::VertexDeclarationKey(const List<VertexElement>& elements)
+		:elements(elements)
+	{ }
+
+
+	size_t HardwareBufferCoreManager::VertexDeclarationKey::HashFunction::operator()(const VertexDeclarationKey& v) const
+	{
+		size_t hash = 0;
+		for(auto& entry : v.elements)
+			hash_combine(hash, VertexElement::getHash(entry));
+
+		return hash;
+	}
+
+	bool HardwareBufferCoreManager::VertexDeclarationKey::EqualFunction::operator()(const VertexDeclarationKey& lhs, 
+		const VertexDeclarationKey& rhs) const
+	{
+		if (lhs.elements.size() != rhs.elements.size())
+			return false;
+
+		size_t numElements = lhs.elements.size();
+		auto iterLeft = lhs.elements.begin();
+		auto iterRight = rhs.elements.begin();
+		for(size_t i = 0; i < numElements; i++)
+		{
+			if (*iterLeft != *iterRight)
+				return false;
+
+			++iterLeft;
+			++iterRight;
+		}
+
+		return true;
+	}
+
 	SPtr<IndexBufferCore> HardwareBufferCoreManager::createIndexBuffer(const INDEX_BUFFER_DESC& desc, 
 	SPtr<IndexBufferCore> HardwareBufferCoreManager::createIndexBuffer(const INDEX_BUFFER_DESC& desc, 
 		GpuDeviceFlags deviceMask)
 		GpuDeviceFlags deviceMask)
 	{
 	{
@@ -93,10 +128,9 @@ namespace bs
 	SPtr<VertexDeclarationCore> HardwareBufferCoreManager::createVertexDeclaration(const SPtr<VertexDataDesc>& desc, 
 	SPtr<VertexDeclarationCore> HardwareBufferCoreManager::createVertexDeclaration(const SPtr<VertexDataDesc>& desc, 
 		GpuDeviceFlags deviceMask)
 		GpuDeviceFlags deviceMask)
 	{
 	{
-		SPtr<VertexDeclarationCore> declPtr = createVertexDeclarationInternal(desc->createElements(), deviceMask);
-		declPtr->initialize();
+		List<VertexElement> elements = desc->createElements();
 
 
-		return declPtr;
+		return createVertexDeclaration(elements, deviceMask);
 	}
 	}
 
 
 	SPtr<GpuParamsCore> HardwareBufferCoreManager::createGpuParams(const SPtr<GpuPipelineParamInfoCore>& paramInfo,
 	SPtr<GpuParamsCore> HardwareBufferCoreManager::createGpuParams(const SPtr<GpuPipelineParamInfoCore>& paramInfo,
@@ -111,9 +145,16 @@ namespace bs
 	SPtr<VertexDeclarationCore> HardwareBufferCoreManager::createVertexDeclaration(const List<VertexElement>& elements,
 	SPtr<VertexDeclarationCore> HardwareBufferCoreManager::createVertexDeclaration(const List<VertexElement>& elements,
 		GpuDeviceFlags deviceMask)
 		GpuDeviceFlags deviceMask)
 	{
 	{
+		VertexDeclarationKey key(elements);
+
+		auto iterFind = mCachedDeclarations.find(key);
+		if (iterFind != mCachedDeclarations.end())
+			return iterFind->second;
+
 		SPtr<VertexDeclarationCore> declPtr = createVertexDeclarationInternal(elements, deviceMask);
 		SPtr<VertexDeclarationCore> declPtr = createVertexDeclarationInternal(elements, deviceMask);
 		declPtr->initialize();
 		declPtr->initialize();
 
 
+		mCachedDeclarations[key] = declPtr;
 		return declPtr;
 		return declPtr;
 	}
 	}
 
 

+ 12 - 0
Source/BansheeCore/Source/BsVertexDeclaration.cpp

@@ -145,6 +145,18 @@ namespace bs
 		return !(*this == rhs);
 		return !(*this == rhs);
 	}
 	}
 
 
+	size_t VertexElement::getHash(const VertexElement& element)
+	{
+		size_t hash = 0;
+		hash_combine(hash, element.mType);
+		hash_combine(hash, element.mIndex);
+		hash_combine(hash, element.mOffset);
+		hash_combine(hash, element.mSemantic);
+		hash_combine(hash, element.mSource);
+
+		return hash;
+	}
+
 	VertexDeclarationProperties::VertexDeclarationProperties(const List<VertexElement>& elements)
 	VertexDeclarationProperties::VertexDeclarationProperties(const List<VertexElement>& elements)
 	{
 	{
 		for (auto& elem : elements)
 		for (auto& elem : elements)