Ver código fonte

Added sync methods to material params

BearishSun 9 anos atrás
pai
commit
8b5a233303

+ 2 - 1
Source/BansheeCore/Include/BsCorePrerequisites.h

@@ -530,7 +530,8 @@ namespace BansheeEngine
 		TID_CAnimation = 1122,
 		TID_AnimationEvent = 1123,
 		TID_ImportedAnimationEvents = 1124,
-		TID_CBone = 1125
+		TID_CBone = 1125,
+		TID_MaterialParamData = 1126
 	};
 }
 

+ 60 - 17
Source/BansheeCore/Include/BsMaterialParams.h

@@ -6,14 +6,6 @@
 #include "BsIReflectable.h"
 #include "BsStaticAlloc.h"
 #include "BsVector2.h"
-#include "BsVector3.h"
-#include "BsVector4.h"
-#include "BsVector2I.h"
-#include "BsVectorNI.h"
-#include "BsColor.h"
-#include "BsMatrix3.h"
-#include "BsMatrix4.h"
-#include "BsMatrixNxM.h"
 #include "BsGpuParams.h"
 
 namespace BansheeEngine
@@ -51,6 +43,7 @@ namespace BansheeEngine
 			GpuParamDataType dataType;
 			UINT32 index;
 			UINT32 arraySize;
+			UINT32 dirtyFlags;
 		};
 
 		/** 
@@ -149,7 +142,7 @@ namespace BansheeEngine
 		void reportGetParamError(GetParamResult errorCode, const String& name, UINT32 arrayIdx) const;
 
 		/**
-		 * Equivalent to getStructData(const String&, UINT32, T&) except it uses the internal parameter index
+		 * Equivalent to getDataParam(const String&, UINT32, T&) except it uses the internal parameter index
 		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
 		 */
 		template <typename T>
@@ -183,7 +176,8 @@ namespace BansheeEngine
 	protected:
 		const static UINT32 STATIC_BUFFER_SIZE = 256;
 
-		UnorderedMap<String, ParamData> mParams;
+		UnorderedMap<String, UINT32> mParamLookup;
+		Vector<ParamData> mParams;
 
 		UINT8* mDataParamsBuffer = nullptr;
 
@@ -238,6 +232,34 @@ namespace BansheeEngine
 		RTTITypeBase* getRTTI() const override;
 	};
 
+	/** Data for a single buffer parameter. */
+	class BS_CORE_EXPORT MaterialParamBufferDataCore
+	{
+	public:
+		SPtr<GpuBufferCore> value;
+	};
+
+	/** Data for a single buffer parameter. */
+	class BS_CORE_EXPORT MaterialParamBufferData
+	{
+	public:
+		SPtr<GpuBuffer> value;
+	};
+
+	/** Data for a single sampler state parameter. */
+	class BS_CORE_EXPORT MaterialParamSamplerStateDataCore
+	{
+	public:
+		SPtr<SamplerStateCore> value;
+	};
+
+	/** Data for a single sampler state parameter. */
+	class BS_CORE_EXPORT MaterialParamSamplerStateData
+	{
+	public:
+		SPtr<SamplerState> value;
+	};
+
 	/** Helper typedefs that reference types used by either core or sim thread implementation of TMaterialParams<Core>. */
 	template<bool Core> struct TMaterialParamsTypes { };
 	template<> struct TMaterialParamsTypes < false >
@@ -249,6 +271,8 @@ namespace BansheeEngine
 		typedef SPtr<GpuParamBlockBuffer> ParamsBufferType;
 		typedef MaterialParamStructData StructParamDataType;
 		typedef MaterialParamTextureData TextureParamDataType;
+		typedef MaterialParamBufferData BufferParamDataType;
+		typedef MaterialParamSamplerStateData SamplerStateParamDataType;
 		typedef HShader ShaderType;
 	};
 
@@ -261,6 +285,8 @@ namespace BansheeEngine
 		typedef SPtr<GpuParamBlockBufferCore> ParamsBufferType;
 		typedef MaterialParamStructDataCore StructParamDataType;
 		typedef MaterialParamTextureDataCore TextureParamDataType;
+		typedef MaterialParamBufferDataCore BufferParamDataType;
+		typedef MaterialParamSamplerStateDataCore SamplerStateParamDataType;
 		typedef SPtr<ShaderCore> ShaderType;
 	};
 
