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

GpuParams no longer cache gpu param handles

Marko Pintera 11 жил өмнө
parent
commit
93b8d47960

+ 77 - 124
BansheeCore/Include/BsGpuParam.h

@@ -10,6 +10,40 @@
 
 namespace BansheeEngine
 {
+	struct GpuParamsInternalData;
+
+	/**
+	 * @brief	Base class containing some non-templated methods for
+	 *			GpuDataParam.
+	 *
+	 * @see		TGpuDataParam
+	 */
+	class BS_CORE_EXPORT GpuDataParamBase
+	{
+	protected:
+		GpuDataParamBase();
+		GpuDataParamBase(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
+
+		/**
+		 * @brief	Checks if the gpu param is still valid or were the parent GpuParams destroyed.
+		 */
+		bool getIsDestroyed() const;
+
+		/**
+		 * @brief	Gets a parameter block at the specified slot index.
+		 */
+		GpuParamBlock* getParamBlock(UINT32 slotIdx) const;
+
+		/**
+		 * @brief	Returns true if matrices need to be transposed when reading/writing them.
+		 */
+		bool getTransposeMatrices() const;
+
+	protected:
+		GpuParamDataDesc* mParamDesc;
+		std::shared_ptr<GpuParamsInternalData> mInternalData;
+	};
+
 	/**
 	 * @brief	A handle that allows you to set a GpuProgram parameter. Internally keeps a reference to the 
 	 *			GPU parameter buffer and the necessary offsets. You should specialize this type for specific 
@@ -30,33 +64,11 @@ namespace BansheeEngine
 	 * @note	Sim thread only.
 	 */
 	template<class T>
-	class BS_CORE_EXPORT GpuDataParamBase
+	class BS_CORE_EXPORT TGpuDataParam : public GpuDataParamBase
 	{
 	private:
 		friend class GpuParams;
 
-		/**
-		 * @brief	Internal data that is shared between GpuDataParam instances.
-		 */
-		struct InternalData
-		{
-			InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks, bool transpose)
-				:paramDesc(paramDesc), paramBlocks(paramBlocks), transpose(transpose), isDestroyed(false)
-			{ }
-
-			InternalData()
-				:paramDesc(nullptr), paramBlocks(nullptr), transpose(false), isDestroyed(true)
-			{ }
-
-			~InternalData()
-			{ }
-
-			GpuParamDataDesc* paramDesc;
-			GpuParamBlock** paramBlocks;
-			bool transpose;
-			bool isDestroyed;
-		};
-
 		/**
 		 * @brief	Policy class that allows us to re-use this template class for matrices which might
 		 *			need transposing, and other types which do not. Matrix needs to be transposed for
@@ -90,8 +102,7 @@ namespace BansheeEngine
 		};
 
 	public:
-		GpuDataParamBase()
-			:mData(bs_shared_ptr<InternalData>())
+		TGpuDataParam()
 		{ }
 
 		/**
@@ -103,36 +114,34 @@ namespace BansheeEngine
 		 */
 		void set(const T& value, UINT32 arrayIdx = 0)
 		{
-			if(mData->isDestroyed)
+			if (getIsDestroyed())
 				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-			GpuParamDataDesc* paramDesc = mData->paramDesc;
-
 #if BS_DEBUG_MODE
-			if(arrayIdx >= paramDesc->arraySize)
+			if (arrayIdx >= mParamDesc->arraySize)
 			{
 				BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-					toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
+					toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
 			}
 #endif
 
-			UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
+			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); // Truncate if it doesn't fit within parameter size
-			GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
+			GpuParamBlock* paramBlock = getParamBlock(mParamDesc->paramBlockSlot);
 
-			if(TransposePolicy<T>::transposeEnabled(mData->transpose))
+			if (TransposePolicy<T>::transposeEnabled(getTransposeMatrices()))
 			{
 				T transposed = TransposePolicy<T>::transpose(value);
-				paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
+				paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
 			}
 			else
-				paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
+				paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
 
 			// Set unused bytes to 0
 			if(sizeBytes < elementSizeBytes)
 			{
 				UINT32 diffSize = elementSizeBytes - sizeBytes;
-				paramBlock->zeroOut((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride)  * sizeof(UINT32) + sizeBytes, diffSize);
+				paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32)+sizeBytes, diffSize);
 			}
 		}
 
@@ -144,56 +153,42 @@ namespace BansheeEngine
 		 */
 		T get(UINT32 arrayIdx = 0)
 		{
-			if(mData->isDestroyed)
+			if (getIsDestroyed())
 				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-			GpuParamDataDesc* paramDesc = mData->paramDesc;
-
 #if BS_DEBUG_MODE
-			if(arrayIdx >= paramDesc->arraySize)
+			if (arrayIdx >= mParamDesc->arraySize)
 			{
 				BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-					toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
+					toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
 			}
 #endif
 
-			UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
+			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T));
-			GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
+			GpuParamBlock* paramBlock = getParamBlock(mParamDesc->paramBlockSlot);
 
 			T value;
