Kaynağa Gözat

Added a clone method to GPU params

Marko Pintera 11 yıl önce
ebeveyn
işleme
d19ef88b95

+ 39 - 20
BansheeCore/Include/BsGpuParams.h

@@ -20,6 +20,7 @@ namespace BansheeEngine
 	 */
 	 */
 	class BS_CORE_EXPORT GpuParams
 	class BS_CORE_EXPORT GpuParams
 	{
 	{
+		struct PrivatelyConstruct {};
 	public:
 	public:
 		/**
 		/**
 		 * @brief	Creates new GpuParams object using the specified parameter descriptions.
 		 * @brief	Creates new GpuParams object using the specified parameter descriptions.
@@ -31,6 +32,12 @@ namespace BansheeEngine
 		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
 		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
 		 */
 		 */
 		GpuParams(GpuParamDesc& paramDesc, bool transposeMatrices);
 		GpuParams(GpuParamDesc& paramDesc, bool transposeMatrices);
+
+		/**
+		 * @brief	Private constructor for internal use. Performs no initialization.
+		 */
+		GpuParams(GpuParamDesc& paramDesc, PrivatelyConstruct& dummy);
+
 		~GpuParams();
 		~GpuParams();
 
 
 		/**
 		/**
@@ -74,13 +81,13 @@ namespace BansheeEngine
 		bool hasParam(const String& name) const;
 		bool hasParam(const String& name) const;
 
 
 		/**
 		/**
-		* @brief	Checks if texture parameter with the specified name exists.
-		*/
+		 * @brief	Checks if texture parameter with the specified name exists.
+		 */
 		bool hasTexture(const String& name) const;
 		bool hasTexture(const String& name) const;
 
 
 		/**
 		/**
-		* @brief	Checks if sampler state parameter with the specified name exists.
-		*/
+		 * @brief	Checks if sampler state parameter with the specified name exists.
+		 */
 		bool hasSamplerState(const String& name) const;
 		bool hasSamplerState(const String& name) const;
 
 
 		/**
 		/**
@@ -117,8 +124,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		template<>
 		template<>
 		void getParam<Vector2>(const String& name, TGpuDataParam<Vector2>& output) const
 		void getParam<Vector2>(const String& name, TGpuDataParam<Vector2>& output) const
 		{
 		{
@@ -131,8 +138,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		template<>
 		template<>
 		void getParam<Vector3>(const String& name, TGpuDataParam<Vector3>& output) const
 		void getParam<Vector3>(const String& name, TGpuDataParam<Vector3>& output) const
 		{
 		{
@@ -145,8 +152,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		template<>
 		template<>
 		void getParam<Vector4>(const String& name, TGpuDataParam<Vector4>& output) const
 		void getParam<Vector4>(const String& name, TGpuDataParam<Vector4>& output) const
 		{
 		{
@@ -159,8 +166,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		template<>
 		template<>
 		void getParam<Matrix3>(const String& name, TGpuDataParam<Matrix3>& output) const
 		void getParam<Matrix3>(const String& name, TGpuDataParam<Matrix3>& output) const
 		{
 		{
@@ -173,8 +180,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		template<>
 		template<>
 		void getParam<Matrix4>(const String& name, TGpuDataParam<Matrix4>& output) const
 		void getParam<Matrix4>(const String& name, TGpuDataParam<Matrix4>& output) const
 		{
 		{
@@ -187,20 +194,25 @@ namespace BansheeEngine
 		}
 		}
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		void getStructParam(const String& name, GpuParamStruct& output) const;
 		void getStructParam(const String& name, GpuParamStruct& output) const;
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		void getTextureParam(const String& name, GpuParamTexture& output) const;
 		void getTextureParam(const String& name, GpuParamTexture& output) const;
 
 
 		/**
 		/**
-		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		*/
+		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 */
 		void getSamplerStateParam(const String& name, GpuParamSampState& output) const;
 		void getSamplerStateParam(const String& name, GpuParamSampState& output) const;
 
 
+		/**
+		 * @brief	Returns an exact copy of this object.
+		 */
+		GpuParamsPtr clone() const;
+
 	private:
 	private:
 		friend class BindableGpuParams;
 		friend class BindableGpuParams;
 
 
@@ -212,6 +224,13 @@ namespace BansheeEngine
 		 * @brief	Gets a descriptor for a data parameter with the specified name.
 		 * @brief	Gets a descriptor for a data parameter with the specified name.
 		 */
 		 */
 		GpuParamDataDesc* getParamDesc(const String& name) const;
 		GpuParamDataDesc* getParamDesc(const String& name) const;
+
+		/**
+		 * @brief	Calculates size and offsets used when splitting a large memory chunk into separate buffers.
+		 *			Parameter counts must have been previously assigned.
+		 */
+		void getInternalBufferData(UINT32& bufferSize, UINT32& paramBlockOffset, UINT32& paramBlockBufferOffset,
+			UINT32& textureOffset, UINT32& samplerStateOffset) const;
 	};
 	};
 
 
 	/**
 	/**

+ 59 - 17
BansheeCore/Source/BsGpuParams.cpp

@@ -39,26 +39,19 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Allocate everything in a single block of memory to get rid of extra memory allocations
 		// Allocate everything in a single block of memory to get rid of extra memory allocations
-		UINT32 paramBlockBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlock*);
-		UINT32 paramBlockBuffersBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
-		UINT32 textureBufferSize = mInternalData->mNumTextures * sizeof(HTexture);
-		UINT32 samplerStateBufferSize = mInternalData->mNumSamplerStates * sizeof(HSamplerState);
+		UINT32 bufferSize = 0;
+		UINT32 paramBlockOffset = 0;
+		UINT32 paramBlockBufferOffset = 0;
+		UINT32 textureOffset = 0;
+		UINT32 samplerStateOffset = 0;
 
 
-		UINT32 bufferSize = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize;
+		getInternalBufferData(bufferSize, paramBlockOffset, paramBlockBufferOffset, textureOffset, samplerStateOffset);
 
 
 		mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
 		mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
-		
-		UINT8* dataIter = mInternalData->mData;
-		mInternalData->mParamBlocks = (GpuParamBlock**)dataIter;
-		dataIter += paramBlockBufferSize;
-
-		mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)dataIter;
-		dataIter += paramBlockBuffersBufferSize;
-
-		mInternalData->mTextures = (HTexture*)dataIter;
-		dataIter += textureBufferSize;
-
-		mInternalData->mSamplerStates = (HSamplerState*)dataIter;
+		mInternalData->mParamBlocks = (GpuParamBlock**)(mInternalData->mData + paramBlockOffset);
+		mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)(mInternalData->mData + paramBlockBufferOffset);
+		mInternalData->mTextures = (HTexture*)(mInternalData->mData + textureOffset);
+		mInternalData->mSamplerStates = (HSamplerState*)(mInternalData->mData + samplerStateOffset);
 
 
 		// Ensure everything is constructed
 		// Ensure everything is constructed
 		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
 		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
@@ -82,6 +75,12 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	GpuParams::GpuParams(GpuParamDesc& paramDesc, PrivatelyConstruct& dummy)
+		:mParamDesc(paramDesc)
+	{
+		mInternalData = bs_shared_ptr<GpuParamsInternalData>();
+	}
+
 	GpuParams::~GpuParams()
 	GpuParams::~GpuParams()
 	{
 	{
 		mInternalData->mIsDestroyed = true;
 		mInternalData->mIsDestroyed = true;
@@ -206,4 +205,47 @@ namespace BansheeEngine
 
 
 		return nullptr;
 		return nullptr;
 	}
 	}
+
+	GpuParamsPtr GpuParams::clone() const
+	{
+		GpuParamsPtr myClone = bs_shared_ptr<GpuParams>(mParamDesc, PrivatelyConstruct());
+		myClone->mInternalData->mIsDestroyed = mInternalData->mIsDestroyed;
+		myClone->mInternalData->mTransposeMatrices = mInternalData->mTransposeMatrices;
+		myClone->mInternalData->mNumParamBlocks = mInternalData->mNumParamBlocks;
+		myClone->mInternalData->mNumTextures = mInternalData->mNumTextures;
+		myClone->mInternalData->mNumSamplerStates = mInternalData->mNumSamplerStates;
+
+		UINT32 bufferSize = 0;
+		UINT32 paramBlockOffset = 0;
+		UINT32 paramBlockBufferOffset = 0;
+		UINT32 textureOffset = 0;
+		UINT32 samplerStateOffset = 0;
+
+		getInternalBufferData(bufferSize, paramBlockOffset, paramBlockBufferOffset, textureOffset, samplerStateOffset);
+
+		myClone->mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
+		memcpy(myClone->mInternalData->mData, mInternalData->mData, bufferSize);
+
+		myClone->mInternalData->mParamBlocks = (GpuParamBlock**)(myClone->mInternalData->mData + paramBlockOffset);
+		myClone->mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)(myClone->mInternalData->mData + paramBlockBufferOffset);
+		myClone->mInternalData->mTextures = (HTexture*)(myClone->mInternalData->mData + textureOffset);
+		myClone->mInternalData->mSamplerStates = (HSamplerState*)(myClone->mInternalData->mData + samplerStateOffset);
+
+		return myClone;
+	}
+
+	void GpuParams::getInternalBufferData(UINT32& bufferSize, UINT32& paramBlockOffset, UINT32& paramBlockBufferOffset,
+		UINT32& textureOffset, UINT32& samplerStateOffset) const
+	{
+		UINT32 paramBlockBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlock*);
+		UINT32 paramBlockBuffersBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
+		UINT32 textureBufferSize = mInternalData->mNumTextures * sizeof(HTexture);
+		UINT32 samplerStateBufferSize = mInternalData->mNumSamplerStates * sizeof(HSamplerState);
+
+		bufferSize = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize;
+		paramBlockOffset = 0;
+		paramBlockBufferOffset = paramBlockOffset + paramBlockBufferSize;
+		textureOffset = paramBlockBufferOffset + paramBlockBuffersBufferSize;
+		samplerStateOffset = textureOffset + textureBufferSize;
+	}
 }
 }