@@ -273,10 +299,11 @@ namespace BansheeEngine
 		typedef typename TMaterialParamsTypes<Core>::TextureType TextureType;
 		typedef typename TMaterialParamsTypes<Core>::BufferType BufferType;
 		typedef typename TMaterialParamsTypes<Core>::SamplerType SamplerType;
-		typedef typename TMaterialParamsTypes<Core>::ParamsBufferType ParamsBufferType;
 		typedef typename TMaterialParamsTypes<Core>::ShaderType ShaderType;
 		typedef typename TMaterialParamsTypes<Core>::StructParamDataType ParamStructDataType;
 		typedef typename TMaterialParamsTypes<Core>::TextureParamDataType ParamTextureDataType;
+		typedef typename TMaterialParamsTypes<Core>::BufferParamDataType ParamBufferDataType;
+		typedef typename TMaterialParamsTypes<Core>::SamplerStateParamDataType ParamSamplerStateDataType;
 
 		/** Creates a new material params object and initializes enough room for parameters from the provided shader. */
 		TMaterialParams(const ShaderType& shader);
@@ -469,8 +496,8 @@ namespace BansheeEngine
 	protected:
 		ParamStructDataType* mStructParams = nullptr;
 		ParamTextureDataType* mTextureParams = nullptr;
-		BufferType* mBufferParams = nullptr;
-		SamplerType* mSamplerStateParams = nullptr;
+		ParamBufferDataType* mBufferParams = nullptr;
+		ParamSamplerStateDataType* mSamplerStateParams = nullptr;
 		TextureType* mDefaultTextureParams = nullptr;
 		SamplerType* mDefaultSamplerStateParams = nullptr;
 	};
@@ -481,6 +508,15 @@ namespace BansheeEngine
 	public:
 		/** @copydoc TMaterialParams<Core>::TMaterialParams */
 		MaterialParamsCore(const SPtr<ShaderCore>& shader);
+
+		/** 
+		 * Updates the stored parameters from the provided buffer, allowing changed to be transfered between the sim and 
+		 * core thread material param objects. Buffer must be retrieved from MaterialParams::getSyncData. 
+		 *
+		 * @param[in]		buffer		Buffer containing the dirty data.
+		 * @param[in, out]	size		Size of the provided buffer.
+		 */
+		void setSyncData(UINT8* buffer, UINT32 size);
 	};
 
 	/** 
@@ -504,6 +540,17 @@ namespace BansheeEngine
 		/** @copydoc TMaterialParams<Core>::TMaterialParams */
 		MaterialParams(const HShader& shader);
 
+		/** 
+		 * Populates the provided buffer with parameters that can be used for syncing this object with its core-thread
+		 * counterpart. Can be applied by calling MaterialParamsCore::setSyncData.
+		 *
+		 * @param[in]		buffer		Pre-allocated buffer to store the sync data in. Set to null to calculate the size
+		 *								of the required buffer.
+		 * @param[in, out]	size		Size of the provided allocated buffer. Or if the buffer is null, this parameter will
+		 *								contain the required buffer size when the method executes.
+		 */
+		void getSyncData(UINT8* buffer, UINT32& size);
+
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
@@ -515,9 +562,5 @@ namespace BansheeEngine
 		RTTITypeBase* getRTTI() const override;
 	};
 
-	/** @cond SPECIALIZATIONS */
-	BS_ALLOW_MEMCPY_SERIALIZATION(MaterialParamsBase::ParamData);
-	/** @endcond */
-
 	/** @} */
 }

+ 44 - 7
Source/BansheeCore/Include/BsMaterialParamsRTTI.h

@@ -102,7 +102,10 @@ namespace BansheeEngine
 
 		void setParamData(MaterialParams* obj, UINT32 idx, MaterialParam& param)
 		{
-			obj->mParams[param.name] = param.data;
+			UINT32 paramIdx = (UINT32)obj->mParams.size();
+			obj->mParams.push_back(param.data);
+
+			obj->mParamLookup[param.name] = paramIdx;
 		}
 
 		UINT32 getParamDataArraySize(MaterialParams* obj)