-			paramBlock->read((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
+			paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
 
-			if(TransposePolicy<T>::transposeEnabled(mData->transpose))
+			if (TransposePolicy<T>::transposeEnabled(getTransposeMatrices()))
 				return TransposePolicy<T>::transpose(value);
 			else
 				return value;
 		}
 
-		/**
-		 * @brief	Called by the material when this handle is no longer valid (shader changed or material
-		 *			got destroyed).
-		 */
-		void _destroy()
-		{
-			mData->isDestroyed = true;
-		}
-
 	private:
-		GpuDataParamBase(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks, bool transpose)
-			:mData(bs_shared_ptr<InternalData>(paramDesc, paramBlocks, transpose))
+		TGpuDataParam(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
+			:GpuDataParamBase(paramDesc, internalData)
 		{ }
-
-	private:
-		std::shared_ptr<InternalData> mData;
 	};
 
-	typedef GpuDataParamBase<float> GpuParamFloat;
-	typedef GpuDataParamBase<Vector2> GpuParamVec2;
-	typedef GpuDataParamBase<Vector3> GpuParamVec3;
-	typedef GpuDataParamBase<Vector4> GpuParamVec4;
-	typedef GpuDataParamBase<Matrix3> GpuParamMat3;
-	typedef GpuDataParamBase<Matrix4> GpuParamMat4;
+	typedef TGpuDataParam<float> GpuParamFloat;
+	typedef TGpuDataParam<Vector2> GpuParamVec2;
+	typedef TGpuDataParam<Vector3> GpuParamVec3;
+	typedef TGpuDataParam<Vector4> GpuParamVec4;
+	typedef TGpuDataParam<Matrix3> GpuParamMat3;
+	typedef TGpuDataParam<Matrix4> GpuParamMat4;
 
 	/**
 	 * @copydoc GpuDataParamBase
@@ -203,17 +198,6 @@ namespace BansheeEngine
 	private:
 		friend class GpuParams;
 
-		struct InternalData
-		{
-			InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks);
-			InternalData();
-			~InternalData();
-
-			GpuParamDataDesc* paramDesc;
-			GpuParamBlock** paramBlocks;
-			bool isDestroyed;
-		};
-
 	public:
 		GpuParamStruct();
 
@@ -232,15 +216,12 @@ namespace BansheeEngine
 		 */
 		UINT32 getElementSize() const;
 
-		/**
-		 * @copydoc	GpuDataParamBase::_destroy
-		 */
-		void _destroy();
 	private:
-		GpuParamStruct(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks);
+		GpuParamStruct(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
 
 	private:
-		std::shared_ptr<InternalData> mData;
+		GpuParamDataDesc* mParamDesc;
+		std::shared_ptr<GpuParamsInternalData> mInternalData;
 	};
 
 	/**
@@ -251,39 +232,25 @@ namespace BansheeEngine
 	private:
 		friend class GpuParams;
 
-		struct InternalData
-		{
-			InternalData(GpuParamObjectDesc* paramDesc, HTexture* textures);
-			InternalData();
-			~InternalData();
-
-			GpuParamObjectDesc* paramDesc;
-			HTexture* textures;
-			bool isDestroyed;
-		};
-
 	public:
 		GpuParamTexture();
 
 		/**
-		* @copydoc	GpuDataParamBase::set
-		*/
+		 * @copydoc	GpuDataParamBase::set
+		 */
 		void set(const HTexture& texture);
 
 		/**
-		* @copydoc	GpuDataParamBase::get
-		*/
+		 * @copydoc	GpuDataParamBase::get
+		 */
 		HTexture get();
 		
-		/**
-		* @copydoc	GpuDataParamBase::_destroy
-		*/
-		void _destroy();
 	private:
-		GpuParamTexture(GpuParamObjectDesc* paramDesc, HTexture* textures);
+		GpuParamTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
 
 	private:
-		std::shared_ptr<InternalData> mData;
+		GpuParamObjectDesc* mParamDesc;
+		std::shared_ptr<GpuParamsInternalData> mInternalData;
 	};
 
 	/**
@@ -294,38 +261,24 @@ namespace BansheeEngine
 	private:
 		friend class GpuParams;
 
-		struct InternalData
-		{
-			InternalData(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates);
-			InternalData();
-			~InternalData();
-
-			GpuParamObjectDesc* paramDesc;
-			HSamplerState* samplerStates;
-			bool isDestroyed;
-		};
-
 	public:
 		GpuParamSampState();
 
 		/**
-		* @copydoc	GpuDataParamBase::set
-		*/
+		 * @copydoc	GpuDataParamBase::set
+		 */
 		void set(const HSamplerState& texture);
 
 		/**
-		* @copydoc	GpuDataParamBase::get
-		*/
+		 * @copydoc	GpuDataParamBase::get
+		 */
 		HSamplerState get();
 
-		/**
-		* @copydoc	GpuDataParamBase::_destroy
-		*/
-		void _destroy();
 	private:
-		GpuParamSampState(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates);
+		GpuParamSampState(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
 
 	private:
-		std::shared_ptr<InternalData> mData;
+		GpuParamObjectDesc* mParamDesc;
+		std::shared_ptr<GpuParamsInternalData> mInternalData;
 	};
 }

+ 45 - 41
BansheeCore/Include/BsGpuParams.h

@@ -6,6 +6,8 @@
 
 namespace BansheeEngine
 {
+	struct GpuParamsInternalData;
+
 	/**
 	 * @brief	Contains descriptions for all parameters in a GPU program and also
 	 *			allows you to write and read those parameters. All parameter values
@@ -47,7 +49,7 @@ namespace BansheeEngine
 		 * @brief	Replaces the parameter buffer with the specified name. Any following parameter reads or
 		 *			writes that are referencing that buffer will use the new buffer.
 		 *
-		 * @note		This is useful if you want to share a parameter buffer among multiple GPU programs.
+		 * @note	This is useful if you want to share a parameter buffer among multiple GPU programs.
 		 *			You would only set the values once and then share the buffer among all other GpuParams.
 		 *
 		 *			It is up to the caller to guarantee the provided buffer matches parameter block
@@ -95,7 +97,7 @@ namespace BansheeEngine
 		 *
 		 *			Parameter handles will be invalidated when their parent GpuParams object changes.
 		 */
-		template<class T> void getParam(const String& name, GpuDataParamBase<T>& output) const
+		template<class T> void getParam(const String& name, TGpuDataParam<T>& output) const
 		{
 			BS_EXCEPT(InvalidParametersException, "Unsupported parameter type");
 		}
@@ -104,84 +106,84 @@ namespace BansheeEngine
 		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
 		 */
 		template<>
-		void getParam<float>(const String& name, GpuDataParamBase<float>& output) const
+		void getParam<float>(const String& name, TGpuDataParam<float>& output) const
 		{
-			auto iterFind = mFloatParams.find(name);
+			auto iterFind = mParamDesc.params.find(name);
 
-			if(iterFind == mFloatParams.end())
+			if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_FLOAT1)
 				BS_EXCEPT(InvalidParametersException, "Cannot find float parameter with the name '" + name + "'");
 
-			output = iterFind->second;
+			output = GpuParamFloat(&iterFind->second, mInternalData);
 		}
 
 		/**
 		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
 		*/
 		template<>
-		void getParam<Vector2>(const String& name, GpuDataParamBase<Vector2>& output) const
+		void getParam<Vector2>(const String& name, TGpuDataParam<Vector2>& output) const
 		{
-			auto iterFind = mVec2Params.find(name);
+			auto iterFind = mParamDesc.params.find(name);
 
-			if(iterFind == mVec2Params.end())
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector(2) parameter with the name '" + name + "'");
+			if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_FLOAT2)
+				BS_EXCEPT(InvalidParametersException, "Cannot find vector (2) parameter with the name '" + name + "'");
 
-			output = iterFind->second;
+			output = GpuParamVec2(&iterFind->second, mInternalData);
 		}
 
 		/**
 		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
 		*/
 		template<>
-		void getParam<Vector3>(const String& name, GpuDataParamBase<Vector3>& output) const
+		void getParam<Vector3>(const String& name, TGpuDataParam<Vector3>& output) const
 		{
-			auto iterFind = mVec3Params.find(name);
+			auto iterFind = mParamDesc.params.find(name);
 
-			if(iterFind == mVec3Params.end())
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector(3) parameter with the name '" + name + "'");
+			if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_FLOAT3)
+				BS_EXCEPT(InvalidParametersException, "Cannot find vector (3) parameter with the name '" + name + "'");
 
-			output = iterFind->second;
+			output = GpuParamVec3(&iterFind->second, mInternalData);
 		}
 
 		/**
 		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
 		*/
 		template<>
-		void getParam<Vector4>(const String& name, GpuDataParamBase<Vector4>& output) const
+		void getParam<Vector4>(const String& name, TGpuDataParam<Vector4>& output) const
 		{
-			auto iterFind = mVec4Params.find(name);
+			auto iterFind = mParamDesc.params.find(name);
 
-			if(iterFind == mVec4Params.end())
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector(4) parameter with the name '" + name + "'");
+			if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_FLOAT4)
+				BS_EXCEPT(InvalidParametersException, "Cannot find vector (4) parameter with the name '" + name + "'");
 
-			output = iterFind->second;
+			output = GpuParamVec4(&iterFind->second, mInternalData);
 		}
 
 		/**
 		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
 		*/
 		template<>
-		void getParam<Matrix3>(const String& name, GpuDataParamBase<Matrix3>& output) const
+		void getParam<Matrix3>(const String& name, TGpuDataParam<Matrix3>& output) const
 		{
-			auto iterFind = mMat3Params.find(name);
+			auto iterFind = mParamDesc.params.find(name);
 
-			if(iterFind == mMat3Params.end())
-				BS_EXCEPT(InvalidParametersException, "Cannot find matrix(3x3) parameter with the name '" + name + "'");
+			if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_MATRIX_3X3)
+				BS_EXCEPT(InvalidParametersException, "Cannot find matrix (3x3) parameter with the name '" + name + "'");
 
-			output = iterFind->second;
+			output = GpuParamMat3(&iterFind->second, mInternalData);
 		}
 
 		/**
 		* @copydoc	getParam(const String&, GpuDataParamBase<T>&)
 		*/
 		template<>
-		void getParam<Matrix4>(const String& name, GpuDataParamBase<Matrix4>& output) const
+		void getParam<Matrix4>(const String& name, TGpuDataParam<Matrix4>& output) const
 		{
-			auto iterFind = mMat4Params.find(name);
+			auto iterFind = mParamDesc.params.find(name);
 
-			if(iterFind == mMat4Params.end())
-				BS_EXCEPT(InvalidParametersException, "Cannot find matrix(4x4) parameter with the name '" + name + "'");
+			if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_MATRIX_4X4)
+				BS_EXCEPT(InvalidParametersException, "Cannot find matrix (4x4) parameter with the name '" + name + "'");
 
-			output = iterFind->second;
+			output = GpuParamMat4(&iterFind->second, mInternalData);
 		}
 
 		/**
@@ -202,13 +204,22 @@ namespace BansheeEngine
 	private:
 		friend class BindableGpuParams;
 
+	private:
 		GpuParamDesc& mParamDesc;
-		bool mTransposeMatrices;
+		std::shared_ptr<GpuParamsInternalData> mInternalData;
 
 		/**
 		 * @brief	Gets a descriptor for a data parameter with the specified name.
 		 */
 		GpuParamDataDesc* getParamDesc(const String& name) const;