@@ -158,13 +161,13 @@ namespace BansheeEngine
 			obj->mTextureParams = obj->mAlloc.construct<MaterialParamTextureData>(size);
 		}
 
-		SPtr<SamplerState> getSamplerStateParam(MaterialParams* obj, UINT32 idx) { return obj->mSamplerStateParams[idx]; }
-		void setSamplerStateParam(MaterialParams* obj, UINT32 idx, SPtr<SamplerState> param) { obj->mSamplerStateParams[idx] = param; }
+		SPtr<SamplerState> getSamplerStateParam(MaterialParams* obj, UINT32 idx) { return obj->mSamplerStateParams[idx].value; }
+		void setSamplerStateParam(MaterialParams* obj, UINT32 idx, SPtr<SamplerState> param) { obj->mSamplerStateParams[idx].value = param; }
 		UINT32 getSamplerStateArraySize(MaterialParams* obj) { return (UINT32)obj->mNumSamplerParams; }
 		void setSamplerStateArraySize(MaterialParams* obj, UINT32 size)
 		{
 			obj->mNumSamplerParams = size;
-			obj->mSamplerStateParams = obj->mAlloc.construct<SPtr<SamplerState>>(size);
+			obj->mSamplerStateParams = obj->mAlloc.construct<MaterialParamSamplerStateData>(size);
 		}
 
 		MaterialParamsRTTI()
@@ -187,10 +190,13 @@ namespace BansheeEngine
 		void onSerializationStarted(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
 		{
 			MaterialParams* paramsObj = static_cast<MaterialParams*>(obj);
-			Vector<MaterialParam> matParams;
 
-			for(auto& entry : paramsObj->mParams)
-				matParams.push_back({ entry.first, entry.second });
+			Vector<MaterialParam> matParams;
+			for (auto& entry : paramsObj->mParamLookup)
+			{
+				UINT32 paramIdx = entry.second;
+				matParams.push_back({ entry.first, paramsObj->mParams[paramIdx] });
+			}
 
 			paramsObj->mRTTIData = matParams;
 		}
@@ -218,6 +224,37 @@ namespace BansheeEngine
 		}
 	};
 