+	};
+
+	/**
+	 * @brief	Structure used for storing GpuParams internal data.
+	 */
+	struct GpuParamsInternalData
+	{
+		GpuParamsInternalData();
 
 		UINT8* mData;
 
@@ -221,14 +232,7 @@ namespace BansheeEngine
 		HTexture* mTextures;
 		HSamplerState* mSamplerStates;
 
-		mutable Map<String, GpuParamFloat> mFloatParams;
-		mutable Map<String, GpuParamVec2> mVec2Params;
-		mutable Map<String, GpuParamVec3> mVec3Params;
-		mutable Map<String, GpuParamVec4> mVec4Params;
-		mutable Map<String, GpuParamMat3> mMat3Params;
-		mutable Map<String, GpuParamMat4> mMat4Params;
-		mutable Map<String, GpuParamStruct> mStructParams;
-		mutable Map<String, GpuParamTexture> mTextureParams;
-		mutable Map<String, GpuParamSampState> mSampStateParams;
+		bool mTransposeMatrices;
+		bool mIsDestroyed;
 	};
 }

+ 1 - 1
BansheeCore/Include/BsMaterial.h

@@ -408,7 +408,7 @@ namespace BansheeEngine
 		 * 			caller to keep track of that.
 		 */
 		template <typename T>
-		void getParam(const String& name, GpuDataParamBase<T>& output) const
+		void getParam(const String& name, TGpuDataParam<T>& output) const
 		{
 			throwIfNotInitialized();
 

+ 16 - 16
BansheeCore/Source/BsBindableGpuParams.cpp

@@ -13,22 +13,22 @@ namespace BansheeEngine
 		mNumTextures(0), mNumSamplerStates(0),mParamBlocks(nullptr), mParamBlockBuffers(nullptr), mTextures(nullptr), mSamplerStates(nullptr)
 	{
 		// Allocate everything in a single block of memory to get rid of extra memory allocations
-		UINT32 paramBlockBufferSize = params->mNumParamBlocks * sizeof(BindableGpuParamBlock*);
-		UINT32 paramBlockBuffersBufferSize = params->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
-		UINT32 textureBufferSize = params->mNumTextures * sizeof(HTexture);
-		UINT32 samplerStateBufferSize = params->mNumSamplerStates * sizeof(HSamplerState);
+		UINT32 paramBlockBufferSize = params->mInternalData->mNumParamBlocks * sizeof(BindableGpuParamBlock*);
+		UINT32 paramBlockBuffersBufferSize = params->mInternalData->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
+		UINT32 textureBufferSize = params->mInternalData->mNumTextures * sizeof(HTexture);
+		UINT32 samplerStateBufferSize = params->mInternalData->mNumSamplerStates * sizeof(HSamplerState);
 
 		UINT32 bufferSize = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize;
-		for(UINT32 i = 0; i < params->mNumParamBlocks; i++)
+		for (UINT32 i = 0; i < params->mInternalData->mNumParamBlocks; i++)
 		{
-			if(params->mParamBlockBuffers[i] != nullptr)
-				bufferSize += sizeof(BindableGpuParamBlock) + params->mParamBlockBuffers[i]->getSize();
+			if (params->mInternalData->mParamBlockBuffers[i] != nullptr)
+				bufferSize += sizeof(BindableGpuParamBlock)+params->mInternalData->mParamBlockBuffers[i]->getSize();
 		}
 
 		mData = (UINT8*)allocator->alloc(bufferSize);
-		mNumParamBlocks = params->mNumParamBlocks;
-		mNumTextures = params->mNumTextures;
-		mNumSamplerStates = params->mNumSamplerStates;
+		mNumParamBlocks = params->mInternalData->mNumParamBlocks;
+		mNumTextures = params->mInternalData->mNumTextures;
+		mNumSamplerStates = params->mInternalData->mNumSamplerStates;
 
 		UINT8* dataIter = mData;
 		mParamBlocks = (BindableGpuParamBlock**)dataIter;
@@ -44,15 +44,15 @@ namespace BansheeEngine
 		dataIter += samplerStateBufferSize;
 
 		// Copy data
-		memcpy(mParamBlockBuffers, params->mParamBlockBuffers, paramBlockBuffersBufferSize);
-		memcpy(mTextures, params->mTextures, textureBufferSize);
-		memcpy(mSamplerStates, params->mSamplerStates, samplerStateBufferSize);
+		memcpy(mParamBlockBuffers, params->mInternalData->mParamBlockBuffers, paramBlockBuffersBufferSize);
+		memcpy(mTextures, params->mInternalData->mTextures, textureBufferSize);
+		memcpy(mSamplerStates, params->mInternalData->mSamplerStates, samplerStateBufferSize);
 
-		for(UINT32 i = 0; i < params->mNumParamBlocks; i++)
+		for (UINT32 i = 0; i < params->mInternalData->mNumParamBlocks; i++)
 		{
-			if(params->mParamBlockBuffers[i] != nullptr)
+			if (params->mInternalData->mParamBlockBuffers[i] != nullptr)
 			{
-				GpuParamBlock* paramBlock = params->mParamBlockBuffers[i]->getParamBlock();
+				GpuParamBlock* paramBlock = params->mInternalData->mParamBlockBuffers[i]->getParamBlock();
 
 				UINT32 bufferSize = paramBlock->getSize();
 				mParamBlocks[i] = (BindableGpuParamBlock*)dataIter;

+ 55 - 82
BansheeCore/Source/BsGpuParam.cpp

@@ -1,37 +1,49 @@
 #include "BsGpuParam.h"
+#include "BsGpuParams.h"
 
 namespace BansheeEngine
 {
-	/************************************************************************/
-	/* 									STRUCT	                     		*/
-	/************************************************************************/
-
-	GpuParamStruct::InternalData::InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks)
-		:paramDesc(paramDesc), paramBlocks(paramBlocks), isDestroyed(false)
+	GpuDataParamBase::GpuDataParamBase()
+		:mParamDesc(nullptr)
 	{ }
 
-	GpuParamStruct::InternalData::InternalData()
-		:paramDesc(nullptr), paramBlocks(nullptr), isDestroyed(true)
+	GpuDataParamBase::GpuDataParamBase(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
+		:mParamDesc(paramDesc), mInternalData(internalData)
 	{ }
 
-	GpuParamStruct::InternalData::~InternalData()
-	{ }
+	bool GpuDataParamBase::getIsDestroyed() const
+	{
+		return mInternalData->mIsDestroyed;
+	}
+
+	GpuParamBlock* GpuDataParamBase::getParamBlock(UINT32 slotIdx) const
+	{
+		return mInternalData->mParamBlocks[slotIdx];
+	}
+
+	bool GpuDataParamBase::getTransposeMatrices() const
+	{
+		return mInternalData->mTransposeMatrices;
+	}
+
+	/************************************************************************/
+	/* 									STRUCT	                     		*/
+	/************************************************************************/
 
 	GpuParamStruct::GpuParamStruct()
-		:mData(bs_shared_ptr<InternalData>())
+		:mParamDesc(nullptr)
 	{ }
 
-	GpuParamStruct::GpuParamStruct(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks)
-		:mData(bs_shared_ptr<InternalData>(paramDesc, paramBlocks))
+	GpuParamStruct::GpuParamStruct(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
+		:mParamDesc(paramDesc), mInternalData(internalData)
 	{ }
 
 	void GpuParamStruct::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
-		if(mData->isDestroyed)
+		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		GpuParamDataDesc* paramDesc = mData->paramDesc;
-		UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
+		UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 
 #if BS_DEBUG_MODE
 		if(sizeBytes > elementSizeBytes)
@@ -40,33 +52,32 @@ namespace BansheeEngine
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 		}
 
-		if(arrayIdx >= paramDesc->arraySize)
+		if (arrayIdx >= mParamDesc->arraySize)
 		{
 			BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-				toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
+				toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
 		}
 #endif
 
 		sizeBytes = std::min(elementSizeBytes, sizeBytes);
 
-		GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
-		paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
+		GpuParamBlock* paramBlock = mInternalData->mParamBlocks[mParamDesc->paramBlockSlot];
+		paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
 
 		// Set unused bytes to 0
 		if(sizeBytes < elementSizeBytes)
 		{
 			UINT32 diffSize = elementSizeBytes - sizeBytes;
-			paramBlock->zeroOut((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride)  * sizeof(UINT32) + sizeBytes, diffSize);
+			paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32)+sizeBytes, diffSize);
 		}
 	}
 
 	void GpuParamStruct::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
-		if(mData->isDestroyed)
+		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		GpuParamDataDesc* paramDesc = mData->paramDesc;
-		UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
+		UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 
 #if BS_DEBUG_MODE
 		if(sizeBytes > elementSizeBytes)
@@ -75,117 +86,79 @@ namespace BansheeEngine
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 		}
 
-		if(arrayIdx >= paramDesc->arraySize)
+		if (arrayIdx >= mParamDesc->arraySize)
 		{
 			BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-				toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
+				toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
 		}
 #endif
 		sizeBytes = std::min(elementSizeBytes, sizeBytes);
 
-		GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
-		paramBlock->read((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
+		GpuParamBlock* paramBlock = mInternalData->mParamBlocks[mParamDesc->paramBlockSlot];
+		paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
 	}
 
 	UINT32 GpuParamStruct::getElementSize() const
 	{
-		if(mData->isDestroyed)
+		if(mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		GpuParamDataDesc* paramDesc = mData->paramDesc;
-		return paramDesc->elementSize * sizeof(UINT32);
-	}
-
-	void GpuParamStruct::_destroy()
-	{
-		mData->isDestroyed = true;
+		return mParamDesc->elementSize * sizeof(UINT32);
 	}
 
 	/************************************************************************/
 	/* 								TEXTURE		                     		*/
 	/************************************************************************/
 
-	GpuParamTexture::InternalData::InternalData(GpuParamObjectDesc* paramDesc, HTexture* textures)
-		:paramDesc(paramDesc), textures(textures), isDestroyed(false)
-	{ }
-
-	GpuParamTexture::InternalData::InternalData()
-		:paramDesc(nullptr), textures(nullptr), isDestroyed(true)
-	{ }
-
-	GpuParamTexture::InternalData::~InternalData()
-	{ }
-
 	GpuParamTexture::GpuParamTexture()
-		:mData(bs_shared_ptr<InternalData>())
+		:mParamDesc(nullptr)
 	{ }
 
-	GpuParamTexture::GpuParamTexture(GpuParamObjectDesc* paramDesc, HTexture* textures)
-		:mData(bs_shared_ptr<InternalData>(paramDesc, textures))
+	GpuParamTexture::GpuParamTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
+		: mParamDesc(paramDesc), mInternalData(internalData)
 	{ }
 
 	void GpuParamTexture::set(const HTexture& texture)
 	{
-		if(mData->isDestroyed)
+		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		mData->textures[mData->paramDesc->slot] = texture;
+		mInternalData->mTextures[mParamDesc->slot] = texture;
 	}
 
 	HTexture GpuParamTexture::get()
 	{
-		if(mData->isDestroyed)
+		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		return mData->textures[mData->paramDesc->slot];
-	}
-
-	void GpuParamTexture::_destroy()
-	{
-		mData->isDestroyed = true;
+		return mInternalData->mTextures[mParamDesc->slot];
 	}
 
 	/************************************************************************/
 	/* 								SAMPLER STATE                      		*/
 	/************************************************************************/
 
-	GpuParamSampState::InternalData::InternalData(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates)
-		:paramDesc(paramDesc), samplerStates(samplerStates), isDestroyed(false)
-	{ }
-
-	GpuParamSampState::InternalData::InternalData()
-		:paramDesc(nullptr), samplerStates(nullptr), isDestroyed(true)
-	{ }
-
-	GpuParamSampState::InternalData::~InternalData()
-	{ }
-
 	GpuParamSampState::GpuParamSampState()
-		:mData(bs_shared_ptr<InternalData>())
+		:mParamDesc(nullptr)
 	{ }
 
-	GpuParamSampState::GpuParamSampState(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates)
-		:mData(bs_shared_ptr<InternalData>(paramDesc, samplerStates))
+	GpuParamSampState::GpuParamSampState(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
+		: mParamDesc(nullptr), mInternalData(internalData)
 	{ }
 
 	void GpuParamSampState::set(const HSamplerState& samplerState)
 	{
-		if(mData->isDestroyed)
+		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		mData->samplerStates[mData->paramDesc->slot] = samplerState;
+		mInternalData->mSamplerStates[mParamDesc->slot] = samplerState;
 	}
 
 	HSamplerState GpuParamSampState::get()
 	{
-		if(mData->isDestroyed)
+		if (mInternalData->mIsDestroyed)
 			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
 
-		return mData->samplerStates[mData->paramDesc->slot];
-	}
-
-	void GpuParamSampState::_destroy()
-	{
-		mData->isDestroyed = true;
+		return mInternalData->mSamplerStates[mParamDesc->slot];
 	}
 }

+ 58 - 112
BansheeCore/Source/BsGpuParams.cpp

@@ -9,162 +9,108 @@
 
 namespace BansheeEngine
 {
-	GpuParams::GpuParams(GpuParamDesc& paramDesc, bool transposeMatrices)
-		:mParamDesc(paramDesc), mTransposeMatrices(transposeMatrices), mData(nullptr), mNumParamBlocks(0), mNumTextures(0), mNumSamplerStates(0),
+	GpuParamsInternalData::GpuParamsInternalData()
+		:mTransposeMatrices(false), mData(nullptr), mNumParamBlocks(0), mNumTextures(0), mNumSamplerStates(0),
 		mParamBlocks(nullptr), mParamBlockBuffers(nullptr), mTextures(nullptr), mSamplerStates(nullptr)
+	{ }
+
+	GpuParams::GpuParams(GpuParamDesc& paramDesc, bool transposeMatrices)
+		:mParamDesc(paramDesc)
 	{
+		mInternalData = bs_shared_ptr<GpuParamsInternalData>();
+		mInternalData->mTransposeMatrices = transposeMatrices;
+
 		for(auto& paramBlock : mParamDesc.paramBlocks)
 		{
-			if((paramBlock.second.slot + 1) > mNumParamBlocks)
-				mNumParamBlocks = paramBlock.second.slot + 1;
+			if ((paramBlock.second.slot + 1) > mInternalData->mNumParamBlocks)
+				mInternalData->mNumParamBlocks = paramBlock.second.slot + 1;
 		}
 
 		for(auto& texture : mParamDesc.textures)
 		{
-			if((texture.second.slot + 1) > mNumTextures)
-				mNumTextures = texture.second.slot + 1;
+			if ((texture.second.slot + 1) > mInternalData->mNumTextures)
+				mInternalData->mNumTextures = texture.second.slot + 1;
 		}
 
 		for(auto& sampler : mParamDesc.samplers)
 		{
-			if((sampler.second.slot + 1) > mNumSamplerStates)
-				mNumSamplerStates = sampler.second.slot + 1;
+			if ((sampler.second.slot + 1) > mInternalData->mNumSamplerStates)
+				mInternalData->mNumSamplerStates = sampler.second.slot + 1;
 		}
 
 		// Allocate everything in a single block of memory to get rid of extra memory allocations
-		UINT32 paramBlockBufferSize = mNumParamBlocks * sizeof(GpuParamBlock*);
-		UINT32 paramBlockBuffersBufferSize = mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
-		UINT32 textureBufferSize = mNumTextures * sizeof(HTexture);
-		UINT32 samplerStateBufferSize = mNumSamplerStates * sizeof(HSamplerState);
+		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 = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize;
 
-		mData = (UINT8*)bs_alloc(bufferSize);
+		mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
 		
-		UINT8* dataIter = mData;
-		mParamBlocks = (GpuParamBlock**)dataIter;
+		UINT8* dataIter = mInternalData->mData;
+		mInternalData->mParamBlocks = (GpuParamBlock**)dataIter;
 		dataIter += paramBlockBufferSize;
 
-		mParamBlockBuffers = (GpuParamBlockBufferPtr*)dataIter;
+		mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)dataIter;
 		dataIter += paramBlockBuffersBufferSize;
 
-		mTextures = (HTexture*)dataIter;
+		mInternalData->mTextures = (HTexture*)dataIter;
 		dataIter += textureBufferSize;
 
-		mSamplerStates = (HSamplerState*)dataIter;
+		mInternalData->mSamplerStates = (HSamplerState*)dataIter;
 
 		// Ensure everything is constructed
-		for(UINT32 i = 0; i < mNumParamBlocks; i++)
+		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
 		{
-			mParamBlocks[i] = nullptr;
-
-			GpuParamBlockBufferPtr* ptrToIdx = (&mParamBlockBuffers[i]);
-			ptrToIdx = new (&mParamBlockBuffers[i]) GpuParamBlockBufferPtr(nullptr);
-		}
+			mInternalData->mParamBlocks[i] = nullptr;
 
-		for(UINT32 i = 0; i < mNumTextures; i++)
-		{
-			HTexture* ptrToIdx = (&mTextures[i]);
-			ptrToIdx = new (&mTextures[i]) HTexture();
+			GpuParamBlockBufferPtr* ptrToIdx = (&mInternalData->mParamBlockBuffers[i]);
+			ptrToIdx = new (&mInternalData->mParamBlockBuffers[i]) GpuParamBlockBufferPtr(nullptr);
 		}
 
-		for(UINT32 i = 0; i < mNumSamplerStates; i++)
+		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
 		{
-			HSamplerState* ptrToIdx = (&mSamplerStates[i]);
-			ptrToIdx = new (&mSamplerStates[i]) HSamplerState();
+			HTexture* ptrToIdx = (&mInternalData->mTextures[i]);
+			ptrToIdx = new (&mInternalData->mTextures[i]) HTexture();
 		}
 
-		// Create parameter handles
-		for(auto& param : mParamDesc.params)
+		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
 		{
-			switch(param.second.type)
-			{
-			case GPDT_FLOAT1:
-				mFloatParams[param.second.name] = GpuParamFloat(&param.second, mParamBlocks, mTransposeMatrices);
-				break;
-			case GPDT_FLOAT2:
-				mVec2Params[param.second.name] = GpuParamVec2(&param.second, mParamBlocks, mTransposeMatrices);
-				break;
-			case GPDT_FLOAT3:
-				mVec3Params[param.second.name] = GpuParamVec3(&param.second, mParamBlocks, mTransposeMatrices);
-				break;
-			case GPDT_FLOAT4:
-				mVec4Params[param.second.name] = GpuParamVec4(&param.second, mParamBlocks, mTransposeMatrices);
-				break;
-			case GPDT_MATRIX_3X3:
-				mMat3Params[param.second.name] = GpuParamMat3(&param.second, mParamBlocks, mTransposeMatrices);
-				break;
-			case GPDT_MATRIX_4X4:
-				mMat4Params[param.second.name] = GpuParamMat4(&param.second, mParamBlocks, mTransposeMatrices);
-				break;
-			case GPDT_STRUCT:
-				mStructParams[param.second.name] = GpuParamStruct(&param.second, mParamBlocks);
-				break;
-			}
+			HSamplerState* ptrToIdx = (&mInternalData->mSamplerStates[i]);
+			ptrToIdx = new (&mInternalData->mSamplerStates[i]) HSamplerState();
 		}
-
-		for(auto& texture : mParamDesc.textures)
-			mTextureParams[texture.second.name] = GpuParamTexture(&texture.second, mTextures);
-
-		for(auto& sampler : mParamDesc.samplers)
-			mSampStateParams[sampler.second.name] = GpuParamSampState(&sampler.second, mSamplerStates);
 	}
 
 	GpuParams::~GpuParams()
 	{
-		// Free params
-		for(auto& param : mFloatParams)
-			param.second._destroy();
-
-		for(auto& param : mVec2Params)
-			param.second._destroy();
-
-		for(auto& param : mVec3Params)
-			param.second._destroy();
-
-		for(auto& param : mVec4Params)
-			param.second._destroy();
-
-		for(auto& param : mMat3Params)
-			param.second._destroy();
-
-		for(auto& param : mMat4Params)
-			param.second._destroy();
-
-		for(auto& param : mStructParams)
-			param.second._destroy();
-
-		for(auto& param : mTextureParams)
-			param.second._destroy();
-
-		for(auto& param : mSampStateParams)
-			param.second._destroy();
+		mInternalData->mIsDestroyed = true;
 
 		// Ensure everything is destructed
-		for(UINT32 i = 0; i < mNumParamBlocks; i++)
+		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
 		{
-			mParamBlockBuffers[i].~shared_ptr();
+			mInternalData->mParamBlockBuffers[i].~shared_ptr();
 		}
 
-		for(UINT32 i = 0; i < mNumTextures; i++)
-			mTextures[i].~ResourceHandle();
+		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
+			mInternalData->mTextures[i].~ResourceHandle();
 
-		for(UINT32 i = 0; i < mNumSamplerStates; i++)
-			mSamplerStates[i].~ResourceHandle();
+		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
+			mInternalData->mSamplerStates[i].~ResourceHandle();
 
-		bs_free(mData);
+		bs_free(mInternalData->mData);
 	}
 
 	void GpuParams::setParamBlockBuffer(UINT32 slot, const GpuParamBlockBufferPtr& paramBlockBuffer)
 	{
-		if(slot < 0 || slot >= mNumParamBlocks)
+		if (slot < 0 || slot >= mInternalData->mNumParamBlocks)
 		{
 			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " + 
-				toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
+				toString(mInternalData->mNumParamBlocks - 1) + ". Requested: " + toString(slot));
 		}
 
-		mParamBlockBuffers[slot] = paramBlockBuffer;
-		mParamBlocks[slot] = paramBlockBuffer->getParamBlock();
+		mInternalData->mParamBlockBuffers[slot] = paramBlockBuffer;
+		mInternalData->mParamBlocks[slot] = paramBlockBuffer->getParamBlock();
 	}
 
 	void GpuParams::setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer)
@@ -177,8 +123,8 @@ namespace BansheeEngine
 			return;
 		}
 