+	template<> struct RTTIPlainType<MaterialParamsBase::ParamData>
+	{
+		enum { id = TID_MaterialParamData }; enum { hasDynamicSize = 0 };
+
+		static void toMemory(const MaterialParamsBase::ParamData& data, char* memory)
+		{
+			memory = rttiWriteElem(data.type, memory);
+			memory = rttiWriteElem(data.dataType, memory);
+			memory = rttiWriteElem(data.index, memory);
+			memory = rttiWriteElem(data.arraySize, memory);
+		}
+
+		static UINT32 fromMemory(MaterialParamsBase::ParamData& data, char* memory)
+		{
+			UINT32 size = 0;
+			memory = rttiReadElem(data.type, memory, size);
+			memory = rttiReadElem(data.dataType, memory, size);
+			memory = rttiReadElem(data.index, memory, size);
+			memory = rttiReadElem(data.arraySize, memory, size);
+			data.dirtyFlags = (UINT32)-1;
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const MaterialParamsBase::ParamData& data)
+		{
+			assert(false);
+			return 0;
+		}
+	};
+
 	template<> struct RTTIPlainType<MaterialParamsRTTI::MaterialParam>
 	{	
 		enum { id = TID_MaterialRTTIParam }; enum { hasDynamicSize = 1 };

+ 265 - 14
Source/BansheeCore/Source/BsMaterialParams.cpp

@@ -3,6 +3,9 @@
 #include "BsMaterialParams.h"
 #include "BsMaterialParamsRTTI.h"
 #include "BsShader.h"
+#include "BsTexture.h"
+#include "BsGpuBuffer.h"
+#include "BsSamplerState.h"
 
 namespace BansheeEngine
 {
@@ -37,12 +40,17 @@ namespace BansheeEngine
 
 		for (auto& entry : dataParams)
 		{
-			ParamData& dataParam = mParams[entry.first];
+			UINT32 paramIdx = (UINT32)mParams.size();
+			mParams.push_back(ParamData());
+			mParamLookup[entry.first] = paramIdx;
+
+			ParamData& dataParam = mParams.back();
 
 			UINT32 arraySize = entry.second.arraySize > 1 ? entry.second.arraySize : 1;
 			dataParam.arraySize = arraySize;
 			dataParam.type = ParamType::Data;
 			dataParam.dataType = entry.second.type;
+			dataParam.dirtyFlags = (UINT32)-1;
 
 			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)dataParam.dataType];
 			UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
@@ -53,36 +61,51 @@ namespace BansheeEngine
 
 		for (auto& entry : textureParams)
 		{
-			ParamData& dataParam = mParams[entry.first];
+			UINT32 paramIdx = (UINT32)mParams.size();
+			mParams.push_back(ParamData());
+			mParamLookup[entry.first] = paramIdx;
+
+			ParamData& dataParam = mParams.back();
 
 			dataParam.arraySize = 1;
 			dataParam.type = ParamType::Texture;
 			dataParam.dataType = GPDT_UNKNOWN;
 			dataParam.index = textureIdx;
+			dataParam.dirtyFlags = (UINT32)-1;
 
 			textureIdx++;
 		}
 
 		for (auto& entry : bufferParams)
 		{
-			ParamData& dataParam = mParams[entry.first];
+			UINT32 paramIdx = (UINT32)mParams.size();
+			mParams.push_back(ParamData());
+			mParamLookup[entry.first] = paramIdx;
+
+			ParamData& dataParam = mParams.back();
 
 			dataParam.arraySize = 1;
 			dataParam.type = ParamType::Buffer;
 			dataParam.dataType = GPDT_UNKNOWN;
 			dataParam.index = bufferIdx;
+			dataParam.dirtyFlags = (UINT32)-1;
 
 			bufferIdx++;
 		}
 
 		for (auto& entry : samplerParams)
 		{
-			ParamData& dataParam = mParams[entry.first];
+			UINT32 paramIdx = (UINT32)mParams.size();
+			mParams.push_back(ParamData());
+			mParamLookup[entry.first] = paramIdx;
+
+			ParamData& dataParam = mParams.back();
 
 			dataParam.arraySize = 1;
 			dataParam.type = ParamType::Sampler;
 			dataParam.dataType = GPDT_UNKNOWN;
 			dataParam.index = samplerIdx;
+			dataParam.dirtyFlags = (UINT32)-1;
 
 			samplerIdx++;
 		}
@@ -98,11 +121,11 @@ namespace BansheeEngine
 	MaterialParamsBase::GetParamResult MaterialParamsBase::getParamData(const String& name, ParamType type, GpuParamDataType dataType,
 		UINT32 arrayIdx, const ParamData** output) const
 	{
-		auto iterFind = mParams.find(name);
-		if (iterFind == mParams.end())
+		auto iterFind = mParamLookup.find(name);
+		if (iterFind == mParamLookup.end())
 			return GetParamResult::NotFound;
 
-		const ParamData& param = iterFind->second;
+		const ParamData& param = mParams[iterFind->second];
 		*output = &param;
 
 		if (param.type != type || (type == ParamType::Data && param.dataType != dataType))
@@ -167,14 +190,13 @@ namespace BansheeEngine
 
 		mStructParams = mAlloc.construct<ParamStructDataType>(mNumStructParams);
 		mTextureParams = mAlloc.construct<ParamTextureDataType>(mNumTextureParams);
-		mBufferParams = mAlloc.construct<BufferType>(mNumBufferParams);
-		mSamplerStateParams = mAlloc.construct<SamplerType>(mNumSamplerParams);
+		mBufferParams = mAlloc.construct<ParamBufferDataType>(mNumBufferParams);
+		mSamplerStateParams = mAlloc.construct<ParamSamplerStateDataType>(mNumSamplerParams);
 		mDefaultTextureParams = mAlloc.construct<TextureType>(mNumTextureParams);
 		mDefaultSamplerStateParams = mAlloc.construct<SamplerType>(mNumSamplerParams);
 
 		UINT32 structIdx = 0;
 		UINT32 textureIdx = 0;
-		UINT32 bufferIdx = 0;
 		UINT32 samplerIdx = 0;
 
 		for (auto& entry : dataParams)
@@ -427,13 +449,13 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParams<Core>::getBuffer(UINT32 index, BufferType& value) const
 	{
-		value = mBufferParams[index];
+		value = mBufferParams[index].value;
 	}
 
 	template<bool Core>
 	void TMaterialParams<Core>::setBuffer(UINT32 index, const BufferType& value)
 	{
-		mBufferParams[index] = value;
+		mBufferParams[index].value = value;
 	}
 
 	template<bool Core>
@@ -462,13 +484,13 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParams<Core>::getSamplerState(UINT32 index, SamplerType& value) const
 	{
-		value = mSamplerStateParams[index];
+		value = mSamplerStateParams[index].value;
 	}
 
 	template<bool Core>
 	void TMaterialParams<Core>::setSamplerState(UINT32 index, const SamplerType& value)
 	{
-		mSamplerStateParams[index] = value;
+		mSamplerStateParams[index].value = value;
 	}
 
 	template<bool Core>
@@ -490,10 +512,239 @@ namespace BansheeEngine
 		:TMaterialParams(shader)
 	{ }
 
+	void MaterialParamsCore::setSyncData(UINT8* buffer, UINT32 size)
+	{
+		char* sourceData = (char*)buffer;
+
+		UINT32 numDirtyDataParams = 0;
+		UINT32 numDirtyTextureParams = 0;
+		UINT32 numDirtyBufferParams = 0;
+		UINT32 numDirtySamplerParams = 0;
+
+		sourceData = rttiReadElem(numDirtyDataParams, sourceData);
+		sourceData = rttiReadElem(numDirtyTextureParams, sourceData);
+		sourceData = rttiReadElem(numDirtyBufferParams, sourceData);
+		sourceData = rttiReadElem(numDirtySamplerParams, sourceData);
+
+		for(UINT32 i = 0; i < numDirtyDataParams; i++)
+		{
+			UINT32 paramIdx = 0;
+			sourceData = rttiReadElem(paramIdx, sourceData);
+
+			ParamData& param = mParams[paramIdx];
+			param.dirtyFlags = 0xFFFFFFFF;
+
+			UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1;
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.type];
+			UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
+			UINT32 dataParamSize = arraySize * paramSize;
+			memcpy(&mDataParamsBuffer[param.index], sourceData, dataParamSize);
+			sourceData += dataParamSize;
+		}
+
+		for(UINT32 i = 0; i < numDirtyTextureParams; i++)
+		{
+			UINT32 paramIdx = 0;
+			sourceData = rttiReadElem(paramIdx, sourceData);
+
+			ParamData& param = mParams[paramIdx];
+			param.dirtyFlags = 0xFFFFFFFF;
+
+			MaterialParamTextureDataCore* sourceTexData = (MaterialParamTextureDataCore*)sourceData;
+			sourceData += sizeof(MaterialParamTextureDataCore);
+
+			mTextureParams[param.index] = *sourceTexData;
+			sourceTexData->~MaterialParamTextureDataCore();
+		}
+
+		for (UINT32 i = 0; i < numDirtyBufferParams; i++)
+		{
+			UINT32 paramIdx = 0;
+			sourceData = rttiReadElem(paramIdx, sourceData);
+
+			ParamData& param = mParams[paramIdx];
+			param.dirtyFlags = 0xFFFFFFFF;
+
+			MaterialParamBufferDataCore* sourceBufferData = (MaterialParamBufferDataCore*)sourceData;
+			sourceData += sizeof(MaterialParamBufferDataCore);
+
+			mBufferParams[param.index] = *sourceBufferData;
+			sourceBufferData->~MaterialParamBufferDataCore();
+		}
+
+		for (UINT32 i = 0; i < numDirtySamplerParams; i++)
+		{
+			UINT32 paramIdx = 0;
+			sourceData = rttiReadElem(paramIdx, sourceData);
+
+			ParamData& param = mParams[paramIdx];
+			param.dirtyFlags = 0xFFFFFFFF;
+
+			MaterialParamSamplerStateDataCore* sourceSamplerStateData = (MaterialParamSamplerStateDataCore*)sourceData;
+			sourceData += sizeof(MaterialParamSamplerStateDataCore);
+
+			mSamplerStateParams[param.index] = *sourceSamplerStateData;
+			sourceSamplerStateData->~MaterialParamSamplerStateDataCore();
+		}
+	}
+
 	MaterialParams::MaterialParams(const HShader& shader)
 		:TMaterialParams(shader)
 	{ }
 
+	void MaterialParams::getSyncData(UINT8* buffer, UINT32& size)
+	{
+		// Note: Not syncing struct data
+
+		UINT32 numDirtyDataParams = 0;
+		UINT32 numDirtyTextureParams = 0;
+		UINT32 numDirtyBufferParams = 0;
+		UINT32 numDirtySamplerParams = 0;
+
+		UINT32 dataParamSize = 0;
+		for(auto& param : mParams)
+		{
+			if (param.dirtyFlags != 0x8000000)
+				continue;
+
+			switch(param.type)
+			{
+			case ParamType::Data:
+			{
+				numDirtyDataParams++;
+
+				UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1;
+				const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.type];
+				UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
+				dataParamSize += arraySize * paramSize;
+			}
+				break;
+			case ParamType::Texture:
+				numDirtyTextureParams++;
+				break;
+			case ParamType::Buffer:
+				numDirtyBufferParams++;
+				break;
+			case ParamType::Sampler:
+				numDirtySamplerParams++;
+				break;
+			}
+		}
+
+		UINT32 textureEntrySize = sizeof(MaterialParamTextureDataCore) + sizeof(UINT32);
+		UINT32 bufferEntrySize = sizeof(MaterialParamBufferDataCore) + sizeof(UINT32);
+		UINT32 samplerStateEntrySize = sizeof(MaterialParamSamplerStateDataCore) + sizeof(UINT32);
+
+		UINT32 dataParamsOffset = sizeof(UINT32) * 4;
+		UINT32 textureParamsOffset = dataParamsOffset + dataParamSize + sizeof(UINT32) * numDirtyDataParams;
+		UINT32 bufferParamsOffset = textureParamsOffset + textureEntrySize * numDirtyTextureParams;
+		UINT32 samplerStateParamsOffset = bufferParamsOffset + bufferEntrySize * numDirtyBufferParams;
+
+		UINT32 totalSize = samplerStateParamsOffset + samplerStateEntrySize * numDirtySamplerParams;
+
+		if (buffer == nullptr)
+		{
+			size = totalSize;
+			return;
+		}
+
+		if(size != totalSize)
+		{
+			LOGERR("Invalid buffer size provided, ignoring.");
+			return;
+		}
+
+		char* writeDest = (char*)buffer;
+		writeDest = rttiWriteElem(numDirtyDataParams, writeDest);
+		writeDest = rttiWriteElem(numDirtyTextureParams, writeDest);
+		writeDest = rttiWriteElem(numDirtyBufferParams, writeDest);
+		writeDest = rttiWriteElem(numDirtySamplerParams, writeDest);
+
+		UINT32 dirtyDataParamOffset = 0;
+		UINT32 dirtyTextureParamIdx = 0;
+		UINT32 dirtyBufferParamIdx = 0;
+		UINT32 dirtySamplerParamIdx = 0;
+
+		for(UINT32 i = 0; i < (UINT32)mParams.size(); i++)
+		{
+			ParamData& param = mParams[i];
+			if (param.dirtyFlags != 0x8000000)
+				continue;
+
+			param.dirtyFlags &= ~0x80000000;
+
+			switch (param.type)
+			{
+			case ParamType::Data:
+			{
+				UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1;
+				const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.type];
+				UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
+				UINT32 dataSize = arraySize * paramSize;
+
+				writeDest = (char*)buffer + dataParamsOffset + dirtyDataParamOffset;
+				writeDest = rttiWriteElem(i, writeDest);
+				memcpy(writeDest, &mDataParamsBuffer[param.index], dataSize);
+				writeDest += dataSize;
+
+				dirtyDataParamOffset += dataSize + sizeof(UINT32);
+			}
+			break;
+			case ParamType::Texture:
+			{
+				writeDest = (char*)buffer + textureParamsOffset + dirtyTextureParamIdx * textureEntrySize;
+				writeDest = rttiWriteElem(i, writeDest);
+
+				const MaterialParamTextureData& textureData = mTextureParams[param.index];
+				MaterialParamTextureDataCore* coreTexData = (MaterialParamTextureDataCore*)writeDest;
+				new (coreTexData) MaterialParamTextureDataCore();
+
+				coreTexData->isLoadStore = textureData.isLoadStore;
+				coreTexData->surface = textureData.surface;
+
+				if (textureData.value.isLoaded())
+					coreTexData->value = textureData.value->getCore();
+
+				dirtyTextureParamIdx++;
+			}
+				break;
+			case ParamType::Buffer:
+			{
+				writeDest = (char*)buffer + bufferParamsOffset + dirtyBufferParamIdx * bufferEntrySize;
+				writeDest = rttiWriteElem(i, writeDest);
+
+				const MaterialParamBufferData& bufferData = mBufferParams[param.index];
+				MaterialParamBufferDataCore* coreBufferData = (MaterialParamBufferDataCore*)writeDest;
+				new (coreBufferData) MaterialParamBufferDataCore();
+
+				if(bufferData.value != nullptr)
+					coreBufferData->value = bufferData.value->getCore();
+
+				dirtyBufferParamIdx++;
+			}
+				break;
+			case ParamType::Sampler:
+			{
+				writeDest = (char*)buffer + samplerStateParamsOffset + dirtySamplerParamIdx * samplerStateEntrySize;
+				writeDest = rttiWriteElem(i, writeDest);
+
+				const MaterialParamSamplerStateData& samplerData = mSamplerStateParams[param.index];
+				MaterialParamSamplerStateDataCore* coreSamplerData = (MaterialParamSamplerStateDataCore*)writeDest;
+				new (coreSamplerData) MaterialParamSamplerStateDataCore();
+
+				if (samplerData.value != nullptr)
+					coreSamplerData->value = samplerData.value->getCore();
+
+				dirtySamplerParamIdx++;
+			}
+				break;
+			}
+		}
+	}
+
 	RTTITypeBase* MaterialParams::getRTTIStatic()
 	{
 		return MaterialParamsRTTI::instance();

+ 3 - 3
Source/BansheeUtility/Include/BsDebug.h

@@ -90,13 +90,13 @@ namespace BansheeEngine
 	BS_UTILITY_EXPORT Debug& gDebug();
 
 /** Shortcut for logging a message in the debug channel. */
-#define LOGDBG(x) BansheeEngine::gDebug().logDebug((x));
+#define LOGDBG(x) BansheeEngine::gDebug().logDebug((x) + String("\t\t in ") + __PRETTY_FUNCTION__ + " [" + __FILE__ + ":" + toString(__LINE__) + "]");
 
 /** Shortcut for logging a message in the warning channel. */
-#define LOGWRN(x) BansheeEngine::gDebug().logWarning((x));
+#define LOGWRN(x) BansheeEngine::gDebug().logWarning((x) + String("\t\t in ") + __PRETTY_FUNCTION__ + " [" + __FILE__ + ":" + toString(__LINE__) + "]");
 
 /** Shortcut for logging a message in the error channel. */
-#define LOGERR(x) BansheeEngine::gDebug().logError((x));
+#define LOGERR(x) BansheeEngine::gDebug().logError((x) + String("\t\t in ") + __PRETTY_FUNCTION__ + " [" + __FILE__ + ":" + toString(__LINE__) + "]");
 
 /** Shortcut for logging a verbose message in the debug channel. Verbose messages can be ignored unlike other log messages. */
 #define LOGDBG_VERBOSE(x)

+ 0 - 5
Source/BansheeUtility/Include/BsException.h

@@ -4,11 +4,6 @@
 
 #include "BsPrerequisitesUtil.h"
 
-#if defined(_MSC_VER)
-#undef __PRETTY_FUNCTION__
-#define __PRETTY_FUNCTION__ __FUNCSIG__
-#endif
-
 namespace BansheeEngine
 {
 	/** @addtogroup Error

+ 3 - 1
Source/BansheeUtility/Include/BsPlatformDefines.h

@@ -42,6 +42,8 @@
 #   define BS_COMPILER BS_COMPILER_MSVC
 #   define BS_COMP_VER _MSC_VER
 #	define BS_THREADLOCAL __declspec(thread)
+#	undef __PRETTY_FUNCTION__
+#	define __PRETTY_FUNCTION__ __FUNCSIG__
 #else
 #   pragma error "No known compiler. "
 
@@ -116,4 +118,4 @@
 #        define BS_THREADLOCAL __thread
 #	endif
 
-#endif
+#endif