-		mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
-		mParamBlocks[iterFind->second.slot] = paramBlockBuffer->getParamBlock();
+		mInternalData->mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
+		mInternalData->mParamBlocks[iterFind->second.slot] = paramBlockBuffer->getParamBlock();
 	}
 
 	UINT32 GpuParams::getDataParamSize(const String& name) const
@@ -224,32 +170,32 @@ namespace BansheeEngine
 
 	void GpuParams::getStructParam(const String& name, GpuParamStruct& output) const
 	{
-		auto iterFind = mStructParams.find(name);
+		auto iterFind = mParamDesc.params.find(name);
 
-		if(iterFind == mStructParams.end())
+		if (iterFind == mParamDesc.params.end() || iterFind->second.type != GPDT_STRUCT)
 			BS_EXCEPT(InvalidParametersException, "Cannot find struct parameter with the name '" + name + "'");
 
-		output = iterFind->second;
+		output = GpuParamStruct(&iterFind->second, mInternalData);
 	}
 
 	void GpuParams::getTextureParam(const String& name, GpuParamTexture& output) const
 	{
-		auto iterFind = mTextureParams.find(name);
+		auto iterFind = mParamDesc.textures.find(name);
 
-		if(iterFind == mTextureParams.end())
+		if (iterFind == mParamDesc.textures.end())
 			BS_EXCEPT(InvalidParametersException, "Cannot find texture parameter with the name '" + name + "'");
 
-		output = iterFind->second;
+		output = GpuParamTexture(&iterFind->second, mInternalData);
 	}
 
 	void GpuParams::getSamplerStateParam(const String& name, GpuParamSampState& output) const
 	{
-		auto iterFind = mSampStateParams.find(name);
+		auto iterFind = mParamDesc.samplers.find(name);
 
-		if(iterFind == mSampStateParams.end())
+		if (iterFind == mParamDesc.samplers.end())
 			BS_EXCEPT(InvalidParametersException, "Cannot find sampler state parameter with the name '" + name + "'");
 
-		output = iterFind->second;
+		output = GpuParamSampState(&iterFind->second, mInternalData);
 	}
 
 	GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const

+ 9 - 9
BansheeCore/Source/BsMaterial.cpp

@@ -112,13 +112,13 @@ namespace BansheeEngine
 			const Map<String, SHADER_PARAM_BLOCK_DESC>& shaderDesc = mShader->_getParamBlocks();
 			for(auto iter = validShareableParamBlocks.begin(); iter != validShareableParamBlocks.end(); ++iter)
 			{
-				bool isShared = false;
+				bool createBlockBuffer = true;
 				GpuParamBlockUsage usage = GPBU_STATIC;
 
 				auto iterFind = shaderDesc.find(*iter);
 				if(iterFind != shaderDesc.end())
 				{
-					isShared = iterFind->second.shared;
+					createBlockBuffer = !iterFind->second.shared && iterFind->second.rendererSemantic == 0;
 					usage = iterFind->second.usage;
 				}
 
@@ -135,7 +135,7 @@ namespace BansheeEngine
 				}
 
 				GpuParamBlockBufferPtr newParamBlockBuffer;
-				if(!isShared)
+				if(createBlockBuffer)
 				{
 					newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(blockDesc.blockSize * sizeof(UINT32), usage);
 					mParamBuffers.push_back(newParamBlockBuffer);
@@ -532,7 +532,7 @@ namespace BansheeEngine
 
 	GpuParamFloat Material::getParamFloat(const String& name) const
 	{
-		GpuDataParamBase<float> gpuParam;
+		TGpuDataParam<float> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -540,7 +540,7 @@ namespace BansheeEngine
 
 	GpuParamVec2 Material::getParamVec2(const String& name) const
 	{
-		GpuDataParamBase<Vector2> gpuParam;
+		TGpuDataParam<Vector2> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -548,7 +548,7 @@ namespace BansheeEngine
 
 	GpuParamVec3 Material::getParamVec3(const String& name) const
 	{
-		GpuDataParamBase<Vector3> gpuParam;
+		TGpuDataParam<Vector3> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -556,7 +556,7 @@ namespace BansheeEngine
 
 	GpuParamVec4 Material::getParamVec4(const String& name) const
 	{
-		GpuDataParamBase<Vector4> gpuParam;
+		TGpuDataParam<Vector4> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -564,7 +564,7 @@ namespace BansheeEngine
 
 	GpuParamMat3 Material::getParamMat3(const String& name) const
 	{
-		GpuDataParamBase<Matrix3> gpuParam;
+		TGpuDataParam<Matrix3> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -572,7 +572,7 @@ namespace BansheeEngine
 
 	GpuParamMat4 Material::getParamMat4(const String& name) const
 	{
-		GpuDataParamBase<Matrix4> gpuParam;
+		TGpuDataParam<Matrix4> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;

+ 2 - 0
Renderer.txt

@@ -1,6 +1,8 @@
 Get renderer to run
  - Go through TODOs on BansheeRenderer
  - What happens to MeshRenderData when mesh is destroyed? It contains a callback to Mesh, so I must ensure it outlives it.
+   - Just keep a reference to the MeshPtr instead of that notify callback.
+   - OR just notify MeshRenderData on Mesh destruction (And make it use a shared ptr)
  - How to clean up RenderableProxies in Renderer?
  - Even though I allocate material proxies with frame alloc I think I still need to free them for debug purposes