Browse Source

GpuParams/GpuParamBlockBuffer refactor WIP

Marko Pintera 11 years ago
parent
commit
c653bed63a
49 changed files with 1440 additions and 1376 deletions
  1. 0 2
      BansheeCore/BansheeCore.vcxproj
  2. 0 6
      BansheeCore/BansheeCore.vcxproj.filters
  3. 1 1
      BansheeCore/Include/BsCorePrerequisites.h
  4. 473 103
      BansheeCore/Include/BsGpuParam.h
  5. 0 84
      BansheeCore/Include/BsGpuParamBlock.h
  6. 78 15
      BansheeCore/Include/BsGpuParamBlockBuffer.h
  7. 377 164
      BansheeCore/Include/BsGpuParams.h
  8. 6 1
      BansheeCore/Include/BsGpuProgram.h
  9. 0 1
      BansheeCore/Include/BsHardwareBufferManager.h
  10. 5 14
      BansheeCore/Include/BsMaterial.h
  11. 18 10
      BansheeCore/Include/BsMaterialParam.h
  12. 3 38
      BansheeCore/Include/BsMaterialProxy.h
  13. 1 1
      BansheeCore/Include/BsRenderSystem.h
  14. 4 2
      BansheeCore/Source/BsCoreApplication.cpp
  15. 1 1
      BansheeCore/Source/BsCoreThreadAccessor.cpp
  16. 130 148
      BansheeCore/Source/BsGpuParam.cpp
  17. 0 90
      BansheeCore/Source/BsGpuParamBlock.cpp
  18. 137 6
      BansheeCore/Source/BsGpuParamBlockBuffer.cpp
  19. 70 335
      BansheeCore/Source/BsGpuParams.cpp
  20. 3 3
      BansheeCore/Source/BsGpuProgram.cpp
  21. 14 131
      BansheeCore/Source/BsMaterial.cpp
  22. 0 32
      BansheeCore/Source/BsMaterialProxy.cpp
  23. 2 2
      BansheeD3D11RenderSystem/Include/BsD3D11GpuParamBlockBuffer.h
  24. 2 2
      BansheeD3D11RenderSystem/Include/BsD3D11GpuProgram.h
  25. 1 1
      BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h
  26. 2 2
      BansheeD3D11RenderSystem/Source/BsD3D11GpuParamBlockBuffer.cpp
  27. 0 6
      BansheeD3D11RenderSystem/Source/BsD3D11GpuProgram.cpp
  28. 10 10
      BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp
  29. 2 2
      BansheeD3D9RenderSystem/Include/BsD3D9GpuProgram.h
  30. 1 1
      BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h
  31. 0 7
      BansheeD3D9RenderSystem/Source/BsD3D9GpuProgram.cpp
  32. 8 10
      BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp
  33. 10 10
      BansheeEditor/Include/BsGizmoManager.h
  34. 2 2
      BansheeEditor/Include/BsHandleDrawManager.h
  35. 9 9
      BansheeEditor/Include/BsScenePicking.h
  36. 8 8
      BansheeEditor/Source/BsGizmoManager.cpp
  37. 2 2
      BansheeEditor/Source/BsHandleDrawManager.cpp
  38. 2 2
      BansheeEditor/Source/BsScenePicking.cpp
  39. 2 2
      BansheeGLRenderSystem/Include/BsGLGpuParamBlockBuffer.h
  40. 1 1
      BansheeGLRenderSystem/Include/BsGLRenderSystem.h
  41. 2 2
      BansheeGLRenderSystem/Source/BsGLGpuParamBlockBuffer.cpp
  42. 11 12
      BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp
  43. 2 2
      BansheeGLRenderSystem/Source/GLSL/include/BsGLSLGpuProgram.h
  44. 0 7
      BansheeGLRenderSystem/Source/GLSL/src/BsGLSLGpuProgram.cpp
  45. 8 8
      BansheeRenderer/Include/BsBansheeLitTexRenderableController.h
  46. 0 11
      BansheeRenderer/Include/BsBansheeRenderer.h
  47. 7 11
      BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp
  48. 0 54
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  49. 25 2
      TODO.txt

+ 0 - 2
BansheeCore/BansheeCore.vcxproj

@@ -335,7 +335,6 @@
     <ClInclude Include="Include\BsFontRTTI.h" />
     <ClInclude Include="Include\BsGpuBuffer.h" />
     <ClInclude Include="Include\BsGpuBufferView.h" />
-    <ClInclude Include="Include\BsGpuParamBlock.h" />
     <ClInclude Include="Include\BsGpuParamDesc.h" />
     <ClInclude Include="Include\BsGpuParams.h" />
     <ClInclude Include="Include\BsGpuProgInclude.h" />
@@ -451,7 +450,6 @@
     <ClCompile Include="Source\BsGameObjectManager.cpp" />
     <ClCompile Include="Source\BsGpuBuffer.cpp" />
     <ClCompile Include="Source\BsGpuBufferView.cpp" />
-    <ClCompile Include="Source\BsGpuParamBlock.cpp" />
     <ClCompile Include="Source\BsGpuParamBlockBuffer.cpp" />
     <ClCompile Include="Source\BsGpuParams.cpp" />
     <ClCompile Include="Source\BsProfilerGPU.cpp" />

+ 0 - 6
BansheeCore/BansheeCore.vcxproj.filters

@@ -375,9 +375,6 @@
     <ClInclude Include="Include\BsGpuParamBlockBuffer.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsGpuParamBlock.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsGpuParam.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
@@ -653,9 +650,6 @@
     <ClCompile Include="Source\BsGpuParam.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsGpuParamBlock.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsGpuParamBlockBuffer.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>

+ 1 - 1
BansheeCore/Include/BsCorePrerequisites.h

@@ -155,6 +155,7 @@ namespace BansheeEngine
 	class VertexDeclarationCore;
 	class GpuBufferCore;
 	class GpuParamBlockBufferCore;
+	class GpuParamsCore;
 	// Asset import
 	class SpecificImporter;
 	class Importer;
@@ -229,7 +230,6 @@ namespace BansheeEngine
 	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
 	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
 	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
-	typedef std::shared_ptr<GpuParamBlock> GpuParamBlockPtr;
 	typedef std::shared_ptr<GpuParamBlockBuffer> GpuParamBlockBufferPtr;
 	typedef std::shared_ptr<GpuParams> GpuParamsPtr;
 	typedef std::shared_ptr<TextureView> TextureViewPtr;

+ 473 - 103
BansheeCore/Include/BsGpuParam.h

@@ -2,7 +2,7 @@
 
 #include "BsCorePrerequisites.h"
 #include "BsGpuParamDesc.h"
-#include "BsGpuParamBlock.h"
+#include "BsGpuParamBlockBuffer.h"
 #include "BsDebug.h"
 #include "BsException.h"
 #include "BsVector2.h"
@@ -14,7 +14,24 @@
 
 namespace BansheeEngine
 {
-	struct GpuParamsInternalData;
+	/**
+	 * @brief	Base class containing some non-templated methods for
+	 *			all types for GpuParams
+	 */
+	class BS_CORE_EXPORT GpuParamBase
+	{
+	protected:
+		GpuParamBase();
+		GpuParamBase(const SPtr<GpuParams>& parent);
+
+		/**
+		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
+		 */
+		void markCoreDirty();
+
+	protected:
+		SPtr<GpuParams> mParent;
+	};
 
 	/**
 	 * @brief	Base class containing some non-templated methods for
@@ -22,35 +39,231 @@ namespace BansheeEngine
 	 *
 	 * @see		TGpuDataParam
 	 */
-	class BS_CORE_EXPORT GpuDataParamBase
+	class BS_CORE_EXPORT GpuDataParamBase : public GpuParamBase
 	{
 	protected:
 		GpuDataParamBase();
-		GpuDataParamBase(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
+		GpuDataParamBase(GpuParamDataDesc* paramDesc, const SPtr<GpuParams>& parent);
 
 		/**
-		 * @brief	Checks if the gpu param is still valid or were the parent GpuParams destroyed.
+		 * @brief	Returns true if matrices need to be transposed when reading/writing them.
 		 */
-		bool isDestroyed() const;
+		bool getTransposeMatrices() const;
 
 		/**
-		 * @brief	Gets a parameter block at the specified slot index.
+		 * @copydoc	GpuParamBlockBuffer::write
 		 */
-		GpuParamBlockPtr getParamBlock(UINT32 slotIdx) const;
+		bool write(UINT32 offset, const void* data, UINT32 size);
 
 		/**
-		 * @brief	Returns true if matrices need to be transposed when reading/writing them.
+		 * @copydoc	GpuParamBlockBuffer::read
 		 */
-		bool getTransposeMatrices() const;
+		bool read(UINT32 offset, void* data, UINT32 size);
+
+		/**
+		 * @copydoc	GpuParamBlockBuffer::zeroOut
+		 */
+		void zeroOut(UINT32 offset, UINT32 size);
+
+	protected:
+		GpuParamDataDesc* mParamDesc;
+	};
+
+	/**
+	 * @brief	Base class containing some non-templated methods for
+	 *			GpuObjectParam.
+	 *
+	 * @see		TGpuObjectParam
+	 */
+	class BS_CORE_EXPORT GpuObjectParamBase : public GpuParamBase
+	{
+	protected:
+		GpuObjectParamBase();
+		GpuObjectParamBase(GpuParamObjectDesc* paramDesc, const SPtr<GpuParams>& parent);
+
+		/**
+		 * @brief	Gets a texture bound to the specified slot.
+		 */
+		HTexture getTexture(UINT32 slot);
+
+		/**
+		 * @brief	Gets a sampler state bound to the specified slot.
+		 */
+		HSamplerState getSamplerState(UINT32 slot);
+
+		/**
+		 * @brief	Sets a texture at the specified slot.
+		 */
+		void setTexture(UINT32 slot, const HTexture& texture);
+
+		/**
+		 * @brief	Sets a sampler state at the specified slot.
+		 */
+		void setSamplerState(UINT32 slot, const HSamplerState& sampler);
+
+		/**
+		 * @brief	Sets information that determines which texture surfaces to bind
+		 *			as load/store parameters.
+		 */
+		void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
+
+		/**
+		 * @brief	Changes the type of the texture at the specified slot.
+		 */
+		void setIsLoadStoreTexture(UINT32 slot, bool isLoadStore);
+
+	protected:
+		GpuParamObjectDesc* mParamDesc;
+	};
+
+	/**
+	 * @brief	Base class containing some non-templated methods for
+	 *			all types for GpuParamCore params
+	 */
+	class BS_CORE_EXPORT GpuParamCoreBase
+	{
+	protected:
+		GpuParamCoreBase();
+		GpuParamCoreBase(const SPtr<GpuParamsCore>& parent);
 
 		/**
 		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
 		 */
 		void markCoreDirty();
 
+	protected:
+		SPtr<GpuParamsCore> mParent;
+	};
+
+	/**
+	 * @brief	Base class containing some non-templated methods for
+	 *			GpuDataParam.
+	 *
+	 * @see		TGpuDataParam
+	 */
+	class BS_CORE_EXPORT GpuDataParamCoreBase : public GpuParamCoreBase
+	{
+	protected:
+		GpuDataParamCoreBase();
+		GpuDataParamCoreBase(GpuParamDataDesc* paramDesc, const SPtr<GpuParamsCore>& parent);
+
+		/**
+		 * @brief	Returns true if matrices need to be transposed when reading/writing them.
+		 */
+		bool getTransposeMatrices() const;
+
+		/**
+		 * @copydoc	GpuParamBlockBuffer::write
+		 */
+		bool write(UINT32 offset, const void* data, UINT32 size);
+
+		/**
+		 * @copydoc	GpuParamBlockBuffer::read
+		 */
+		bool read(UINT32 offset, void* data, UINT32 size);
+
+		/**
+		 * @copydoc	GpuParamBlockBuffer::zeroOut
+		 */
+		void zeroOut(UINT32 offset, UINT32 size);
+
 	protected:
 		GpuParamDataDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
+	};
+
+	/**
+	 * @brief	Base class containing some non-templated methods for
+	 *			GpuObjectParam.
+	 *
+	 * @see		TGpuObjectParam
+	 */
+	class BS_CORE_EXPORT GpuObjectParamCoreBase : public GpuParamCoreBase
+	{
+	protected:
+		GpuObjectParamCoreBase();
+		GpuObjectParamCoreBase(GpuParamObjectDesc* paramDesc, const SPtr<GpuParamsCore>& parent);
+
+		/**
+		 * @brief	Gets a texture bound to the specified slot.
+		 */
+		SPtr<TextureCore> getTexture(UINT32 slot);
+
+		/**
+		 * @brief	Gets a sampler state bound to the specified slot.
+		 */
+		SPtr<SamplerStateCore> getSamplerState(UINT32 slot);
+
+		/**
+		 * @brief	Sets a texture at the specified slot.
+		 */
+		void setTexture(UINT32 slot, const SPtr<TextureCore>& texture);
+
+		/**
+		 * @brief	Sets a sampler state at the specified slot.
+		 */
+		void setSamplerState(UINT32 slot, const SPtr<SamplerStateCore>& sampler);
+
+		/**
+		 * @brief	Sets information that determines which texture surfaces to bind
+		 *			as load/store parameters.
+		 */
+		void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
+
+		/**
+		 * @brief	Changes the type of the texture at the specified slot.
+		 */
+		void setIsLoadStoreTexture(UINT32 slot, bool isLoadStore);
+
+	protected:
+		GpuParamObjectDesc* mParamDesc;
+	};
+
+	template<bool Core>
+	struct TGpuParamsPtrType
+	{ };
+
+	template<>
+	struct TGpuParamsPtrType<false>
+	{
+		typedef SPtr<GpuParams> Type;
+	};
+
+	template<>
+	struct TGpuParamsPtrType<true>
+	{
+		typedef SPtr<GpuParamsCore> Type;
+	};
+
+	template<bool Core>
+	struct TGpuDataParamBaseType
+	{ };
+
+	template<>
+	struct TGpuDataParamBaseType<false>
+	{ 
+		typedef GpuDataParamBase Type;
+	};
+
+	template<>
+	struct TGpuDataParamBaseType<true>
+	{ 
+		typedef GpuDataParamCoreBase Type;
+	};
+
+	template<bool Core>
+	struct TGpuObjectParamBaseType
+	{ };
+
+	template<>
+	struct TGpuObjectParamBaseType<false>
+	{ 
+		typedef GpuObjectParamBase Type;
+	};
+
+	template<>
+	struct TGpuObjectParamBaseType<true>
+	{ 
+		typedef GpuObjectParamCoreBase Type;
 	};
 
 	/**
@@ -69,15 +282,11 @@ namespace BansheeEngine
 	 *			once and then set the parameter value many times with minimal performance impact.
 	 * 
 	 * @see		Material
-	 *
-	 * @note	Sim thread only.
 	 */
-	template<class T>
-	class BS_CORE_EXPORT TGpuDataParam : public GpuDataParamBase
+	template<class T, bool Core>
+	class BS_CORE_EXPORT TGpuDataParam : public TGpuDataParamBaseType<Core>::Type
 	{
 	private:
-		friend class GpuParams;
-
 		/**
 		 * @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
@@ -114,6 +323,10 @@ namespace BansheeEngine
 		TGpuDataParam()
 		{ }
 
+		TGpuDataParam(GpuParamDataDesc* paramDesc, const typename TGpuParamsPtrType<Core>::Type& parent)
+			:TGpuDataParamBaseType<Core>::Type(paramDesc, parent)
+		{ }
+
 		/**
 		 * @brief	Sets a parameter value at the specified array index. If parameter does not
 		 *			contain an array leave the index at 0.
@@ -123,12 +336,9 @@ namespace BansheeEngine
 		 */
 		void set(const T& value, UINT32 arrayIdx = 0)
 		{
-			if (mInternalData == nullptr)
+			if (mParent == nullptr)
 				return;
 
-			if (isDestroyed())
-				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
 #if BS_DEBUG_MODE
 			if (arrayIdx >= mParamDesc->arraySize)
 			{
@@ -139,24 +349,20 @@ namespace BansheeEngine
 
 			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); // Truncate if it doesn't fit within parameter size
-			GpuParamBlockPtr paramBlock = getParamBlock(mParamDesc->paramBlockSlot);
-
-			if (paramBlock == nullptr)
-				return;
 
 			if (TransposePolicy<T>::transposeEnabled(getTransposeMatrices()))
 			{
 				T transposed = TransposePolicy<T>::transpose(value);
-				paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
+				write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
 			}
 			else
-				paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
+				write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
 
 			// Set unused bytes to 0
 			if(sizeBytes < elementSizeBytes)
 			{
 				UINT32 diffSize = elementSizeBytes - sizeBytes;
-				paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32)+sizeBytes, diffSize);
+				zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32)+sizeBytes, diffSize);
 			}
 
 			markCoreDirty();
@@ -170,12 +376,9 @@ namespace BansheeEngine
 		 */
 		T get(UINT32 arrayIdx = 0)
 		{
-			if (mInternalData == nullptr)
+			if (mParent == nullptr)
 				return T();
 
-			if (isDestroyed())
-				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
 #if BS_DEBUG_MODE
 			if (arrayIdx >= mParamDesc->arraySize)
 			{
@@ -186,160 +389,327 @@ namespace BansheeEngine
 
 			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
 			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T));
-			GpuParamBlockPtr paramBlock = getParamBlock(mParamDesc->paramBlockSlot);
 
-			if (paramBlock == nullptr)
-				return T();
-			
 			T value;
-			paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
+			read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
 
 			if (TransposePolicy<T>::transposeEnabled(getTransposeMatrices()))
 				return TransposePolicy<T>::transpose(value);
 			else
 				return value;
 		}
-
-	private:
-		TGpuDataParam(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-			:GpuDataParamBase(paramDesc, internalData)
-		{ }
 	};
 
-	typedef TGpuDataParam<float> GpuParamFloat;
-	typedef TGpuDataParam<Color> GpuParamColor;
-	typedef TGpuDataParam<Vector2> GpuParamVec2;
-	typedef TGpuDataParam<Vector3> GpuParamVec3;
-	typedef TGpuDataParam<Vector4> GpuParamVec4;
-	typedef TGpuDataParam<Matrix3> GpuParamMat3;
-	typedef TGpuDataParam<Matrix4> GpuParamMat4;
-
-	template class TGpuDataParam<float>;
-	template class TGpuDataParam<Color>;
-	template class TGpuDataParam<Vector2>;
-	template class TGpuDataParam<Vector3>;
-	template class TGpuDataParam<Vector4>;
-	template class TGpuDataParam<Matrix3>;
-	template class TGpuDataParam<Matrix4>;
+	typedef TGpuDataParam<float, false> GpuParamFloat;
+	typedef TGpuDataParam<Color, false> GpuParamColor;
+	typedef TGpuDataParam<Vector2, false> GpuParamVec2;
+	typedef TGpuDataParam<Vector3, false> GpuParamVec3;
+	typedef TGpuDataParam<Vector4, false> GpuParamVec4;
+	typedef TGpuDataParam<Matrix3, false> GpuParamMat3;
+	typedef TGpuDataParam<Matrix4, false> GpuParamMat4;
+
+	template class TGpuDataParam<float, false>;
+	template class TGpuDataParam<Color, false>;
+	template class TGpuDataParam<Vector2, false>;
+	template class TGpuDataParam<Vector3, false>;
+	template class TGpuDataParam<Vector4, false>;
+	template class TGpuDataParam<Matrix3, false>;
+	template class TGpuDataParam<Matrix4, false>;
+
+	typedef TGpuDataParam<float, true> GpuParamFloatCore;
+	typedef TGpuDataParam<Color, true> GpuParamColorCore;
+	typedef TGpuDataParam<Vector2, true> GpuParamVec2Core;
+	typedef TGpuDataParam<Vector3, true> GpuParamVec3Core;
+	typedef TGpuDataParam<Vector4, true> GpuParamVec4Core;
+	typedef TGpuDataParam<Matrix3, true> GpuParamMat3Core;
+	typedef TGpuDataParam<Matrix4, true> GpuParamMat4Core;
+
+	template class TGpuDataParam<float, true>;
+	template class TGpuDataParam<Color, true>;
+	template class TGpuDataParam<Vector2, true>;
+	template class TGpuDataParam<Vector3, true>;
+	template class TGpuDataParam<Vector4, true>;
+	template class TGpuDataParam<Matrix3, true>;
+	template class TGpuDataParam<Matrix4, true>;
 
 	/**
 	 * @copydoc TGpuDataParam
 	 */
-	class BS_CORE_EXPORT GpuParamStruct
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamStruct : public TGpuDataParamBaseType<Core>::Type
 	{
-	private:
-		friend class GpuParams;
-
 	public:
-		GpuParamStruct();
+		TGpuParamStruct()
+		{ }
+
+		TGpuParamStruct(GpuParamDataDesc* paramDesc, const typename TGpuParamsPtrType<Core>::Type& parent)
+			:TGpuDataParamBaseType<Core>::Type(paramDesc, parent)
+		{ }
 
 		/**
 		 * @copydoc	TGpuDataParam::set
 		 */
-		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0)
+		{
+			if (mParent == nullptr)
+				return;
+
+			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
+
+#if BS_DEBUG_MODE
+			if (sizeBytes > elementSizeBytes)
+			{
+				LOGWRN("Provided element size larger than maximum element size. Maximum size: " +
+					toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
+			}
+
+			if (arrayIdx >= mParamDesc->arraySize)
+			{
+				BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
+					toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
+			}
+#endif
+
+			sizeBytes = std::min(elementSizeBytes, sizeBytes);
+
+			write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
+
+			// Set unused bytes to 0
+			if (sizeBytes < elementSizeBytes)
+			{
+				UINT32 diffSize = elementSizeBytes - sizeBytes;
+				zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32) + sizeBytes, diffSize);
+			}
+
+			markCoreDirty();
+		}
 
 		/**
 		 * @copydoc	TGpuDataParam::get
 		 */
-		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0)
+		{
+			if (mParent == nullptr)
+				return;
+
+			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
+
+#if BS_DEBUG_MODE
+			if (sizeBytes > elementSizeBytes)
+			{
+				LOGWRN("Provided element size larger than maximum element size. Maximum size: " +
+					toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
+			}
+
+			if (arrayIdx >= mParamDesc->arraySize)
+			{
+				BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
+					toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
+			}
+#endif
+			sizeBytes = std::min(elementSizeBytes, sizeBytes);
+
+			read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
+		}
+
 
 		/**
 		 * @brief	Returns the size of the struct in bytes.
 		 */
-		UINT32 getElementSize() const;
+		UINT32 getElementSize() const
+		{
+			if (mParent == nullptr)
+				return 0;
 
-	private:
-		GpuParamStruct(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
+			return mParamDesc->elementSize * sizeof(UINT32);
+		}
+	};
 
-	private:
-		GpuParamDataDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
+	typedef TGpuParamStruct<false> GpuParamStruct;
+	typedef TGpuParamStruct<true> GpuParamStructCore;
+
+	template class TGpuParamStruct<false>;
+	template class TGpuParamStruct<true>;
+
+	template<bool Core>
+	struct GpuParamTextureType
+	{ };
+
+	template<>
+	struct GpuParamTextureType<false>
+	{ 
+		typedef HTexture Type;
+	};
+
+	template<>
+	struct GpuParamTextureType<true>
+	{
+		typedef SPtr<TextureCore> Type;
 	};
 
 	/**
-	 * @copydoc TGpuDataParam
+	 * @copydoc TGpuObjectParam
 	 */
-	class BS_CORE_EXPORT GpuParamTexture
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamTexture : public TGpuObjectParamBaseType<Core>::Type
 	{
 	private:
 		friend class GpuParams;
+		friend class GpuParamsCore;
 
 	public:
-		GpuParamTexture();
+		TGpuParamTexture()
+		{ }
+
+		TGpuParamTexture(GpuParamObjectDesc* paramDesc, const typename TGpuParamsPtrType<Core>::Type& parent)
+			:TGpuObjectParamBaseType<Core>::Type(paramDesc, parent)
+		{ }
 
 		/**
 		 * @copydoc	TGpuDataParam::set
 		 */
-		void set(const HTexture& texture);
+		void set(const typename GpuParamTextureType<Core>::Type& texture)
+		{
+			if (mParent == nullptr)
+				return;
+
+			setTexture(mParamDesc->slot, texture);
+			setIsLoadStoreTexture(mParamDesc->slot, false);
+
+			markCoreDirty();
+		}
 
 		/**
 		 * @copydoc	TGpuDataParam::get
 		 */
-		HTexture get();
-		
-	private:
-		GpuParamTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
+		typename GpuParamTextureType<Core>::Type get()
+		{
+			if (mParent == nullptr)
+				return GpuParamTextureType<Core>::Type();
 
-	private:
-		GpuParamObjectDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
+			return getTexture(mParamDesc->slot);
+		}
 	};
 
+	typedef TGpuParamTexture<false> GpuParamTexture;
+	typedef TGpuParamTexture<true> GpuParamTextureCore;
+
+	template class TGpuParamTexture<false>;
+	template class TGpuParamTexture<true>;
+
 	/**
-	 * @copydoc TGpuDataParam
+	 * @copydoc TGpuObjectParam
 	 */
-	class BS_CORE_EXPORT GpuParamLoadStoreTexture
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamLoadStoreTexture : public TGpuObjectParamBaseType<Core>::Type
 	{
 	private:
 		friend class GpuParams;
+		friend class GpuParamsCore;
 
 	public:
-		GpuParamLoadStoreTexture();
+		TGpuParamLoadStoreTexture()
+		{ }
+
+		TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const typename TGpuParamsPtrType<Core>::Type& parent)
+			:TGpuObjectParamBaseType<Core>::Type(paramDesc, parent)
+		{ }
 
 		/**
 		 * @copydoc	TGpuDataParam::set
 		 */
-		void set(const HTexture& texture, const TextureSurface& surface);
+		void set(const typename GpuParamTextureType<Core>::Type& texture, const TextureSurface& surface)
+		{
+			if (mParent == nullptr)
+				return;
+
+			setTexture(mParamDesc->slot, texture);
+			setIsLoadStoreTexture(mParamDesc->slot, true);
+			setLoadStoreSurface(mParamDesc->slot, surface);
+
+			markCoreDirty();
+		}
 
 		/**
 		 * @copydoc	TGpuDataParam::get
 		 */
-		HTexture get();
-		
-	private:
-		GpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
+		typename GpuParamTextureType<Core>::Type get()
+		{
+			if (mParent == nullptr)
+				return GpuParamTextureType<Core>::Type();
 
-	private:
-		GpuParamObjectDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
+			return getTexture(mParamDesc->slot);
+		}
+	};
+
+	typedef TGpuParamLoadStoreTexture<false> GpuParamLoadStoreTexture;
+	typedef TGpuParamLoadStoreTexture<true> GpuParamLoadStoreTextureCore;
+
+	template class TGpuParamLoadStoreTexture<false>;
+	template class TGpuParamLoadStoreTexture<true>;
+
+	template<bool Core>
+	struct GpuParamSamplerStateType
+	{ };
+
+	template<>
+	struct GpuParamSamplerStateType<false>
+	{
+		typedef HSamplerState Type;
+	};
+
+	template<>
+	struct GpuParamSamplerStateType<true>
+	{
+		typedef SPtr<SamplerStateCore> Type;
 	};
 
 	/**
-	 * @copydoc TGpuDataParam
+	 * @copydoc TGpuObjectParam
 	 */
-	class BS_CORE_EXPORT GpuParamSampState
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamSampState : public TGpuObjectParamBaseType<Core>::Type
 	{
 	private:
 		friend class GpuParams;
+		friend class GpuParamsCore;
 
 	public:
-		GpuParamSampState();
+		TGpuParamSampState()
+		{ }
+
+		TGpuParamSampState(GpuParamObjectDesc* paramDesc, const typename TGpuParamsPtrType<Core>::Type& parent)
+			:TGpuObjectParamBaseType<Core>::Type(paramDesc, parent)
+		{ }
 
 		/**
 		 * @copydoc	TGpuDataParam::set
 		 */
-		void set(const HSamplerState& texture);
+		void set(const typename GpuParamSamplerStateType<Core>::Type& samplerState)
+		{
+			if (mParent == nullptr)
+				return;
+
+			setSamplerState(mParamDesc->slot, samplerState);
+
+			markCoreDirty();
+		}
 
 		/**
 		 * @copydoc	TGpuDataParam::get
 		 */
-		HSamplerState get();
-
-	private:
-		GpuParamSampState(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
+		typename GpuParamSamplerStateType<Core>::Type get()
+		{
+			if (mParent == nullptr)
+				return GpuParamSamplerStateType<Core>::Type();
 
-	private:
-		GpuParamObjectDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
+			return getSamplerState(mParamDesc->slot);
+		}
 	};
+
+	typedef TGpuParamSampState<false> GpuParamSampState;
+	typedef TGpuParamSampState<true> GpuParamSampStateCore;
+
+	template class TGpuParamSampState<false>;
+	template class TGpuParamSampState<true>;
 }

+ 0 - 84
BansheeCore/Include/BsGpuParamBlock.h

@@ -1,84 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Stores data (e.g. int, float, Vector2) GPU parameters in a raw buffer. 
-	 *			Used primarily for caching GPU parameters on the CPU before they're submitted 
-	 *			to the actual GPU parameter buffer.
-	 */
-	class BS_CORE_EXPORT GpuParamBlock
-	{
-	public:
-		/**
-		 * @brief	Construct a new parameter block with internal data allocated using the
-		 *			standard allocator.
-		 */
-		GpuParamBlock(UINT32 size);
-
-		/**
-		 * @brief	Construct a new parameter block with internal data allocated using the
-		 *			provided frame allocator. Such blocks must be released the same frame
-		 *			they were allocated on.
-		 */
-		GpuParamBlock(FrameAlloc* alloc, UINT32 size);
-
-		virtual ~GpuParamBlock();
-
-		/**
-		 * @brief	Write some data to the specified offset in the buffer. 
-		 *			Marks the block as dirty.
-		 *			All values are in bytes.
-		 */
-		void write(UINT32 offset, const void* data, UINT32 size);
-
-		/**
-		 * @brief	Read some data from the specified offset in the buffer.
-		 *			All values are in bytes.
-		 */
-		void read(UINT32 offset, void* data, UINT32 size);
-
-		/**
-		 * @brief	Clear specified section of the buffer to zero.
-		 *			All values are in bytes.
-		 */
-		void zeroOut(UINT32 offset, UINT32 size);
-
-		/**
-		 * @brief	Returns size of the internal buffer in bytes.
-		 */
-		UINT32 getSize() const { return mSize; }
-
-		/**
-		 * @brief	Returns a raw pointer to the internal buffer.
-		 */
-		UINT8* getData() const { return mData; }
-
-		/**
-		 * @brief	Uploads the current data to the specified buffer, and marks the block a non-dirty.
-		 * 			
-		 * @note	Core thread only.			
-		 */
-		void uploadToBuffer(const GpuParamBlockBufferPtr& buffer);
-
-		/**
-		 * @brief	Checks if something has been written to the buffer
-		 *			since the last time object was clean.
-		 */
-		bool isDirty() const { return mDirty; }
-
-		/**
-		 * @brief	Marks the object as dirty or clean. Signifies
-		 *			whether or not some new data has been written in the buffer.
-		 */
-		void setDirty(bool dirty) { mDirty = dirty; }
-	protected:
-		UINT8* mData;
-		UINT32 mSize;
-		bool mDirty;
-		FrameAlloc* mAlloc;
-	};
-}

+ 78 - 15
BansheeCore/Include/BsGpuParamBlockBuffer.h

@@ -16,13 +16,13 @@ namespace BansheeEngine
 	{
 	public:
 		GpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage);
-		virtual ~GpuParamBlockBufferCore() { }
+		virtual ~GpuParamBlockBufferCore();
 
 		/**
 		 * @brief	Writes all of the specified data to the buffer.
 		 * 			Data size must be the same size as the buffer;
 		 */
-		virtual void writeData(const UINT8* data) = 0;
+		virtual void writeToGPU(const UINT8* data) = 0;
 
 		/**
 		 * @brief	Copies data from the internal buffer to a pre-allocated array. 
@@ -32,7 +32,37 @@ namespace BansheeEngine
 		 * @param [in,out]	data	Array where the data will be written to. Must be of
 		 * 							"getSize()" bytes.
 		 */
-		virtual void readData(UINT8* data) const = 0;
+		virtual void readFromGPU(UINT8* data) const = 0;
+
+		/**
+		 * @brief	Flushes any cached data into the actual GPU buffer.
+		 */
+		void flushToGPU();
+
+		/**
+		 * @brief	Write some data to the specified offset in the buffer. 
+		 *
+		 * @note	All values are in bytes.
+		 *			Actual hardware buffer update is delayed until rendering.
+		 */
+		void write(UINT32 offset, const void* data, UINT32 size);
+
+		/**
+		 * @brief	Read some data from the specified offset in the buffer.
+		 *			
+		 * @note	All values are in bytes.
+		 *			This reads from the cached CPU buffer. Actual hardware buffer can be read
+		 *			from the core thread.
+		 */
+		void read(UINT32 offset, void* data, UINT32 size);
+
+		/**
+		 * @brief	Clear specified section of the buffer to zero.
+		 *
+		 * @note	All values are in bytes.
+		 *			Actual hardware buffer update is delayed until rendering.
+		 */
+		void zeroOut(UINT32 offset, UINT32 size);
 
 		/**
 		 * @brief	Returns the size of the buffer in bytes.
@@ -40,8 +70,16 @@ namespace BansheeEngine
 		UINT32 getSize() const { return mSize; }
 
 	protected:
+		/**
+		 * @copydoc	CoreObjectCore::syncToCore
+		 */
+		virtual void syncToCore(const CoreSyncData& data);
+
 		GpuParamBlockUsage mUsage;
 		UINT32 mSize;
+
+		UINT8* mCachedData;
+		bool mGPUBufferDirty;
 	};
 
 	/**
@@ -57,21 +95,42 @@ namespace BansheeEngine
 	{
 	public:
 		GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage);
-		virtual ~GpuParamBlockBuffer() { }
+		virtual ~GpuParamBlockBuffer();
 
 		/**
-		 * @brief	Returns the size of the buffer in bytes.
+		 * @brief	Write some data to the specified offset in the buffer. 
+		 *
+		 * @note	All values are in bytes.
+		 *			Actual hardware buffer update is delayed until rendering.
 		 */
-		UINT32 getSize() const { return mSize; }
+		void write(UINT32 offset, const void* data, UINT32 size);
 
 		/**
-		 * @brief	Returns	a parameter block buffer which is used for caching 
-		 *			the parameter information. Essentially a CPU copy of the GPU buffer.
+		 * @brief	Read some data from the specified offset in the buffer.
+		 *			
+		 * @note	All values are in bytes.
+		 *			This reads from the cached CPU buffer. Actual hardware buffer can be read
+		 *			from the core thread.
+		 */
+		void read(UINT32 offset, void* data, UINT32 size);
+
+		/**
+		 * @brief	Clear specified section of the buffer to zero.
 		 *
-		 * @note	Thread safe but it's up to the caller to ensure this is only called from
-		 *			one thread.
+		 * @note	All values are in bytes.
+		 *			Actual hardware buffer update is delayed until rendering.
+		 */
+		void zeroOut(UINT32 offset, UINT32 size);
+
+		/**
+		 * @brief	Returns internal cached data of the buffer.
 		 */
-		GpuParamBlockPtr getParamBlock() const { return mParamBlock; }
+		const UINT8* getCachedData() const { return mCachedData; }
+
+		/**
+		 * @brief	Returns the size of the buffer in bytes.
+		 */
+		UINT32 getSize() const { return mSize; }
 
 		/**
 		 * @brief	Retrieves a core implementation of a GPU param block buffer usable only from the
@@ -90,10 +149,14 @@ namespace BansheeEngine
 		 */
 		SPtr<CoreObjectCore> createCore() const;
 
+		/**
+		 * @copydoc	CoreObject::syncToCore
+		 */
+		virtual CoreSyncData syncToCore(FrameAlloc* allocator);
+
 		GpuParamBlockUsage mUsage;
 		UINT32 mSize;
-
-		GpuParamBlockPtr mParamBlock;
+		UINT8* mCachedData;
 	};
 
 	/**
@@ -108,12 +171,12 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	GpuParamBlockBufferCore::writeData
 		 */
-		void writeData(const UINT8* data);
+		void writeToGPU(const UINT8* data);
 
 		/**
 		 * @copydoc GpuParamBlockBufferCore::readData.
 		 */
-		void readData(UINT8* data) const;
+		void readFromGPU(UINT8* data) const;
 
 	protected:
 		UINT8* mData;

+ 377 - 164
BansheeCore/Include/BsGpuParams.h

@@ -2,6 +2,7 @@
 
 #include "BsCorePrerequisites.h"
 #include "BsGpuParam.h"
+#include "BsCoreObject.h"
 
 namespace BansheeEngine
 {
@@ -21,19 +22,11 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Contains descriptions for all parameters in a GPU program and also
-	 *			allows you to write and read those parameters. All parameter values
-	 *			are stored internally on the CPU, and are only submitted to the GPU
-	 *			once the parameters are bound to the pipeline.
-	 *
-	 * @see		CoreThreadAccessor::bindGpuParams
-	 *
-	 * @note	Sim thread only.
+	 * @brief	Contains functionality common for both sim and core thread
+	 *			version of GpuParams.
 	 */
-	class BS_CORE_EXPORT GpuParams
+	class BS_CORE_EXPORT GpuParamsBase
 	{
-		struct PrivatelyConstruct {};
-
 	public:
 		/**
 		 * @brief	Creates new GpuParams object using the specified parameter descriptions.
@@ -46,43 +39,13 @@ namespace BansheeEngine
 		 *
 		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
 		 */
-		GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
-
-		/**
-		 * @brief	Private constructor for internal use. Performs no initialization.
-		 */
-		GpuParams(const GpuParamDescPtr& paramDesc, PrivatelyConstruct& dummy);
-
-		~GpuParams();
+		GpuParamsBase(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+		virtual ~GpuParamsBase();
 
 		// Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
 		// all the internal buffers too). Trivial to implement but not needed at this time. Un-delete and implement if necessary.
-		GpuParams(const GpuParams& other) = delete;
-		GpuParams& operator=(const GpuParams& rhs) = delete;
-
-		/**
-		 * @brief	Binds a new parameter buffer to the specified slot. Any following parameter reads or
-		 *			writes that are referencing that buffer slot will use the new buffer.
-		 *
-		 * @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
-		 *			descriptor for this slot.
-		 */
-		void setParamBlockBuffer(UINT32 slot, const GpuParamBlockBufferPtr& paramBlockBuffer);
-
-		/**
-		 * @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.
-		 *			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
-		 *			descriptor for this slot.
-		 */
-		void setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer);
+		GpuParamsBase(const GpuParamsBase& other) = delete;
+		GpuParamsBase& operator=(const GpuParamsBase& rhs) = delete;
 
 		/**
 		 * @brief	Returns a description of all stored parameters.
@@ -116,271 +79,521 @@ namespace BansheeEngine
 		bool hasParamBlock(const String& name) const;
 
 		/**
-		 * @brief	Returns a handle for the parameter with the specified name. 
-		 *			Handle may then be stored and used for quickly setting or retrieving
-		 *			values to/from that parameter.
+		 * @brief	Checks is the texture at the specified slot to be bound as
+		 *			random load/store texture instead of a normal sampled texture.
+		 */
+		bool isLoadStoreTexture(UINT32 slot) const;
+
+		/**
+		 * @brief	Changes the type of the texture at the specified slot.
+		 */
+		void setIsLoadStoreTexture(UINT32 slot, bool isLoadStore);
+
+		/**
+		 * @brief	Returns information that determines which texture surfaces to bind
+		 *			as load/store parameters.
+		 */
+		const TextureSurface& getLoadStoreSurface(UINT32 slot) const;
+
+		/**
+		 * @brief	Sets information that determines which texture surfaces to bind
+		 *			as load/store parameters.
+		 */
+		void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
+
+		/**
+		 * @brief	Checks whether matrices should be transformed before
+		 *			being written to the parameter buffer.
+		 */
+		bool getTransposeMatrices() const { return mTransposeMatrices; }
+
+		/**
+		 * @copydoc	CoreObject::markCoreDirty
 		 *
-		 *			Throws exception if parameter with that name and type doesn't exist.
+		 * @note	Internal method.
+		 */
+		virtual void _markCoreDirty() { }
+
+	protected:
+		/**
+		 * @brief	Gets a descriptor for a data parameter with the specified name.
+		 */
+		GpuParamDataDesc* getParamDesc(const String& name) const;
+
+		GpuParamDescPtr mParamDesc;
+
+		UINT32 mNumParamBlocks;
+		UINT32 mNumTextures;
+		UINT32 mNumSamplerStates;
+
+		BoundTextureInfo* mTextureInfo;
+
+		bool mTransposeMatrices;
+	};
+
+	template<bool Core>
+	struct TGpuParamsBaseType
+	{ };
+
+	template<>
+	struct TGpuParamsBaseType<true>
+	{ 
+		typedef CoreObjectCore Type;
+	};
+
+	template<>
+	struct TGpuParamsBaseType<false>
+	{
+		typedef CoreObject Type;
+	};
+
+	template<bool Core>
+	struct TGpuParamsType
+	{ };
+
+	template<>
+	struct TGpuParamsType<false>
+	{
+		typedef GpuParams Type;
+	};
+
+	template<>
+	struct TGpuParamsType<true>
+	{
+		typedef GpuParamsCore Type;
+	};
+
+	/**
+	 * @brief	Templated version of GpuParams that contains functionality for both
+	 *			sim and core thread versions of stored data.
+	 */
+	template <class TParamsBuffer, class TTexture, class TSampler, bool Core>
+	class TGpuParams : public TGpuParamsBaseType<Core>::Type, public GpuParamsBase
+	{
+	public:
+		/**
+		 * @copydoc	GpuParamsBase::GpuParamsBase(const GpuParamDescPtr&, bool)
+		 */
+		TGpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
+			:GpuParamsBase(paramDesc, transposeMatrices), mParamBlockBuffers(nullptr), mTextures(nullptr), 
+			mSamplerStates(nullptr)
+		{
+			mParamBlockBuffers = bs_newN<TParamsBuffer>(mNumParamBlocks);
+			mTextures = bs_newN<TTexture>(mNumTextures);
+			mSamplerStates = bs_newN<TSampler>(mNumSamplerStates);
+		}
+
+		virtual ~TGpuParams()
+		{
+			bs_deleteN(mParamBlockBuffers, mNumParamBlocks);
+			bs_deleteN(mTextures, mNumTextures);
+			bs_deleteN(mSamplerStates, mNumSamplerStates);
+		}
+
+		/**
+		 * @brief	Binds a new parameter buffer to the specified slot. Any following parameter reads or
+		 *			writes that are referencing that buffer slot will use the new buffer.
+		 *
+		 * @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.
 		 *
-		 *			Parameter handles will be invalidated when their parent GpuParams object changes.
+		 *			It is up to the caller to guarantee the provided buffer matches parameter block
+		 *			descriptor for this slot.
 		 */
-		template<class T> void getParam(const String& name, TGpuDataParam<T>& output) const
+		void setParamBlockBuffer(UINT32 slot, const TParamsBuffer& paramBlockBuffer)
 		{
-			BS_EXCEPT(InvalidParametersException, "Unsupported parameter type");
+			if (slot < 0 || slot >= mNumParamBlocks)
+			{
+				BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
+					toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
+			}
+
+			mParamBlockBuffers[slot] = paramBlockBuffer;
+
+			_markCoreDirty();
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 * @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.
+		 *			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
+		 *			descriptor for this slot.
 		 */
+		void setParamBlockBuffer(const String& name, const TParamsBuffer& paramBlockBuffer)
+		{
+			auto iterFind = mParamDesc->paramBlocks.find(name);
+
+			if (iterFind == mParamDesc->paramBlocks.end())
+			{
+				LOGWRN("Cannot find parameter block with the name: " + name);
+				return;
+			}
+
+			mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
+
+			_markCoreDirty();
+		}
+
+		/**
+		* @brief	Returns a handle for the parameter with the specified name.
+		*			Handle may then be stored and used for quickly setting or retrieving
+		*			values to/from that parameter.
+		*
+		*			Throws exception if parameter with that name and type doesn't exist.
+		*
+		*			Parameter handles will be invalidated when their parent GpuParams object changes.
+		*/
+		template<class T> void getParam(const String& name, TGpuDataParam<T, Core>& output) const
+		{
+			BS_EXCEPT(InvalidParametersException, "Unsupported parameter type");
+		}
+
+		/**
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<float>(const String& name, TGpuDataParam<float>& output) const
+		void getParam<float>(const String& name, TGpuDataParam<float, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT1)
 			{
-				output = GpuParamFloat(&iterFind->second, nullptr);
+				output = TGpuDataParam<float, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find float parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamFloat(&iterFind->second, mInternalData);
+				output = TGpuDataParam<float, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<Vector2>(const String& name, TGpuDataParam<Vector2>& output) const
+		void getParam<Vector2>(const String& name, TGpuDataParam<Vector2, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT2)
 			{
-				output = GpuParamVec2(&iterFind->second, nullptr);
+				output = TGpuDataParam<Vector2, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find vector (2) parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamVec2(&iterFind->second, mInternalData);
+				output = TGpuDataParam<Vector2, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<Vector3>(const String& name, TGpuDataParam<Vector3>& output) const
+		void getParam<Vector3>(const String& name, TGpuDataParam<Vector3, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT3)
 			{
-				output = GpuParamVec3(&iterFind->second, nullptr);
+				output = TGpuDataParam<Vector3, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find vector (3) parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamVec3(&iterFind->second, mInternalData);
+				output = TGpuDataParam<Vector3, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<Vector4>(const String& name, TGpuDataParam<Vector4>& output) const
+		void getParam<Vector4>(const String& name, TGpuDataParam<Vector4, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT4)
 			{
-				output = GpuParamVec4(&iterFind->second, nullptr);
+				output = TGpuDataParam<Vector4, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find vector (4) parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamVec4(&iterFind->second, mInternalData);
+				output = TGpuDataParam<Vector4, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<Color>(const String& name, TGpuDataParam<Color>& output) const
+		void getParam<Color>(const String& name, TGpuDataParam<Color, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT4)
 			{
-				output = GpuParamColor(&iterFind->second, nullptr);
+				output = TGpuDataParam<Color, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find color parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamColor(&iterFind->second, mInternalData);
+				output = TGpuDataParam<Color, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<Matrix3>(const String& name, TGpuDataParam<Matrix3>& output) const
+		void getParam<Matrix3>(const String& name, TGpuDataParam<Matrix3, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_MATRIX_3X3)
 			{
-				output = GpuParamMat3(&iterFind->second, nullptr);
+				output = TGpuDataParam<Matrix3, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find matrix (3x3) parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamMat3(&iterFind->second, mInternalData);
+				output = TGpuDataParam<Matrix3, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
+		* @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		*/
 		template<>
-		void getParam<Matrix4>(const String& name, TGpuDataParam<Matrix4>& output) const
+		void getParam<Matrix4>(const String& name, TGpuDataParam<Matrix4, Core>& output) const
 		{
 			auto iterFind = mParamDesc->params.find(name);
 
 			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_MATRIX_4X4)
 			{
-				output = GpuParamMat4(&iterFind->second, nullptr);
+				output = TGpuDataParam<Matrix4, Core>(&iterFind->second, nullptr);
 				LOGWRN("Cannot find matrix (4x4) parameter with the name '" + name + "'");
 			}
 			else
-				output = GpuParamMat4(&iterFind->second, mInternalData);
+				output = TGpuDataParam<Matrix4, Core>(&iterFind->second, _getThisPtr());
 		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 * @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
 		 */
-		void getStructParam(const String& name, GpuParamStruct& output) const;
+		void getStructParam(const String& name, TGpuParamStruct<Core>& output) const
+		{
+			auto iterFind = mParamDesc->params.find(name);
 
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		void getTextureParam(const String& name, GpuParamTexture& output) const;
+			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_STRUCT)
+			{
+				output = TGpuParamStruct<Core>(&iterFind->second, nullptr);
+				LOGWRN("Cannot find struct parameter with the name '" + name + "'");
+			}
+			else
+				output = TGpuParamStruct<Core>(&iterFind->second, _getThisPtr());
+		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 * @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
 		 */
-		void getLoadStoreTextureParam(const String& name, GpuParamLoadStoreTexture& output) const;
+		void getTextureParam(const String& name, TGpuParamTexture<Core>& output) const
+		{
+			auto iterFind = mParamDesc->textures.find(name);
+
+			if (iterFind == mParamDesc->textures.end())
+			{
+				output = TGpuParamTexture<Core>(&iterFind->second, nullptr);
+				LOGWRN("Cannot find texture parameter with the name '" + name + "'");
+			}
+			else
+				output = TGpuParamTexture<Core>(&iterFind->second, _getThisPtr());
+		}
 
 		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
+		 * @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
 		 */
-		void getSamplerStateParam(const String& name, GpuParamSampState& output) const;
+		void getLoadStoreTextureParam(const String& name, TGpuParamLoadStoreTexture<Core>& output) const
+		{
+			auto iterFind = mParamDesc->textures.find(name);
+
+			if (iterFind == mParamDesc->textures.end())
+			{
+				output = TGpuParamLoadStoreTexture<Core>(&iterFind->second, nullptr);
+				LOGWRN("Cannot find texture parameter with the name '" + name + "'");
+			}
+			else
+				output = TGpuParamLoadStoreTexture<Core>(&iterFind->second, _getThisPtr());
+		}
 
 		/**
-		 * @brief	Uploads all CPU stored parameter buffer data to the GPU buffers.
-		 *
-		 * @note	Core thread only.
+		 * @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
 		 */
-		void updateHardwareBuffers();
+		void getSamplerStateParam(const String& name, TGpuParamSampState<Core>& output) const
+		{
+			auto iterFind = mParamDesc->samplers.find(name);
+
+			if (iterFind == mParamDesc->samplers.end())
+			{
+				output = TGpuParamSampState<Core>(&iterFind->second, nullptr);
+				LOGWRN("Cannot find sampler state parameter with the name '" + name + "'");
+			}
+			else
+				output = TGpuParamSampState<Core>(&iterFind->second, _getThisPtr());
+		}
 
 		/**
 		 * @brief	Gets a parameter block buffer from the specified slot.
 		 */
-		GpuParamBlockBufferPtr getParamBlockBuffer(UINT32 slot) const;
+		TParamsBuffer getParamBlockBuffer(UINT32 slot) const
+		{
+			if (slot < 0 || slot >= mNumParamBlocks)
+			{
+				BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
+					toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
+			}
+
+			return mParamBlockBuffers[slot];
+		}
 
 		/**
 		 * @brief	Gets a texture bound to the specified slot.
 		 */
-		HTexture getTexture(UINT32 slot);
+		TTexture getTexture(UINT32 slot)
+		{
+			if (slot < 0 || slot >= mNumTextures)
+			{
+				BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
+					toString(mNumTextures - 1) + ". Requested: " + toString(slot));
+			}
+
+			return mTextures[slot];
+		}
 
 		/**
 		 * @brief	Gets a sampler state bound to the specified slot.
 		 */
-		HSamplerState getSamplerState(UINT32 slot);
+		TSampler getSamplerState(UINT32 slot)
+		{
+			if (slot < 0 || slot >= mNumSamplerStates)
+			{
+				BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
+					toString(mNumSamplerStates - 1) + ". Requested: " + toString(slot));
+			}
 
-		/**
-		 * @brief	Checks is the texture at the specified slot to be bound as
-		 *			random load/store texture instead of a normal sampled texture.
-		 */
-		bool isLoadStoreTexture(UINT32 slot) const;
+			return mSamplerStates[slot];
+		}
 
 		/**
-		 * @brief	Returns information that determines which texture surfaces to bind
-		 *			as load/store parameters.
+		 * @brief	Sets a texture at the specified slot.
 		 */
-		const TextureSurface& getLoadStoreSurface(UINT32 slot) const;
+		void setTexture(UINT32 slot, const TTexture& texture)
+		{
+			if (slot < 0 || slot >= mNumTextures)
+			{
+				BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
+					toString(mNumTextures - 1) + ". Requested: " + toString(slot));
+			}
 
-		/**
-		 * @brief	Updates all internal data from the provided copy. Copy must have the same
-		 *			number of parameters as this object. Internal buffer contents will also be copied
-		 *			and their sizes must match as well.
-		 */
-		void _updateFromCopy(const GpuParamsPtr& copy);
+			mTextures[slot] = texture;
+			_markCoreDirty();
+		}
 
 		/**
-		 * @brief	Returns an exact copy of this object. Internal parameter buffers will also be cloned.
-		 *
-		 * @param	frameAlloc			Optional frame allocator to allocate the returned data with. If not specified
-		 *								allocation will be done using normal means.
-		 * @param	onlyDirtyBlocks		If true, only dirty param blocks will be cloned and the non-dirty ones will
-		 *								be set to null.
-		 *			
-		 * @note	Internal method.
+		 * @brief	Sets a sampler state at the specified slot.
 		 */
-		GpuParamsPtr _clone(FrameAlloc* frameAlloc = nullptr, bool onlyDirtyBlocks = false) const;
+		void setSamplerState(UINT32 slot, const TSampler& sampler)
+		{
+			if (slot < 0 || slot >= mNumSamplerStates)
+			{
+				BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
+					toString(mNumSamplerStates - 1) + ". Requested: " + toString(slot));
+			}
 
-		/**
-		 * @brief	Checks is the core dirty flag set. This is used by external systems 
-		 *			to know  when internal data has changed and core proxy potentially needs to be updated.
-		 *
-		 * @note	Internal method. Sim thread only.
-		 */
-		bool _isCoreDirty() const;
+			mSamplerStates[slot] = sampler;
+			_markCoreDirty();
+		}
 
+	protected:
 		/**
-		 * @brief	Marks the core dirty flag as clean.
-		 *
-		 * @note	Internal method. Sim thread only.
+		 * @copydoc	CoreObject::getThisPtr
 		 */
-		void _markCoreClean();
+		SPtr<typename TGpuParamsType<Core>::Type> _getThisPtr() const
+		{
+			return std::static_pointer_cast<typename TGpuParamsType<Core>::Type>(getThisPtr());
+		}
 
-	private:
-		GpuParamDescPtr mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
+		TParamsBuffer* mParamBlockBuffers;
+		TTexture* mTextures;
+		TSampler* mSamplerStates;
+	};
+
+	/**
+	 * @brief	Core thread version of GpuParams.
+	 *
+	 * @see		GpuParams
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT GpuParamsCore : public TGpuParams<SPtr<GpuParamBlockBufferCore>, SPtr<TextureCore>, SPtr<SamplerStateCore>, true>
+	{
+	public:
+		~GpuParamsCore() { }
 
 		/**
-		 * @brief	Gets a descriptor for a data parameter with the specified name.
+		 * @brief	Uploads all CPU stored parameter buffer data to the GPU buffers.
 		 */
-		GpuParamDataDesc* getParamDesc(const String& name) const;
+		void updateHardwareBuffers();
 
 		/**
-		 * @brief	Allocates and constructs internal buffers. Parameter counts must have been previously assigned.
-		 *			If provided, internal data will be allocated using the frame allocator, otherwise using
-		 *			the normal allocator.
+		 * @copydoc	GpuParamsBase::GpuParamsBase
 		 */
-		void constructInternalBuffers(FrameAlloc* frameAlloc = nullptr);
+		static SPtr<GpuParamsCore> create(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+
+	protected:
+		friend class GpuParams;
 
 		/**
-		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
+		 * @copydoc	GpuParamsBase::GpuParamsBase
 		 */
-		void markCoreDirty();
+		GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
 	};
 
 	/**
-	 * @brief	Structure used for storing GpuParams internal data.
+	 * @brief	Contains descriptions for all parameters in a GPU program and also
+	 *			allows you to write and read those parameters. All parameter values
+	 *			are stored internally on the CPU, and are only submitted to the GPU
+	 *			once the parameters are bound to the pipeline.
+	 *
+	 * @see		CoreThreadAccessor::bindGpuParams
+	 *
+	 * @note	Sim thread only.
 	 */
-	struct GpuParamsInternalData
+	class BS_CORE_EXPORT GpuParams : public TGpuParams<GpuParamBlockBufferPtr, HTexture, HSamplerState, false>
 	{
-		GpuParamsInternalData();
+	public:
+		~GpuParams() { }
 
-		UINT8* mData;
+		/**
+		 * @copydoc	CoreObject::markCoreDirty
+		 *
+		 * @note	Internal method.
+		 */
+		void _markCoreDirty();
 
-		UINT32 mNumParamBlocks;
-		UINT32 mNumTextures;
-		UINT32 mNumSamplerStates;
+		/**
+		 * @brief	Retrieves a core implementation of a mesh usable only from the
+		 *			core thread.
+		 */
+		SPtr<GpuParamsCore> getCore() const;
 
-		GpuParamBlockPtr* mParamBlocks;
-		GpuParamBlockBufferPtr* mParamBlockBuffers;
-		HTexture* mTextures;
-		BoundTextureInfo* mTextureInfo;
-		HSamplerState* mSamplerStates;
+		/**
+		 * @copydoc	GpuParamsBase::GpuParamsBase
+		 */
+		static SPtr<GpuParams> create(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
 
-		bool mTransposeMatrices;
-		bool mIsDestroyed;
-		UINT32 mCoreDirtyFlags;
+	protected:
+		/**
+		 * @copydoc	GpuParamsBase::GpuParamsBase
+		 */
+		GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
 
-		FrameAlloc* mFrameAlloc;
+		/**
+		 * @copydoc	CoreObject::createCore
+		 */
+		SPtr<CoreObjectCore> createCore() const;
 	};
 }

+ 6 - 1
BansheeCore/Include/BsGpuProgram.h

@@ -139,10 +139,15 @@ namespace BansheeEngine
 		 */
 		virtual bool isAdjacencyInfoRequired() const { return mNeedsAdjacencyInfo; }
 
+		/**
+		 * @brief	Checks whether the program expects matrices in column major format.
+		 */
+		virtual bool hasColumnMajorMatrices() const { return false; }
+
 		/**
 		 * @copydoc	GpuProgram::createParameters
 		 */
-		virtual GpuParamsPtr createParameters();
+		virtual SPtr<GpuParamsCore> createParameters();
 
 		/**
 		 * @copydoc	GpuProgram::getParamDesc

+ 0 - 1
BansheeCore/Include/BsHardwareBufferManager.h

@@ -5,7 +5,6 @@
 #include "BsVertexBuffer.h"
 #include "BsIndexBuffer.h"
 #include "BsVertexDeclaration.h"
-#include "BsGpuParamBlock.h"
 
 namespace BansheeEngine 
 {

+ 5 - 14
BansheeCore/Include/BsMaterial.h

@@ -18,8 +18,7 @@ namespace BansheeEngine
 	enum class MaterialDirtyFlag
 	{
 		Material = 0x01, /**< Internal material data is dirty. */
-		Proxy = 0x02, /**< Active proxy needs to be updated. */
-		Params = 0x04 /**< Parameters are dirty. */
+		Proxy = 0x02 /**< Active proxy needs to be updated. */
 	};
 
 	/**
@@ -468,14 +467,6 @@ namespace BansheeEngine
 		 */
 		void _setActiveProxy(const MaterialProxyPtr& proxy) { mActiveProxy = proxy; }
 
-		/**
-		 * @brief	Returns updated GPU parameters since the last time the parameters were marked clean.
-		 *
-		 * @note	Returned data will be allocated with a frame allocator and must be released during the
-		 *			same frame it was allocated.
-		 */
-		MaterialProxy::DirtyParamsInfo* _getDirtyProxyParams(FrameAlloc* frameAlloc);
-
 		/**
 		 * @brief	Creates a new core proxy from the currently set material data. Core proxies ensure
 		 *			that the core thread has all the necessary material data, while avoiding the need
@@ -501,7 +492,7 @@ namespace BansheeEngine
 		 * 			caller to keep track of that.
 		 */
 		template <typename T>
-		void getParam(const String& name, TMaterialDataParam<T>& output) const
+		void getParam(const String& name, TMaterialDataParam<T, false>& output) const
 		{
 			throwIfNotInitialized();
 
@@ -513,7 +504,7 @@ namespace BansheeEngine
 			}
 
 			const String& gpuVarName = iterFind->second;
-			Vector<TGpuDataParam<T>> gpuParams;
+			Vector<TGpuDataParam<T, false>> gpuParams;
 
 			for (auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
 			{
@@ -526,14 +517,14 @@ namespace BansheeEngine
 					{
 						if (paramPtr->hasParam(gpuVarName))
 						{
-							gpuParams.push_back(TGpuDataParam<T>());
+							gpuParams.push_back(TGpuDataParam<T, false>());
 							paramPtr->getParam<T>(gpuVarName, gpuParams.back());
 						}
 					}
 				}
 			}
 
-			output = TMaterialDataParam<T>(gpuParams);
+			output = TMaterialDataParam<T, false>(gpuParams);
 		}
 
 	private:

+ 18 - 10
BansheeCore/Include/BsMaterialParam.h

@@ -11,7 +11,7 @@ namespace BansheeEngine
 	 *
 	 * @see		TGpuDataParam
 	 */
-	template<class T>
+	template<class T, bool Core>
 	class BS_CORE_EXPORT TMaterialDataParam
 	{
 	public:
@@ -40,20 +40,28 @@ namespace BansheeEngine
 	private:
 		friend class Material;
 
-		TMaterialDataParam(const Vector<TGpuDataParam<T>>& params)
+		TMaterialDataParam(const Vector<TGpuDataParam<T, Core>>& params)
 			:mParams(params)
 		{ }
 	protected:
-		Vector<TGpuDataParam<T>> mParams;
+		Vector<TGpuDataParam<T, Core>> mParams;
 	};
 
-	typedef TMaterialDataParam<float> MaterialParamFloat;
-	typedef TMaterialDataParam<Color> MaterialParamColor;
-	typedef TMaterialDataParam<Vector2> MaterialParamVec2;
-	typedef TMaterialDataParam<Vector3> MaterialParamVec3;
-	typedef TMaterialDataParam<Vector4> MaterialParamVec4;
-	typedef TMaterialDataParam<Matrix3> MaterialParamMat3;
-	typedef TMaterialDataParam<Matrix4> MaterialParamMat4;
+	typedef TMaterialDataParam<float, false> MaterialParamFloat;
+	typedef TMaterialDataParam<Color, false> MaterialParamColor;
+	typedef TMaterialDataParam<Vector2, false> MaterialParamVec2;
+	typedef TMaterialDataParam<Vector3, false> MaterialParamVec3;
+	typedef TMaterialDataParam<Vector4, false> MaterialParamVec4;
+	typedef TMaterialDataParam<Matrix3, false> MaterialParamMat3;
+	typedef TMaterialDataParam<Matrix4, false> MaterialParamMat4;
+
+	typedef TMaterialDataParam<float, true> MaterialParamFloatCore;
+	typedef TMaterialDataParam<Color, true> MaterialParamColorCore;
+	typedef TMaterialDataParam<Vector2, true> MaterialParamVec2Core;
+	typedef TMaterialDataParam<Vector3, true> MaterialParamVec3Core;
+	typedef TMaterialDataParam<Vector4, true> MaterialParamVec4Core;
+	typedef TMaterialDataParam<Matrix3, true> MaterialParamMat3Core;
+	typedef TMaterialDataParam<Matrix4, true> MaterialParamMat4Core;
 
 	/**
 	 * @copydoc	TMaterialDataParam

+ 3 - 38
BansheeCore/Include/BsMaterialProxy.h

@@ -42,52 +42,17 @@ namespace BansheeEngine
 		 */
 		struct BS_CORE_EXPORT BufferBindInfo
 		{
-			BufferBindInfo(UINT32 paramsIdx, UINT32 slotIdx, const GpuParamBlockBufferPtr& buffer)
+			BufferBindInfo(UINT32 paramsIdx, UINT32 slotIdx, const SPtr<GpuParamBlockBufferCore>& buffer)
 				:paramsIdx(paramsIdx), slotIdx(slotIdx), buffer(buffer)
 			{ }
 
 			UINT32 paramsIdx;
 			UINT32 slotIdx;
-			GpuParamBlockBufferPtr buffer;
-		};
-
-		/**
-		 * @brief	Contains GPU parameters and index of the parameters it binds to in the material proxy.
-		 */
-		struct BS_CORE_EXPORT ParamsBindInfo
-		{
-			// Note: Manually allocated. Must not have a constructor/destructor.
-
-			UINT32 paramsIdx;
-			GpuParamsPtr params;
-		};
-
-		/**
-		 * @brief	Contains a set of GPU params that need updating on the core thread.
-		 */
-		struct BS_CORE_EXPORT DirtyParamsInfo
-		{
-			// Note: Manually allocated. Must not have a constructor/destructor.
-
-			ParamsBindInfo* entries;
-			UINT32 numEntries;
-
-			FrameAlloc* owner;
-
-			/**
-			 * @brief	Allocates and constructs a new object. You must release it
-			 *			manually using the same frame allocator.
-			 */
-			static DirtyParamsInfo* create(FrameAlloc* alloc, UINT32 numParams);
-
-			/**
-			 * @brief	Deallocates and destructs a previously allocated params info object.
-			 */
-			static void destroy(DirtyParamsInfo* paramsInfo);
+			SPtr<GpuParamBlockBufferCore> buffer;
 		};
 
 		Vector<MaterialProxyPass> passes;
-		Vector<GpuParamsPtr> params;
+		Vector<SPtr<GpuParamsCore>> params;
 
 		ShaderProxyPtr shader;
 

+ 1 - 1
BansheeCore/Include/BsRenderSystem.h

@@ -178,7 +178,7 @@ namespace BansheeEngine
 		 * @brief	Binds GPU program parameters. Caller must ensure these match the previously
 		 *			bound GPU program.
 		 */
-		virtual void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params) = 0;
+		virtual void bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& params) = 0;
 
 		/**
 		 * @brief	Unbinds a program of a given type. 

+ 4 - 2
BansheeCore/Source/BsCoreApplication.cpp

@@ -218,8 +218,10 @@ namespace BansheeEngine
 			gCoreThread().queueCommand(&Platform::_coreUpdate);
 			gCoreThread().submitAccessors(); 
 
-			// This should be called after accessors are submitted to ensure we don't sync CoreObjects that are about to be destroyed (They're only ever destroyed from accessors)
-			gCoreThread().queueCommand(std::bind(&CoreObjectManager::syncDownload, CoreObjectManager::instancePtr(), CoreObjectSync::Core, gCoreThread().getFrameAlloc()));
+			// This should be called after accessors are submitted to ensure we don't sync CoreObjects that are 
+			// about to be destroyed (They're only ever destroyed from accessors)
+			gCoreThread().queueCommand(std::bind(&CoreObjectManager::syncDownload, CoreObjectManager::instancePtr(), 
+				CoreObjectSync::Core, gCoreThread().getFrameAlloc()));
 			gCoreThread().queueCommand(std::bind(&CoreApplication::endCoreProfiling, this));
 			gCoreThread().queueCommand(std::bind(&CoreApplication::frameRenderingFinishedCallback, this));
 

+ 1 - 1
BansheeCore/Source/BsCoreThreadAccessor.cpp

@@ -135,7 +135,7 @@ namespace BansheeEngine
 
 	void CoreThreadAccessorBase::bindGpuParams(GpuProgramType gptype, const GpuParamsPtr& params)
 	{
-		mCommandQueue->queue(std::bind(&RenderSystem::bindGpuParams, RenderSystem::instancePtr(), gptype, params->_clone(gCoreThread().getFrameAlloc(), true)));
+		mCommandQueue->queue(std::bind(&RenderSystem::bindGpuParams, RenderSystem::instancePtr(), gptype, params->getCore()));
 	}
 
 	void CoreThreadAccessorBase::beginRender()

+ 130 - 148
BansheeCore/Source/BsGpuParam.cpp

@@ -1,232 +1,214 @@
 #include "BsGpuParam.h"
 #include "BsGpuParams.h"
+#include "BsGpuParamBlockBuffer.h"
 
 namespace BansheeEngine
 {
-	GpuDataParamBase::GpuDataParamBase()
-		:mParamDesc(nullptr)
-	{ }
+	/************************************************************************/
+	/* 							GPU PARAMS BASE                      		*/
+	/************************************************************************/
 
-	GpuDataParamBase::GpuDataParamBase(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-		:mParamDesc(paramDesc), mInternalData(internalData)
+	GpuParamBase::GpuParamBase()
 	{ }
 
-	bool GpuDataParamBase::isDestroyed() const
-	{
-		return mInternalData->mIsDestroyed;
-	}
-
-	GpuParamBlockPtr GpuDataParamBase::getParamBlock(UINT32 slotIdx) const
-	{
-		return mInternalData->mParamBlocks[slotIdx];
-	}
+	GpuParamBase::GpuParamBase(const SPtr<GpuParams>& parent)
+		:mParent(parent)
+	{ }
 
-	bool GpuDataParamBase::getTransposeMatrices() const
+	void GpuParamBase::markCoreDirty()
 	{
-		return mInternalData->mTransposeMatrices;
-	}
-
-	void GpuDataParamBase::markCoreDirty() 
-	{ 
-		mInternalData->mCoreDirtyFlags = 0xFFFFFFFF; 
+		mParent->_markCoreDirty();
 	}
 
 	/************************************************************************/
-	/* 									STRUCT	                     		*/
+	/* 							GPU DATA PARAMS BASE                      	*/
 	/************************************************************************/
 
-	GpuParamStruct::GpuParamStruct()
-		:mParamDesc(nullptr)
+	GpuDataParamBase::GpuDataParamBase()
+		: GpuParamBase(), mParamDesc(nullptr)
 	{ }
 
-	GpuParamStruct::GpuParamStruct(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-		:mParamDesc(paramDesc), mInternalData(internalData)
+	GpuDataParamBase::GpuDataParamBase(GpuParamDataDesc* paramDesc, const SPtr<GpuParams>& parent)
+		: GpuParamBase(parent), mParamDesc(paramDesc)
 	{ }
 
-	void GpuParamStruct::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	bool GpuDataParamBase::getTransposeMatrices() const
 	{
-		if (mInternalData == nullptr)
-			return;
-
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
-		UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
-
-#if BS_DEBUG_MODE
-		if(sizeBytes > elementSizeBytes)
-		{
-			LOGWRN("Provided element size larger than maximum element size. Maximum size: " + 
-				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
-		}
-
-		if (arrayIdx >= mParamDesc->arraySize)
-		{
-			BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-				toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
-		}
-#endif
+		return mParent->getTransposeMatrices();
+	}
 
-		sizeBytes = std::min(elementSizeBytes, sizeBytes);
+	bool GpuDataParamBase::write(UINT32 offset, const void* data, UINT32 size)
+	{
+		GpuParamBlockBufferPtr paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSlot);
+		if (paramBlock == nullptr)
+			return false;
 
-		GpuParamBlockPtr paramBlock = mInternalData->mParamBlocks[mParamDesc->paramBlockSlot];
-		paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
+		paramBlock->write(offset, data, size);
+		return true;
+	}
 
-		// Set unused bytes to 0
-		if(sizeBytes < elementSizeBytes)
-		{
-			UINT32 diffSize = elementSizeBytes - sizeBytes;
-			paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32)+sizeBytes, diffSize);
-		}
+	bool GpuDataParamBase::read(UINT32 offset, void* data, UINT32 size)
+	{
+		GpuParamBlockBufferPtr paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSlot);
+		if (paramBlock == nullptr)
+			return false;
 
-		mInternalData->mCoreDirtyFlags = 0xFFFFFFFF;
+		paramBlock->read(offset, data, size);
+		return true;
 	}
 
-	void GpuParamStruct::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
+	void GpuDataParamBase::zeroOut(UINT32 offset, UINT32 size)
 	{
-		if (mInternalData == nullptr)
+		GpuParamBlockBufferPtr paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSlot);
+		if (paramBlock == nullptr)
 			return;
 
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
+		paramBlock->zeroOut(offset, size);
+	}
+
+	/************************************************************************/
+	/* 						GPU OBJECT PARAMS BASE                      	*/
+	/************************************************************************/
 
-		UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
+	GpuObjectParamBase::GpuObjectParamBase()
+		: GpuParamBase(), mParamDesc(nullptr)
+	{ }
+
+	GpuObjectParamBase::GpuObjectParamBase(GpuParamObjectDesc* paramDesc, const SPtr<GpuParams>& parent)
+		: GpuParamBase(parent), mParamDesc(paramDesc)
+	{ }
 
-#if BS_DEBUG_MODE
-		if(sizeBytes > elementSizeBytes)
-		{
-			LOGWRN("Provided element size larger than maximum element size. Maximum size: " + 
-				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
-		}
+	HTexture GpuObjectParamBase::getTexture(UINT32 slot)
+	{
+		return mParent->getTexture(slot);
+	}
 
-		if (arrayIdx >= mParamDesc->arraySize)
-		{
-			BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-				toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
-		}
-#endif
-		sizeBytes = std::min(elementSizeBytes, sizeBytes);
+	HSamplerState GpuObjectParamBase::getSamplerState(UINT32 slot)
+	{
+		return mParent->getSamplerState(slot);
+	}
 
-		GpuParamBlockPtr paramBlock = mInternalData->mParamBlocks[mParamDesc->paramBlockSlot];
-		paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
+	void GpuObjectParamBase::setTexture(UINT32 slot, const HTexture& texture)
+	{
+		mParent->setTexture(slot, texture);
 	}
 
-	UINT32 GpuParamStruct::getElementSize() const
+	void GpuObjectParamBase::setSamplerState(UINT32 slot, const HSamplerState& sampler)
 	{
-		if (mInternalData == nullptr)
-			return 0;
+		mParent->setSamplerState(slot, sampler);
+	}
 
-		if(mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
+	void GpuObjectParamBase::setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const
+	{
+		mParent->setLoadStoreSurface(slot, surface);
+	}
 
-		return mParamDesc->elementSize * sizeof(UINT32);
+	void GpuObjectParamBase::setIsLoadStoreTexture(UINT32 slot, bool isLoadStore)
+	{
+		mParent->setIsLoadStoreTexture(slot, isLoadStore);
 	}
 
 	/************************************************************************/
-	/* 								TEXTURE		                     		*/
+	/* 							GPU PARAMS CORE BASE                      	*/
 	/************************************************************************/
 
-	GpuParamTexture::GpuParamTexture()
-		:mParamDesc(nullptr)
+	GpuParamCoreBase::GpuParamCoreBase()
 	{ }
 
-	GpuParamTexture::GpuParamTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-		: mParamDesc(paramDesc), mInternalData(internalData)
+	GpuParamCoreBase::GpuParamCoreBase(const SPtr<GpuParamsCore>& parent)
+		:mParent(parent)
 	{ }
 
-	void GpuParamTexture::set(const HTexture& texture)
+	void GpuParamCoreBase::markCoreDirty()
 	{
-		if (mInternalData == nullptr)
-			return;
-
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
-		mInternalData->mTextures[mParamDesc->slot] = texture;
-		mInternalData->mTextureInfo[mParamDesc->slot].isLoadStore = false;
-		mInternalData->mCoreDirtyFlags = 0xFFFFFFFF;
-	}
-
-	HTexture GpuParamTexture::get()
-	{
-		if (mInternalData == nullptr)
-			return HTexture();
-
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
-		return mInternalData->mTextures[mParamDesc->slot];
+		mParent->_markCoreDirty();
 	}
 
 	/************************************************************************/
-	/* 							LOAD/STORE TEXTURE		                    */
+	/* 						GPU DATA PARAMS CORE BASE                      	*/
 	/************************************************************************/
 
-	GpuParamLoadStoreTexture::GpuParamLoadStoreTexture()
-		:mParamDesc(nullptr)
+	GpuDataParamCoreBase::GpuDataParamCoreBase()
+		: GpuParamCoreBase(), mParamDesc(nullptr)
 	{ }
 
-	GpuParamLoadStoreTexture::GpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-		: mParamDesc(paramDesc), mInternalData(internalData)
+	GpuDataParamCoreBase::GpuDataParamCoreBase(GpuParamDataDesc* paramDesc, const SPtr<GpuParamsCore>& parent)
+		: GpuParamCoreBase(parent), mParamDesc(paramDesc)
 	{ }
 
-	void GpuParamLoadStoreTexture::set(const HTexture& texture, const TextureSurface& surface)
+	bool GpuDataParamCoreBase::getTransposeMatrices() const
 	{
-		if (mInternalData == nullptr)
-			return;
+		return mParent->getTransposeMatrices();
+	}
 
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
+	bool GpuDataParamCoreBase::write(UINT32 offset, const void* data, UINT32 size)
+	{
+		SPtr<GpuParamBlockBufferCore> paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSlot);
+		if (paramBlock == nullptr)
+			return false;
 
-		mInternalData->mTextures[mParamDesc->slot] = texture;
-		mInternalData->mTextureInfo[mParamDesc->slot].isLoadStore = true;
-		mInternalData->mTextureInfo[mParamDesc->slot].surface = surface;
-		mInternalData->mCoreDirtyFlags = 0xFFFFFFFF;
+		paramBlock->write(offset, data, size);
+		return true;
 	}
 
-	HTexture GpuParamLoadStoreTexture::get()
+	bool GpuDataParamCoreBase::read(UINT32 offset, void* data, UINT32 size)
 	{
-		if (mInternalData == nullptr)
-			return HTexture();
+		SPtr<GpuParamBlockBufferCore> paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSlot);
+		if (paramBlock == nullptr)
+			return false;
+
+		paramBlock->read(offset, data, size);
+		return true;
+	}
 
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
+	void GpuDataParamCoreBase::zeroOut(UINT32 offset, UINT32 size)
+	{
+		SPtr<GpuParamBlockBufferCore> paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSlot);
+		if (paramBlock == nullptr)
+			return;
 
-		return mInternalData->mTextures[mParamDesc->slot];
+		paramBlock->zeroOut(offset, size);
 	}
 
 	/************************************************************************/
-	/* 								SAMPLER STATE                      		*/
+	/* 						GPU OBJECT PARAMS CORE BASE                    	*/
 	/************************************************************************/
 
-	GpuParamSampState::GpuParamSampState()
-		:mParamDesc(nullptr)
+	GpuObjectParamCoreBase::GpuObjectParamCoreBase()
+		: GpuParamCoreBase(), mParamDesc(nullptr)
 	{ }
 
-	GpuParamSampState::GpuParamSampState(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-		: mParamDesc(paramDesc), mInternalData(internalData)
+	GpuObjectParamCoreBase::GpuObjectParamCoreBase(GpuParamObjectDesc* paramDesc, const SPtr<GpuParamsCore>& parent)
+		: GpuParamCoreBase(parent), mParamDesc(paramDesc)
 	{ }
 
-	void GpuParamSampState::set(const HSamplerState& samplerState)
+	SPtr<TextureCore> GpuObjectParamCoreBase::getTexture(UINT32 slot)
 	{
-		if (mInternalData == nullptr)
-			return;
+		return mParent->getTexture(slot);
+	}
 
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
+	SPtr<SamplerStateCore> GpuObjectParamCoreBase::getSamplerState(UINT32 slot)
+	{
+		return mParent->getSamplerState(slot);
+	}
 
-		mInternalData->mSamplerStates[mParamDesc->slot] = samplerState;
-		mInternalData->mCoreDirtyFlags = 0xFFFFFFFF;
+	void GpuObjectParamCoreBase::setTexture(UINT32 slot, const SPtr<TextureCore>& texture)
+	{
+		mParent->setTexture(slot, texture);
 	}
 
-	HSamplerState GpuParamSampState::get()
+	void GpuObjectParamCoreBase::setSamplerState(UINT32 slot, const SPtr<SamplerStateCore>& sampler)
 	{
-		if (mInternalData == nullptr)
-			return HSamplerState();
+		mParent->setSamplerState(slot, sampler);
+	}
 
-		if (mInternalData->mIsDestroyed)
-			BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
+	void GpuObjectParamCoreBase::setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const
+	{
+		mParent->setLoadStoreSurface(slot, surface);
+	}
 
-		return mInternalData->mSamplerStates[mParamDesc->slot];
+	void GpuObjectParamCoreBase::setIsLoadStoreTexture(UINT32 slot, bool isLoadStore)
+	{
+		mParent->setIsLoadStoreTexture(slot, isLoadStore);
 	}
 }

+ 0 - 90
BansheeCore/Source/BsGpuParamBlock.cpp

@@ -1,90 +0,0 @@
-#include "BsGpuParamBlock.h"
-#include "BsGpuParamDesc.h"
-#include "BsGpuParamBlockBuffer.h"
-#include "BsHardwareBufferManager.h"
-#include "BsFrameAlloc.h"
-#include "BsException.h"
-
-namespace BansheeEngine
-{
-	GpuParamBlock::GpuParamBlock(UINT32 size)
-		:mDirty(true), mData(nullptr), mSize(size), mAlloc(nullptr)
-	{
-		if (mSize > 0)
-			mData = (UINT8*)bs_alloc(mSize);
-
-		memset(mData, 0, mSize);
-	}
-
-	GpuParamBlock::GpuParamBlock(FrameAlloc* alloc, UINT32 size)
-		:mDirty(true), mData(nullptr), mSize(size), mAlloc(alloc)
-	{
-		if (mSize > 0)
-			mData = alloc->alloc(mSize);
-
-		memset(mData, 0, mSize);
-	}
-
-	GpuParamBlock::~GpuParamBlock()
-	{
-		if (mData != nullptr)
-		{
-			if (mAlloc != nullptr)
-				mAlloc->dealloc(mData);
-			else
-				bs_free(mData);
-		}
-	}
-
-	void GpuParamBlock::write(UINT32 offset, const void* data, UINT32 size)
-	{
-#if BS_DEBUG_MODE
-		if(offset < 0 || (offset + size) > mSize)
-		{
-			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
-				"Available range: 0 .. " + toString(mSize) + ". " \
-				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
-		}
-#endif
-
-		memcpy(mData + offset, data, size);
-
-		mDirty = true;
-	}
-
-	void GpuParamBlock::read(UINT32 offset, void* data, UINT32 size)
-	{
-#if BS_DEBUG_MODE
-		if(offset < 0 || (offset + size) > mSize)
-		{
-			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
-				"Available range: 0 .. " + toString(mSize) + ". " \
-				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
-		}
-#endif
-
-		memcpy(data, mData + offset, size);
-	}
-
-	void GpuParamBlock::zeroOut(UINT32 offset, UINT32 size)
-	{
-#if BS_DEBUG_MODE
-		if(offset < 0 || (offset + size) > mSize)
-		{
-			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
-				"Available range: 0 .. " + toString(mSize) + ". " \
-				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
-		}
-#endif
-
-		memset(mData + offset, 0, size);
-
-		mDirty = true;
-	}
-
-	void GpuParamBlock::uploadToBuffer(const GpuParamBlockBufferPtr& buffer)
-	{
-		buffer->getCore()->writeData(mData);
-		mDirty = false;
-	}
-}

+ 137 - 6
BansheeCore/Source/BsGpuParamBlockBuffer.cpp

@@ -1,18 +1,141 @@
 #include "BsGpuParamBlockBuffer.h"
-#include "BsGpuParamBlock.h"
 #include "BsHardwareBufferManager.h"
+#include "BsFrameAlloc.h"
 
 namespace BansheeEngine
 {
 	GpuParamBlockBufferCore::GpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage)
-		:mSize(size), mUsage(usage)
+		:mSize(size), mUsage(usage), mCachedData(nullptr), mGPUBufferDirty(false)
 	{
+		if (mSize > 0)
+			mCachedData = (UINT8*)bs_alloc(mSize);
+
+		memset(mCachedData, 0, mSize);
+	}
+
+	GpuParamBlockBufferCore::~GpuParamBlockBufferCore()
+	{
+		if (mCachedData != nullptr)
+			bs_free(mCachedData);
+	}
+
+	void GpuParamBlockBufferCore::write(UINT32 offset, const void* data, UINT32 size)
+	{
+#if BS_DEBUG_MODE
+		if (offset < 0 || (offset + size) > mSize)
+		{
+			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+#endif
+
+		memcpy(mCachedData + offset, data, size);
+		mGPUBufferDirty = true;
+	}
+
+	void GpuParamBlockBufferCore::read(UINT32 offset, void* data, UINT32 size)
+	{
+#if BS_DEBUG_MODE
+		if (offset < 0 || (offset + size) > mSize)
+		{
+			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+#endif
+
+		memcpy(data, mCachedData + offset, size);
+	}
+
+	void GpuParamBlockBufferCore::zeroOut(UINT32 offset, UINT32 size)
+	{
+#if BS_DEBUG_MODE
+		if (offset < 0 || (offset + size) > mSize)
+		{
+			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+#endif
+
+		memset(mCachedData + offset, 0, size);
+		mGPUBufferDirty = true;
+	}
+
+	void GpuParamBlockBufferCore::flushToGPU()
+	{
+		if (mGPUBufferDirty)
+		{
+			writeToGPU(mCachedData);
+			mGPUBufferDirty = false;
+		}
+	}
+
+	void GpuParamBlockBufferCore::syncToCore(const CoreSyncData& data)
+	{
+		assert(mSize == data.getBufferSize());
+
+		write(0, data.getBuffer(), data.getBufferSize());
 	}
 
 	GpuParamBlockBuffer::GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage)
-		:mSize(size), mUsage(usage)
+		:mSize(size), mUsage(usage), mCachedData(nullptr)
+	{
+		if (mSize > 0)
+			mCachedData = (UINT8*)bs_alloc(mSize);
+
+		memset(mCachedData, 0, mSize);
+	}
+
+	GpuParamBlockBuffer::~GpuParamBlockBuffer()
+	{
+		if (mCachedData != nullptr)
+			bs_free(mCachedData);
+	}
+
+	void GpuParamBlockBuffer::write(UINT32 offset, const void* data, UINT32 size)
+	{
+#if BS_DEBUG_MODE
+		if (offset < 0 || (offset + size) > mSize)
+		{
+			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+#endif
+
+		memcpy(mCachedData + offset, data, size);
+		markCoreDirty();
+	}
+
+	void GpuParamBlockBuffer::read(UINT32 offset, void* data, UINT32 size)
 	{
-		mParamBlock = bs_shared_ptr<GpuParamBlock>(size);
+#if BS_DEBUG_MODE
+		if (offset < 0 || (offset + size) > mSize)
+		{
+			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+#endif
+
+		memcpy(data, mCachedData + offset, size);
+	}
+
+	void GpuParamBlockBuffer::zeroOut(UINT32 offset, UINT32 size)
+	{
+#if BS_DEBUG_MODE
+		if (offset < 0 || (offset + size) > mSize)
+		{
+			BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+#endif
+
+		memset(mCachedData + offset, 0, size);
+		markCoreDirty();
 	}
 
 	SPtr<GpuParamBlockBufferCore> GpuParamBlockBuffer::getCore() const
@@ -25,16 +148,24 @@ namespace BansheeEngine
 		return HardwareBufferCoreManager::instance().createGpuParamBlockBufferInternal(mSize, mUsage);
 	}
 
+	CoreSyncData GpuParamBlockBuffer::syncToCore(FrameAlloc* allocator)
+	{
+		UINT8* buffer = allocator->alloc(mSize);
+		read(0, buffer, mSize);
+
+		return CoreSyncData(buffer, mSize);
+	}
+
 	GenericGpuParamBlockBufferCore::GenericGpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage)
 		:GpuParamBlockBufferCore(size, usage), mData(nullptr)
 	{ }
 
-	void GenericGpuParamBlockBufferCore::writeData(const UINT8* data)
+	void GenericGpuParamBlockBufferCore::writeToGPU(const UINT8* data)
 	{
 		memcpy(mData, data, mSize);
 	}
 
-	void GenericGpuParamBlockBufferCore::readData(UINT8* data) const
+	void GenericGpuParamBlockBufferCore::readFromGPU(UINT8* data) const
 	{
 		memcpy(data, mData, mSize);
 	}

+ 70 - 335
BansheeCore/Source/BsGpuParams.cpp

@@ -1,6 +1,5 @@
 #include "BsGpuParams.h"
 #include "BsGpuParamDesc.h"
-#include "BsGpuParamBlock.h"
 #include "BsGpuParamBlockBuffer.h"
 #include "BsVector2.h"
 #include "BsFrameAlloc.h"
@@ -9,102 +8,37 @@
 
 namespace BansheeEngine
 {
-	GpuParamsInternalData::GpuParamsInternalData()
-		:mTransposeMatrices(false), mData(nullptr), mNumParamBlocks(0), mNumTextures(0), mNumSamplerStates(0), mFrameAlloc(nullptr),
-		mParamBlocks(nullptr), mParamBlockBuffers(nullptr), mTextures(nullptr), mSamplerStates(nullptr), mCoreDirtyFlags(0xFFFFFFFF),
-		mIsDestroyed(false), mTextureInfo(nullptr)
-	{ }
-
-	GpuParams::GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
-		:mParamDesc(paramDesc)
+	GpuParamsBase::GpuParamsBase(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
+		:mParamDesc(paramDesc), mTransposeMatrices(transposeMatrices), mNumParamBlocks(0), mNumSamplerStates(0),
+		mNumTextures(0), mTextureInfo(nullptr)
 	{
-		mInternalData = bs_shared_ptr<GpuParamsInternalData>();
-		mInternalData->mTransposeMatrices = transposeMatrices;
-
-		for(auto& paramBlock : mParamDesc->paramBlocks)
-		{
-			if ((paramBlock.second.slot + 1) > mInternalData->mNumParamBlocks)
-				mInternalData->mNumParamBlocks = paramBlock.second.slot + 1;
-		}
-
-		for(auto& texture : mParamDesc->textures)
+		for (auto& paramBlock : mParamDesc->paramBlocks)
 		{
-			if ((texture.second.slot + 1) > mInternalData->mNumTextures)
-				mInternalData->mNumTextures = texture.second.slot + 1;
+			if ((paramBlock.second.slot + 1) > mNumParamBlocks)
+				mNumParamBlocks = paramBlock.second.slot + 1;
 		}
 
-		for(auto& sampler : mParamDesc->samplers)
-		{
-			if ((sampler.second.slot + 1) > mInternalData->mNumSamplerStates)
-				mInternalData->mNumSamplerStates = sampler.second.slot + 1;
-		}
-
-		constructInternalBuffers();
-	}
-
-	GpuParams::GpuParams(const GpuParamDescPtr& paramDesc, PrivatelyConstruct& dummy)
-		:mParamDesc(paramDesc)
-	{
-		
-	}
-
-	GpuParams::~GpuParams()
-	{
-		mInternalData->mIsDestroyed = true;
-
-		// Ensure everything is destructed
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
+		for (auto& texture : mParamDesc->textures)
 		{
-			mInternalData->mParamBlocks[i].~shared_ptr();
-			mInternalData->mParamBlockBuffers[i].~shared_ptr();
+			if ((texture.second.slot + 1) > mNumTextures)
+				mNumTextures = texture.second.slot + 1;
 		}
 
-		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
-			mInternalData->mTextures[i].~ResourceHandle();
-
-		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
-			mInternalData->mTextureInfo[i].~BoundTextureInfo();
-
-		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
-			mInternalData->mSamplerStates[i].~ResourceHandle();
-
-		if (mInternalData->mFrameAlloc != nullptr)
-			mInternalData->mFrameAlloc->dealloc(mInternalData->mData);
-		else
-			bs_free(mInternalData->mData);
-	}
-
-	void GpuParams::setParamBlockBuffer(UINT32 slot, const GpuParamBlockBufferPtr& paramBlockBuffer)
-	{
-		if (slot < 0 || slot >= mInternalData->mNumParamBlocks)
+		for (auto& sampler : mParamDesc->samplers)
 		{
-			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " + 
-				toString(mInternalData->mNumParamBlocks - 1) + ". Requested: " + toString(slot));
+			if ((sampler.second.slot + 1) > mNumSamplerStates)
+				mNumSamplerStates = sampler.second.slot + 1;
 		}
 
-		mInternalData->mParamBlockBuffers[slot] = paramBlockBuffer;
-		mInternalData->mParamBlocks[slot] = paramBlockBuffer->getParamBlock();
-
-		markCoreDirty();
+		mTextureInfo = bs_newN<BoundTextureInfo>(mNumTextures);
 	}
 
-	void GpuParams::setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer)
+	GpuParamsBase::~GpuParamsBase()
 	{
-		auto iterFind = mParamDesc->paramBlocks.find(name);
-
-		if(iterFind == mParamDesc->paramBlocks.end())
-		{
-			LOGWRN("Cannot find parameter block with the name: " + name);
-			return;
-		}
-
-		mInternalData->mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
-		mInternalData->mParamBlocks[iterFind->second.slot] = paramBlockBuffer != nullptr ? paramBlockBuffer->getParamBlock() : nullptr;
-
-		markCoreDirty();
+		bs_deleteN(mTextureInfo, mNumTextures);
 	}
 
-	UINT32 GpuParams::getDataParamSize(const String& name) const
+UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 	{
 		GpuParamDataDesc* desc = getParamDesc(name);
 		if(desc != nullptr)
@@ -113,12 +47,12 @@ namespace BansheeEngine
 		return 0;
 	}
 
-	bool GpuParams::hasParam(const String& name) const
+	bool GpuParamsBase::hasParam(const String& name) const
 	{
 		return getParamDesc(name) != nullptr;
 	}
 
-	bool GpuParams::hasTexture(const String& name) const
+	bool GpuParamsBase::hasTexture(const String& name) const
 	{
 		auto paramIter = mParamDesc->textures.find(name);
 		if(paramIter != mParamDesc->textures.end())
@@ -127,7 +61,7 @@ namespace BansheeEngine
 		return false;
 	}
 
-	bool GpuParams::hasSamplerState(const String& name) const
+	bool GpuParamsBase::hasSamplerState(const String& name) const
 	{
 		auto paramIter = mParamDesc->samplers.find(name);
 		if(paramIter != mParamDesc->samplers.end())
@@ -136,7 +70,7 @@ namespace BansheeEngine
 		return false;
 	}
 
-	bool GpuParams::hasParamBlock(const String& name) const
+	bool GpuParamsBase::hasParamBlock(const String& name) const
 	{
 		auto paramBlockIter = mParamDesc->paramBlocks.find(name);
 		if(paramBlockIter != mParamDesc->paramBlocks.end())
@@ -145,317 +79,118 @@ namespace BansheeEngine
 		return false;
 	}
 
-	void GpuParams::getStructParam(const String& name, GpuParamStruct& output) const
-	{
-		auto iterFind = mParamDesc->params.find(name);
-
-		if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_STRUCT)
-		{
-			output = GpuParamStruct(&iterFind->second, nullptr);
-			LOGWRN("Cannot find struct parameter with the name '" + name + "'");
-		}
-		else
-			output = GpuParamStruct(&iterFind->second, mInternalData);
-	}
-
-	void GpuParams::getTextureParam(const String& name, GpuParamTexture& output) const
-	{
-		auto iterFind = mParamDesc->textures.find(name);
-
-		if (iterFind == mParamDesc->textures.end())
-		{
-			output = GpuParamTexture(&iterFind->second, nullptr);
-			LOGWRN("Cannot find texture parameter with the name '" + name + "'");
-		}
-		else
-			output = GpuParamTexture(&iterFind->second, mInternalData);
-	}
-
-	void GpuParams::getLoadStoreTextureParam(const String& name, GpuParamLoadStoreTexture& output) const
-	{
-		auto iterFind = mParamDesc->textures.find(name);
-
-		if (iterFind == mParamDesc->textures.end())
-		{
-			output = GpuParamLoadStoreTexture(&iterFind->second, nullptr);
-			LOGWRN("Cannot find texture parameter with the name '" + name + "'");
-		}
-		else
-			output = GpuParamLoadStoreTexture(&iterFind->second, mInternalData);
-	}
-
-	void GpuParams::getSamplerStateParam(const String& name, GpuParamSampState& output) const
-	{
-		auto iterFind = mParamDesc->samplers.find(name);
-
-		if (iterFind == mParamDesc->samplers.end())
-		{
-			output = GpuParamSampState(&iterFind->second, nullptr);
-			LOGWRN("Cannot find sampler state parameter with the name '" + name + "'");
-		}
-		else
-			output = GpuParamSampState(&iterFind->second, mInternalData);
-	}
-
-	GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const
+	GpuParamDataDesc* GpuParamsBase::getParamDesc(const String& name) const
 	{
 		auto paramIter = mParamDesc->params.find(name);
-		if(paramIter != mParamDesc->params.end())
+		if (paramIter != mParamDesc->params.end())
 			return &paramIter->second;
 
 		return nullptr;
 	}
 
-	GpuParamBlockBufferPtr GpuParams::getParamBlockBuffer(UINT32 slot) const
+	bool GpuParamsBase::isLoadStoreTexture(UINT32 slot) const
 	{
-		if (slot < 0 || slot >= mInternalData->mNumParamBlocks)
+		if (slot < 0 || slot >= mNumTextures)
 		{
 			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
-				toString(mInternalData->mNumParamBlocks - 1) + ". Requested: " + toString(slot));
+				toString(mNumTextures - 1) + ". Requested: " + toString(slot));
 		}
 
-		return mInternalData->mParamBlockBuffers[slot];
+		return mTextureInfo[slot].isLoadStore;
 	}
 
-	HTexture GpuParams::getTexture(UINT32 slot)
+	void GpuParamsBase::setIsLoadStoreTexture(UINT32 slot, bool isLoadStore)
 	{
-		if (slot < 0 || slot >= mInternalData->mNumTextures)
+		if (slot < 0 || slot >= mNumTextures)
 		{
 			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
-				toString(mInternalData->mNumTextures - 1) + ". Requested: " + toString(slot));
+				toString(mNumTextures - 1) + ". Requested: " + toString(slot));
 		}
 
-		return mInternalData->mTextures[slot];
+		mTextureInfo[slot].isLoadStore = isLoadStore;
 	}
 
-	HSamplerState GpuParams::getSamplerState(UINT32 slot)
+	const TextureSurface& GpuParamsBase::getLoadStoreSurface(UINT32 slot) const
 	{
-		if (slot < 0 || slot >= mInternalData->mNumSamplerStates)
+		if (slot < 0 || slot >= mNumTextures)
 		{
 			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
-				toString(mInternalData->mNumSamplerStates - 1) + ". Requested: " + toString(slot));
+				toString(mNumTextures - 1) + ". Requested: " + toString(slot));
 		}
 
-		return mInternalData->mSamplerStates[slot];
+		return mTextureInfo[slot].surface;
 	}
 
-	bool GpuParams::isLoadStoreTexture(UINT32 slot) const
+	void GpuParamsBase::setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const
 	{
-		if (slot < 0 || slot >= mInternalData->mNumTextures)
+		if (slot < 0 || slot >= mNumTextures)
 		{
 			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
-				toString(mInternalData->mNumTextures - 1) + ". Requested: " + toString(slot));
+				toString(mNumTextures - 1) + ". Requested: " + toString(slot));
 		}
 
-		return mInternalData->mTextureInfo[slot].isLoadStore;
+		mTextureInfo[slot].surface = surface;
 	}
 
-	const TextureSurface& GpuParams::getLoadStoreSurface(UINT32 slot) const
+	GpuParamsCore::GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
+		: TGpuParams(paramDesc, transposeMatrices)
 	{
-		if (slot < 0 || slot >= mInternalData->mNumTextures)
-		{
-			BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
-				toString(mInternalData->mNumTextures - 1) + ". Requested: " + toString(slot));
-		}
 
-		return mInternalData->mTextureInfo[slot].surface;
 	}
 
-	void GpuParams::updateHardwareBuffers()
+	void GpuParamsCore::updateHardwareBuffers()
 	{
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
+		for (UINT32 i = 0; i < mNumParamBlocks; i++)
 		{
-			if (mInternalData->mParamBlocks[i] != nullptr && mInternalData->mParamBlockBuffers[i] != nullptr)
+			if (mParamBlockBuffers[i] != nullptr)
 			{
-				if (mInternalData->mParamBlocks[i]->isDirty())
-					mInternalData->mParamBlocks[i]->uploadToBuffer(mInternalData->mParamBlockBuffers[i]);
+				mParamBlockBuffers[i]->flushToGPU();
 			}
 		}
 	}
 
-	void GpuParams::_updateFromCopy(const GpuParamsPtr& copy)
+	SPtr<GpuParamsCore> GpuParamsCore::create(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
 	{
-		assert(copy->mInternalData->mNumParamBlocks == mInternalData->mNumParamBlocks);
-		assert(copy->mInternalData->mNumTextures == mInternalData->mNumTextures);
-		assert(copy->mInternalData->mNumSamplerStates == mInternalData->mNumSamplerStates);
+		GpuParamsCore* params = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(paramDesc, transposeMatrices);
+		SPtr<GpuParamsCore> paramsPtr = bs_shared_ptr<GpuParamsCore, GenAlloc>(params);
+		paramsPtr->_setThisPtr(paramsPtr);
 
-		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
-		{
-			mInternalData->mTextures[i] = copy->mInternalData->mTextures[i];
-			mInternalData->mTextureInfo[i] = copy->mInternalData->mTextureInfo[i];
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
-		{
-			mInternalData->mSamplerStates[i] = copy->mInternalData->mSamplerStates[i];
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
-		{
-			GpuParamBlockPtr destParamBlock = mInternalData->mParamBlocks[i];
-			GpuParamBlockPtr srcParamBlock = copy->mInternalData->mParamBlocks[i];
-			if (destParamBlock != nullptr && srcParamBlock != nullptr)
-			{
-				destParamBlock->write(0, srcParamBlock->getData(), srcParamBlock->getSize());
-			}
-		}
+		return paramsPtr;
 	}
 
-	GpuParamsPtr GpuParams::_clone(FrameAlloc* frameAlloc, bool onlyDirtyBlocks) const
+	GpuParams::GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
+		: TGpuParams(paramDesc, transposeMatrices)
 	{
-		GpuParamsPtr myClone = nullptr;
-		
-		if (frameAlloc != nullptr)
-		{
-			StdFrameAlloc<std::shared_ptr<GpuParams>> myAlloc(frameAlloc);
-			myClone = std::allocate_shared<GpuParams>(myAlloc, mParamDesc, PrivatelyConstruct());
-			myClone->mInternalData = std::allocate_shared<GpuParamsInternalData>(myAlloc);
-		}
-		else
-		{
-			myClone = bs_shared_ptr<GpuParams>(mParamDesc, PrivatelyConstruct());;
-			myClone->mInternalData = bs_shared_ptr<GpuParamsInternalData>();
-		}
-		
-		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;
 
-		myClone->constructInternalBuffers(frameAlloc);
-
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
-		{
-			GpuParamBlockBufferPtr buffer = mInternalData->mParamBlockBuffers[i];
-			if (buffer != nullptr && (!onlyDirtyBlocks || buffer->getParamBlock()->isDirty()))
-			{
-				GpuParamBlockPtr newBlock = nullptr;
-				if (frameAlloc != nullptr)
-				{
-					StdFrameAlloc<GpuParams> myAlloc(frameAlloc);
-					newBlock = std::allocate_shared<GpuParamBlock>(myAlloc, frameAlloc, buffer->getSize());
-				}
-				else
-				{
-					newBlock = bs_shared_ptr<GpuParamBlock>(buffer->getSize());;
-				}
-
-				newBlock->write(0, buffer->getParamBlock()->getData(), buffer->getSize());
-				myClone->mInternalData->mParamBlocks[i] = newBlock;
-			}
-			else
-				myClone->mInternalData->mParamBlocks[i] = nullptr;
-
-			myClone->mInternalData->mParamBlockBuffers[i] = buffer;
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
-		{
-			myClone->mInternalData->mTextures[i] = mInternalData->mTextures[i];
-			myClone->mInternalData->mTextureInfo[i] = mInternalData->mTextureInfo[i];
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
-		{
-			myClone->mInternalData->mSamplerStates[i] = mInternalData->mSamplerStates[i];
-		}
-
-		return myClone;
 	}
 
-	void GpuParams::constructInternalBuffers(FrameAlloc* frameAlloc)
+	SPtr<GpuParamsCore> GpuParams::getCore() const
 	{
-		// Allocate everything in a single block of memory to get rid of extra memory allocations
-		UINT32 bufferSize = 0;
-		UINT32 paramBlockOffset = 0;
-		UINT32 paramBlockBufferOffset = 0;
-		UINT32 textureOffset = 0;
-		UINT32 samplerStateOffset = 0;
-		UINT32 textureInfoOffset = 0;
-
-		UINT32 paramBlockBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlockPtr);
-		UINT32 paramBlockBuffersBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
-		UINT32 textureBufferSize = mInternalData->mNumTextures * sizeof(HTexture);
-		UINT32 textureInfoBufferSize = mInternalData->mNumTextures * sizeof(BoundTextureInfo);
-		UINT32 samplerStateBufferSize = mInternalData->mNumSamplerStates * sizeof(HSamplerState);
-
-		bufferSize = paramBlockBufferSize + paramBlockBuffersBufferSize + textureBufferSize + samplerStateBufferSize + textureInfoBufferSize;
-		paramBlockOffset = 0;
-		paramBlockBufferOffset = paramBlockOffset + paramBlockBufferSize;
-		textureOffset = paramBlockBufferOffset + paramBlockBuffersBufferSize;
-		samplerStateOffset = textureOffset + textureBufferSize;
-		textureInfoOffset = samplerStateOffset + samplerStateBufferSize;
-
-		if (frameAlloc != nullptr)
-		{
-			mInternalData->mData = frameAlloc->alloc(bufferSize);
-			mInternalData->mFrameAlloc = frameAlloc;
-		}
-		else
-		{
-			mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
-			mInternalData->mFrameAlloc = nullptr;
-		}
-
-		mInternalData->mParamBlocks = (GpuParamBlockPtr*)(mInternalData->mData + paramBlockOffset);
-		mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)(mInternalData->mData + paramBlockBufferOffset);
-		mInternalData->mTextures = (HTexture*)(mInternalData->mData + textureOffset);
-		mInternalData->mSamplerStates = (HSamplerState*)(mInternalData->mData + samplerStateOffset);
-		mInternalData->mTextureInfo = (BoundTextureInfo*)(mInternalData->mData + textureInfoOffset);
-
-		// Ensure everything is constructed
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
-		{
-			{
-				GpuParamBlockPtr* ptrToIdx = (&mInternalData->mParamBlocks[i]);
-				ptrToIdx = new (&mInternalData->mParamBlocks[i]) GpuParamBlockPtr(nullptr);
-			}
-
-			{
-			GpuParamBlockBufferPtr* ptrToIdx = (&mInternalData->mParamBlockBuffers[i]);
-			ptrToIdx = new (&mInternalData->mParamBlockBuffers[i]) GpuParamBlockBufferPtr(nullptr);
-		}
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
-		{
-			{
-				HTexture* ptrToIdx = (&mInternalData->mTextures[i]);
-				ptrToIdx = new (&mInternalData->mTextures[i]) HTexture();
-			}
+		return std::static_pointer_cast<GpuParamsCore>(mCoreSpecific);
+	}
 
-			{
-				BoundTextureInfo* ptrToIdx = (&mInternalData->mTextureInfo[i]);
-				ptrToIdx = new (&mInternalData->mTextureInfo[i]) BoundTextureInfo();
-			}
-		}
+	SPtr<CoreObjectCore> GpuParams::createCore() const
+	{
+		GpuParamsCore* obj = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(mParamDesc, mTransposeMatrices);
 
-		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
-		{
-			HSamplerState* ptrToIdx = (&mInternalData->mSamplerStates[i]);
-			ptrToIdx = new (&mInternalData->mSamplerStates[i]) HSamplerState();
-		}
-	}
+		SPtr<CoreObjectCore> coreObj = bs_shared_ptr<GpuParamsCore, GenAlloc>(obj);
+		coreObj->_setThisPtr(coreObj);
 
-	bool GpuParams::_isCoreDirty() const 
-	{ 
-		return mInternalData->mCoreDirtyFlags != 0; 
+		return coreObj;
 	}
 
-	void GpuParams::_markCoreClean()
+	void GpuParams::_markCoreDirty()
 	{
-		mInternalData->mCoreDirtyFlags = 0;
-
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
-		{
-			if (mInternalData->mParamBlocks[i] != nullptr)
-				mInternalData->mParamBlocks[i]->setDirty(false);
-		}
+		markCoreDirty();
 	}
 
-	void GpuParams::markCoreDirty() 
-	{ 
-		mInternalData->mCoreDirtyFlags = 0xFFFFFFFF; 
+	SPtr<GpuParams> GpuParams::create(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
+	{
+		GpuParams* params = new (bs_alloc<GpuParams>()) GpuParams(paramDesc, transposeMatrices);
+		SPtr<GpuParams> paramsPtr = bs_core_ptr<GpuParams, GenAlloc>(params);
+		paramsPtr->_setThisPtr(paramsPtr);
+		paramsPtr->initialize();
+		
+		return paramsPtr;
 	}
 }

+ 3 - 3
BansheeCore/Source/BsGpuProgram.cpp

@@ -42,9 +42,9 @@ namespace BansheeEngine
 		return true;
 	}
 
-	GpuParamsPtr GpuProgramCore::createParameters()
+	SPtr<GpuParamsCore> GpuProgramCore::createParameters()
 	{
-		return bs_shared_ptr<GpuParams, PoolAlloc>(mParametersDesc, false);
+		return GpuParamsCore::create(mParametersDesc, false);
 	}
 
 	GpuProgram::GpuProgram(const String& source, const String& entryPoint, const String& language,
@@ -67,7 +67,7 @@ namespace BansheeEngine
 
 	GpuParamsPtr GpuProgram::createParameters()
 	{
-		return getCore()->createParameters();
+		return GpuParams::create(getCore()->getParamDesc(), getCore()->hasColumnMajorMatrices());
 	}
 
 	GpuParamDescPtr GpuProgram::getParamDesc() const

+ 14 - 131
BansheeCore/Source/BsMaterial.cpp

@@ -535,7 +535,7 @@ namespace BansheeEngine
 
 	MaterialParamFloat Material::getParamFloat(const String& name) const
 	{
-		TMaterialDataParam<float> gpuParam;
+		TMaterialDataParam<float, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -543,7 +543,7 @@ namespace BansheeEngine
 
 	MaterialParamColor Material::getParamColor(const String& name) const
 	{
-		TMaterialDataParam<Color> gpuParam;
+		TMaterialDataParam<Color, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -551,7 +551,7 @@ namespace BansheeEngine
 
 	MaterialParamVec2 Material::getParamVec2(const String& name) const
 	{
-		TMaterialDataParam<Vector2> gpuParam;
+		TMaterialDataParam<Vector2, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -559,7 +559,7 @@ namespace BansheeEngine
 
 	MaterialParamVec3 Material::getParamVec3(const String& name) const
 	{
-		TMaterialDataParam<Vector3> gpuParam;
+		TMaterialDataParam<Vector3, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -567,7 +567,7 @@ namespace BansheeEngine
 
 	MaterialParamVec4 Material::getParamVec4(const String& name) const
 	{
-		TMaterialDataParam<Vector4> gpuParam;
+		TMaterialDataParam<Vector4, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -575,7 +575,7 @@ namespace BansheeEngine
 
 	MaterialParamMat3 Material::getParamMat3(const String& name) const
 	{
-		TMaterialDataParam<Matrix3> gpuParam;
+		TMaterialDataParam<Matrix3, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -583,7 +583,7 @@ namespace BansheeEngine
 
 	MaterialParamMat4 Material::getParamMat4(const String& name) const
 	{
-		TMaterialDataParam<Matrix4> gpuParam;
+		TMaterialDataParam<Matrix4, false> gpuParam;
 		getParam(name, gpuParam);
 
 		return gpuParam;
@@ -730,22 +730,7 @@ namespace BansheeEngine
 
 	bool Material::_isCoreDirty(MaterialDirtyFlag flag) const
 	{ 
-		if (flag == MaterialDirtyFlag::Params)
-		{
-			for (auto& paramsPerPass : mParametersPerPass)
-			{
-				for (UINT32 i = 0; i < paramsPerPass->getNumParams(); i++)
-				{
-					GpuParamsPtr params = paramsPerPass->getParamByIdx(i);
-					if (params != nullptr && params->_isCoreDirty())
-						return true;
-				}
-			}
-
-			return false;
-		}
-		else
-			return (mCoreDirtyFlags & (UINT32)flag) != 0 || (mShader != nullptr && mShader->_isCoreDirty(ShaderDirtyFlag::Shader));
+		return (mCoreDirtyFlags & (UINT32)flag) != 0 || (mShader != nullptr && mShader->_isCoreDirty(ShaderDirtyFlag::Shader));
 	}
 
 	void Material::_markCoreClean(MaterialDirtyFlag flag)
@@ -757,108 +742,6 @@ namespace BansheeEngine
 			if (mShader != nullptr)
 				mShader->_markCoreClean(ShaderDirtyFlag::Shader);
 		}
-		
-		if (flag == MaterialDirtyFlag::Material || flag == MaterialDirtyFlag::Params)
-		{
-			for (auto& paramsPerPass : mParametersPerPass)
-			{
-				for (UINT32 i = 0; i < paramsPerPass->getNumParams(); i++)
-				{
-					GpuParamsPtr params = paramsPerPass->getParamByIdx(i);
-
-					if (params != nullptr)
-						params->_markCoreClean();
-				}
-			}
-		}
-	}
-
-	MaterialProxy::DirtyParamsInfo* Material::_getDirtyProxyParams(FrameAlloc* frameAlloc)
-	{
-		UINT32 numDirtyParams = 0;
-		UINT32 numPasses = mShader->getBestTechnique()->getNumPasses();
-		for (UINT32 i = 0; i < numPasses; i++)
-		{
-			PassParametersPtr params = mParametersPerPass[i];
-			PassPtr pass = mShader->getBestTechnique()->getPass(i);
-
-			if (pass->hasVertexProgram() && params->mVertParams->_isCoreDirty())
-				numDirtyParams++;
-
-			if (pass->hasFragmentProgram() && params->mFragParams->_isCoreDirty())
-				numDirtyParams++;
-
-			if (pass->hasGeometryProgram() && params->mGeomParams->_isCoreDirty())
-				numDirtyParams++;
-
-			if (pass->hasHullProgram() && params->mHullParams->_isCoreDirty())
-				numDirtyParams++;
-
-			if (pass->hasDomainProgram() && params->mDomainParams->_isCoreDirty())
-				numDirtyParams++;
-
-			if (pass->hasComputeProgram() && params->mComputeParams->_isCoreDirty())
-				numDirtyParams++;
-		}
-
-		MaterialProxy::DirtyParamsInfo* dirtyParamsInfo = MaterialProxy::DirtyParamsInfo::create(frameAlloc, numDirtyParams);
-		
-		UINT32 idx = 0;
-		for (UINT32 i = 0; i < numPasses; i++)
-		{
-			PassParametersPtr params = mParametersPerPass[i];
-			PassPtr pass = mShader->getBestTechnique()->getPass(i);
-
-			if (pass->hasVertexProgram() && params->mVertParams->_isCoreDirty())
-			{
-				dirtyParamsInfo->entries[idx].paramsIdx = idx;
-				dirtyParamsInfo->entries[idx].params = params->mVertParams->_clone(frameAlloc);
-
-				idx++;
-			}
-
-			if (pass->hasFragmentProgram() && params->mFragParams->_isCoreDirty())
-			{
-				dirtyParamsInfo->entries[idx].paramsIdx = idx;
-				dirtyParamsInfo->entries[idx].params = params->mFragParams->_clone(frameAlloc);
-
-				idx++;
-			}
-
-			if (pass->hasGeometryProgram() && params->mGeomParams->_isCoreDirty())
-			{
-				dirtyParamsInfo->entries[idx].paramsIdx = idx;
-				dirtyParamsInfo->entries[idx].params = params->mGeomParams->_clone(frameAlloc);
-
-				idx++;
-			}
-
-			if (pass->hasHullProgram() && params->mHullParams->_isCoreDirty())
-			{
-				dirtyParamsInfo->entries[idx].paramsIdx = idx;
-				dirtyParamsInfo->entries[idx].params = params->mHullParams->_clone(frameAlloc);
-
-				idx++;
-			}
-
-			if (pass->hasDomainProgram() && params->mDomainParams->_isCoreDirty())
-			{
-				dirtyParamsInfo->entries[idx].paramsIdx = idx;
-				dirtyParamsInfo->entries[idx].params = params->mDomainParams->_clone(frameAlloc);
-
-				idx++;
-			}
-
-			if (pass->hasComputeProgram() && params->mComputeParams->_isCoreDirty())
-			{
-				dirtyParamsInfo->entries[idx].paramsIdx = idx;
-				dirtyParamsInfo->entries[idx].params = params->mComputeParams->_clone(frameAlloc);
-
-				idx++;
-			}
-		}
-
-		return dirtyParamsInfo;
 	}
 
 	MaterialProxyPtr Material::_createProxy()
@@ -880,7 +763,7 @@ namespace BansheeEngine
 			{
 				passData.vertexProg = pass->getVertexProgram();
 				passData.vertexProgParamsIdx = (UINT32)proxy->params.size();
-				proxy->params.push_back(params->mVertParams->_clone());
+				proxy->params.push_back(params->mVertParams->getCore());
 			}
 			else
 				passData.vertexProgParamsIdx = 0;
@@ -889,7 +772,7 @@ namespace BansheeEngine
 			{
 				passData.fragmentProg = pass->getFragmentProgram();
 				passData.fragmentProgParamsIdx = (UINT32)proxy->params.size();
-				proxy->params.push_back(params->mFragParams->_clone());
+				proxy->params.push_back(params->mFragParams->getCore());
 			}
 			else
 				passData.fragmentProgParamsIdx = 0;
@@ -898,7 +781,7 @@ namespace BansheeEngine
 			{
 				passData.geometryProg = pass->getGeometryProgram();
 				passData.geometryProgParamsIdx = (UINT32)proxy->params.size();
-				proxy->params.push_back(params->mGeomParams->_clone());
+				proxy->params.push_back(params->mGeomParams->getCore());
 			}
 			else
 				passData.geometryProgParamsIdx = 0;
@@ -907,7 +790,7 @@ namespace BansheeEngine
 			{
 				passData.hullProg = pass->getHullProgram();
 				passData.hullProgParamsIdx = (UINT32)proxy->params.size();
-				proxy->params.push_back(params->mHullParams->_clone());
+				proxy->params.push_back(params->mHullParams->getCore());
 			}
 			else
 				passData.hullProgParamsIdx = 0;
@@ -916,7 +799,7 @@ namespace BansheeEngine
 			{
 				passData.domainProg = pass->getDomainProgram();
 				passData.domainProgParamsIdx = (UINT32)proxy->params.size();
-				proxy->params.push_back(params->mDomainParams->_clone());
+				proxy->params.push_back(params->mDomainParams->getCore());
 			}
 			else
 				passData.domainProgParamsIdx = 0;
@@ -925,7 +808,7 @@ namespace BansheeEngine
 			{
 				passData.computeProg = pass->getComputeProgram();
 				passData.computeProgParamsIdx = (UINT32)proxy->params.size();
-				proxy->params.push_back(params->mComputeParams->_clone());
+				proxy->params.push_back(params->mComputeParams->getCore());
 			}
 			else
 				passData.computeProgParamsIdx = 0;

+ 0 - 32
BansheeCore/Source/BsMaterialProxy.cpp

@@ -1,38 +1,6 @@
 #include "BsMaterialProxy.h"
-#include "BsFrameAlloc.h"
 
 namespace BansheeEngine
 {
-	MaterialProxy::DirtyParamsInfo* MaterialProxy::DirtyParamsInfo::create(FrameAlloc* alloc, UINT32 numParams)
-	{
-		UINT32 sizeRequired = sizeof(DirtyParamsInfo) + numParams * sizeof(ParamsBindInfo);
-		UINT8* buffer = (UINT8*)alloc->alloc(sizeRequired);
 
-		MaterialProxy::DirtyParamsInfo* dirtyParamsInfo = (MaterialProxy::DirtyParamsInfo*)buffer;
-		dirtyParamsInfo->numEntries = numParams;
-		dirtyParamsInfo->owner = alloc;
-
-		buffer += sizeof(MaterialProxy::DirtyParamsInfo);
-		MaterialProxy::ParamsBindInfo* paramsInfoArray = (MaterialProxy::ParamsBindInfo*)buffer;
-		dirtyParamsInfo->entries = paramsInfoArray;
-
-		// Construct shared pointers
-		for (UINT32 i = 0; i < numParams; i++)
-		{
-			new (&dirtyParamsInfo->entries[i].params) GpuParamBlockPtr(nullptr);
-		}
-
-		return dirtyParamsInfo;
-	}
-
-	void MaterialProxy::DirtyParamsInfo::destroy(DirtyParamsInfo* paramsInfo)
-	{
-		// Destruct shared pointers
-		for (UINT32 i = 0; i < paramsInfo->numEntries; i++)
-		{
-			paramsInfo->entries[i].params.~shared_ptr();
-		}
-
-		paramsInfo->owner->dealloc((UINT8*)paramsInfo);
-	}
 }

+ 2 - 2
BansheeD3D11RenderSystem/Include/BsD3D11GpuParamBlockBuffer.h

@@ -16,12 +16,12 @@ namespace BansheeEngine
 		/**
 		 * @copydoc GpuParamBlockBufferCore::writeData.
 		 */
-		void writeData(const UINT8* data);
+		void writeToGPU(const UINT8* data);
 
 		/**
 		 * @copydoc GpuParamBlockBufferCore::readData.
 		 */
-		void readData(UINT8* data) const;
+		void readFromGPU(UINT8* data) const;
 
 		/**
 		 * @brief	Returns internal DX11 buffer object.

+ 2 - 2
BansheeD3D11RenderSystem/Include/BsD3D11GpuProgram.h

@@ -14,9 +14,9 @@ namespace BansheeEngine
 		virtual ~D3D11GpuProgramCore();
 
 		/**
-		 * @copydoc	GpuProgramCore::createParameters
+		 * @copydoc	GpuProgramCore::hasColumnMajorMatrices
 		 */
-		GpuParamsPtr createParameters();
+		bool hasColumnMajorMatrices() const { return mColumnMajorMatrices; }
 
 		/**
 		 * @brief	Returns compiled shader microcode.

+ 1 - 1
BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h

@@ -139,7 +139,7 @@ namespace BansheeEngine
 		/** 
 		 * @copydoc RenderSystem::bindGpuParams
 		 */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& params);
 		
 		/**
 		 * @copydoc	RenderSystem::setClipPlanesImpl

+ 2 - 2
BansheeD3D11RenderSystem/Source/BsD3D11GpuParamBlockBuffer.cpp

@@ -44,14 +44,14 @@ namespace BansheeEngine
 		return mBuffer->getD3DBuffer();
 	}
 
-	void D3D11GpuParamBlockBufferCore::writeData(const UINT8* data)
+	void D3D11GpuParamBlockBufferCore::writeToGPU(const UINT8* data)
 	{
 		mBuffer->writeData(0, mSize, data, BufferWriteType::Discard);
 
 		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_GpuParamBuffer);
 	}
 
-	void D3D11GpuParamBlockBufferCore::readData(UINT8* data) const
+	void D3D11GpuParamBlockBufferCore::readFromGPU(UINT8* data) const
 	{
 		mBuffer->readData(0, mSize, data);
 

+ 0 - 6
BansheeD3D11RenderSystem/Source/BsD3D11GpuProgram.cpp

@@ -146,12 +146,6 @@ namespace BansheeEngine
 		}
 	}
 
-	GpuParamsPtr D3D11GpuProgramCore::createParameters()
-	{
-		GpuParamsPtr params = bs_shared_ptr<GpuParams, PoolAlloc>(mParametersDesc, mColumnMajorMatrices);
-		return params;
-	}
-
 	D3D11GpuVertexProgramCore::D3D11GpuVertexProgramCore(const String& source, const String& entryPoint,
 		GpuProgramProfile profile)
 		: D3D11GpuProgramCore(source, entryPoint, GPT_VERTEX_PROGRAM, profile, false)

+ 10 - 10
BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp

@@ -554,7 +554,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumGpuProgramBinds);
 	}
 
-	void D3D11RenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr bindableParams)
+	void D3D11RenderSystem::bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& bindableParams)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -564,33 +564,33 @@ namespace BansheeEngine
 		
 		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
-			HSamplerState& samplerState = bindableParams->getSamplerState(iter->second.slot);
+			SPtr<SamplerStateCore>& samplerState = bindableParams->getSamplerState(iter->second.slot);
 
 			if(samplerState == nullptr)
 				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault()->getCore());
 			else
-				setSamplerState(gptype, iter->second.slot, samplerState->getCore());
+				setSamplerState(gptype, iter->second.slot, samplerState);
 		}
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
 		{
-			HTexture texture = bindableParams->getTexture(iter->second.slot);
+			SPtr<TextureCore> texture = bindableParams->getTexture(iter->second.slot);
 
 			if (!bindableParams->isLoadStoreTexture(iter->second.slot))
 			{
-				if (!texture.isLoaded())
+				if (texture == nullptr)
 					setTexture(gptype, iter->second.slot, false, nullptr);
 				else
-					setTexture(gptype, iter->second.slot, true, texture->getCore());
+					setTexture(gptype, iter->second.slot, true, texture);
 			}
 			else
 			{
 				const TextureSurface& surface = bindableParams->getLoadStoreSurface(iter->second.slot);
 
-				if (!texture.isLoaded())
+				if (texture == nullptr)
 					setLoadStoreTexture(gptype, iter->second.slot, false, nullptr, surface);
 				else
-					setLoadStoreTexture(gptype, iter->second.slot, true, texture->getCore(), surface);
+					setLoadStoreTexture(gptype, iter->second.slot, true, texture, surface);
 			}
 		}
 
@@ -600,12 +600,12 @@ namespace BansheeEngine
 
 		for(auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
 		{
-			GpuParamBlockBufferPtr currentBlockBuffer = bindableParams->getParamBlockBuffer(iter->second.slot);
+			SPtr<GpuParamBlockBufferCore> currentBlockBuffer = bindableParams->getParamBlockBuffer(iter->second.slot);
 
 			if(currentBlockBuffer != nullptr)
 			{
 				const D3D11GpuParamBlockBufferCore* d3d11paramBlockBuffer = 
-					static_cast<const D3D11GpuParamBlockBufferCore*>(currentBlockBuffer->getCore().get());
+					static_cast<const D3D11GpuParamBlockBufferCore*>(currentBlockBuffer.get());
 				bufferArray[0] = d3d11paramBlockBuffer->getD3D11Buffer();
 			}
 			else

+ 2 - 2
BansheeD3D9RenderSystem/Include/BsD3D9GpuProgram.h

@@ -39,9 +39,9 @@ namespace BansheeEngine
 		void setOptimizationLevel(OptimizationLevel opt) { mOptimisationLevel = opt; }
 
 		/**
-		 * @copydoc	GpuProgramCore::createParameters
+		 * @copydoc	GpuProgramCore::hasColumnMajorMatrices
 		 */
-		GpuParamsPtr createParameters();
+		bool hasColumnMajorMatrices() const { return mColumnMajorMatrices; }
 
     protected:
 		friend class D3D9HLSLProgramFactory;

+ 1 - 1
BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h

@@ -48,7 +48,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderSystem::bindGpuParams()
 		 */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& params);
 
 		/**
 		 * @copydoc RenderSystem::setVertexBuffers()

+ 0 - 7
BansheeD3D9RenderSystem/Source/BsD3D9GpuProgram.cpp

@@ -207,13 +207,6 @@ namespace BansheeEngine
 		GpuProgramCore::destroy();
 	}
 
-	GpuParamsPtr D3D9GpuProgramCore::createParameters()
-	{
-		GpuParamsPtr params = bs_shared_ptr<GpuParams, PoolAlloc>(std::ref(mParametersDesc), mColumnMajorMatrices);
-
-		return params;
-	}
-
 	D3D9GpuVertexProgramCore::D3D9GpuVertexProgramCore(const String& source, const String& entryPoint,
 		GpuProgramProfile profile)
 		: D3D9GpuProgramCore(source, entryPoint, GPT_VERTEX_PROGRAM, profile)

+ 8 - 10
BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp

@@ -269,7 +269,7 @@ namespace BansheeEngine
 		RenderSystem::unbindGpuProgram(gptype);
 	}
 
-	void D3D9RenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr bindableParams)
+	void D3D9RenderSystem::bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& bindableParams)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -278,12 +278,11 @@ namespace BansheeEngine
 
 		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
-			HSamplerState& samplerState = bindableParams->getSamplerState(iter->second.slot);
-
+			SPtr<SamplerStateCore> samplerState = bindableParams->getSamplerState(iter->second.slot);
 			if(samplerState == nullptr)
 				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault()->getCore());
 			else
-				setSamplerState(gptype, iter->second.slot, samplerState->getCore());
+				setSamplerState(gptype, iter->second.slot, samplerState);
 		}
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
@@ -291,12 +290,11 @@ namespace BansheeEngine
 			if (bindableParams->isLoadStoreTexture(iter->second.slot))
 				continue; // Not supported by DX9
 
-			HTexture texture = bindableParams->getTexture(iter->second.slot);
-
-			if(!texture.isLoaded())
+			SPtr<TextureCore> texture = bindableParams->getTexture(iter->second.slot);
+			if(texture == nullptr)
 				setTexture(gptype, iter->second.slot, false, nullptr);
 			else
-				setTexture(gptype, iter->second.slot, true, texture->getCore());
+				setTexture(gptype, iter->second.slot, true, texture);
 		}
 
 		// Read all the buffer data so we can assign it. Not the most efficient way of accessing data
@@ -310,10 +308,10 @@ namespace BansheeEngine
 
 			if(iterFind == bufferData.end())
 			{
-				GpuParamBlockBufferPtr paramBlock = bindableParams->getParamBlockBuffer(paramBlockSlot);
+				SPtr<GpuParamBlockBufferCore> paramBlock = bindableParams->getParamBlockBuffer(paramBlockSlot);
 
 				UINT8* data = (UINT8*)bs_alloc<ScratchAlloc>(paramBlock->getSize());
-				paramBlock->getCore()->readData(data);
+				paramBlock->readFromGPU(data);
 
 				bufferData[paramBlockSlot] = data;
 			}

+ 10 - 10
BansheeEditor/Include/BsGizmoManager.h

@@ -92,7 +92,7 @@ namespace BansheeEngine
 		struct IconRenderData
 		{
 			UINT32 count;
-			HTexture texture;
+			SPtr<TextureCore> texture;
 		};
 
 		struct CoreInitData
@@ -171,35 +171,35 @@ namespace BansheeEngine
 		struct SolidMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamMat4 mViewProj;
+			GpuParamMat4Core mViewProj;
 		};
 
 		struct WireMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamMat4 mViewProj;
+			GpuParamMat4Core mViewProj;
 		};
 
 		struct IconMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamsPtr mFragParams[2];
-			GpuParamMat4 mViewProj[2];
-			GpuParamTexture mTexture[2];
+			SPtr<GpuParamsCore> mFragParams[2];
+			GpuParamMat4Core mViewProj[2];
+			GpuParamTextureCore mTexture[2];
 		};
 
 		struct PickingMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamMat4 mViewProj;
+			GpuParamMat4Core mViewProj;
 		};
 
 		struct AlphaPickingMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamsPtr mFragParams;
-			GpuParamMat4 mViewProj;
-			GpuParamTexture mTexture;
+			SPtr<GpuParamsCore> mFragParams;
+			GpuParamMat4Core mViewProj;
+			GpuParamTextureCore mTexture;
 		};
 
 		struct PrivatelyConstuct { };

+ 2 - 2
BansheeEditor/Include/BsHandleDrawManager.h

@@ -50,13 +50,13 @@ namespace BansheeEngine
 		struct SolidMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamMat4 mViewProj;
+			GpuParamMat4Core mViewProj;
 		};
 
 		struct WireMaterialData
 		{
 			MaterialProxyPtr proxy;
-			GpuParamMat4 mViewProj;
+			GpuParamMat4Core mViewProj;
 		};
 
 		enum class MeshType

+ 9 - 9
BansheeEditor/Include/BsScenePicking.h

@@ -29,16 +29,16 @@ namespace BansheeEngine
 			MaterialProxyPtr mMatPickingProxy;
 			MaterialProxyPtr mMatPickingAlphaProxy;
 
-			GpuParamsPtr mParamPickingVertParams;
-			GpuParamsPtr mParamPickingFragParams;
-			GpuParamsPtr mParamPickingAlphaVertParams;
-			GpuParamsPtr mParamPickingAlphaFragParams;
+			SPtr<GpuParamsCore> mParamPickingVertParams;
+			SPtr<GpuParamsCore> mParamPickingFragParams;
+			SPtr<GpuParamsCore> mParamPickingAlphaVertParams;
+			SPtr<GpuParamsCore> mParamPickingAlphaFragParams;
 
-			GpuParamMat4 mParamPickingWVP;
-			GpuParamMat4 mParamPickingAlphaWVP;
-			GpuParamColor mParamPickingColor;
-			GpuParamColor mParamPickingAlphaColor;
-			GpuParamTexture mParamPickingAlphaTexture;
+			GpuParamMat4Core mParamPickingWVP;
+			GpuParamMat4Core mParamPickingAlphaWVP;
+			GpuParamColorCore mParamPickingColor;
+			GpuParamColorCore mParamPickingAlphaColor;
+			GpuParamTextureCore mParamPickingAlphaTexture;
 		};
 
 	public:

+ 8 - 8
BansheeEditor/Source/BsGizmoManager.cpp

@@ -506,7 +506,7 @@ namespace BansheeEngine
 					iconRenderData->push_back(IconRenderData());
 					IconRenderData& renderData = iconRenderData->back();
 					renderData.count = numIconsPerTexture;
-					renderData.texture = atlasTexture;
+					renderData.texture = atlasTexture->getCore();
 				}
 
 				lastTextureIdx = i;
@@ -649,22 +649,22 @@ namespace BansheeEngine
 		// TODO - Make a better interface when dealing with parameters through proxies?
 		{
 			MaterialProxyPtr proxy = mWireMaterial.proxy;
-			GpuParamsPtr vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
 
 			vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
 		}
 
 		{
 			MaterialProxyPtr proxy = mSolidMaterial.proxy;
-			GpuParamsPtr vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
 
 			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
 		}
 
 		{
 			MaterialProxyPtr proxy = mIconMaterial.proxy;
-			GpuParamsPtr vertParams0 = proxy->params[proxy->passes[0].vertexProgParamsIdx];
-			GpuParamsPtr vertParams1 = proxy->params[proxy->passes[1].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams0 = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams1 = proxy->params[proxy->passes[1].vertexProgParamsIdx];
 
 			vertParams0->getParam("matViewProj", mIconMaterial.mViewProj[0]);
 			vertParams1->getParam("matViewProj", mIconMaterial.mViewProj[1]);
@@ -678,21 +678,21 @@ namespace BansheeEngine
 
 		{
 			MaterialProxyPtr proxy = mPickingMaterial.proxy;
-			GpuParamsPtr vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
 
 			vertParams->getParam("matViewProj", mPickingMaterial.mViewProj);
 		}
 
 		{
 			MaterialProxyPtr proxy = mAlphaPickingMaterial.proxy;
-			GpuParamsPtr vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams = proxy->params[proxy->passes[0].vertexProgParamsIdx];
 
 			vertParams->getParam("matViewProj", mAlphaPickingMaterial.mViewProj);
 
 			mAlphaPickingMaterial.mFragParams = proxy->params[proxy->passes[0].fragmentProgParamsIdx];
 			mAlphaPickingMaterial.mFragParams->getTextureParam("mainTexture", mAlphaPickingMaterial.mTexture);
 
-			GpuParamFloat alphaCutoffParam;
+			GpuParamFloatCore alphaCutoffParam;
 			mAlphaPickingMaterial.mFragParams->getParam("alphaCutoff", alphaCutoffParam);
 			alphaCutoffParam.set(PICKING_ALPHA_CUTOFF);
 		}

+ 2 - 2
BansheeEditor/Source/BsHandleDrawManager.cpp

@@ -188,14 +188,14 @@ namespace BansheeEngine
 		// TODO - Make a better interface when dealing with parameters through proxies?
 		{
 			mWireMaterial.proxy = wireMatProxy;
-			GpuParamsPtr vertParams = wireMatProxy->params[wireMatProxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams = wireMatProxy->params[wireMatProxy->passes[0].vertexProgParamsIdx];
 
 			vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
 		}
 
 		{
 			mSolidMaterial.proxy = solidMatProxy;
-			GpuParamsPtr vertParams = solidMatProxy->params[solidMatProxy->passes[0].vertexProgParamsIdx];
+			SPtr<GpuParamsCore> vertParams = solidMatProxy->params[solidMatProxy->passes[0].vertexProgParamsIdx];
 
 			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
 		}

+ 2 - 2
BansheeEditor/Source/BsScenePicking.cpp

@@ -72,7 +72,7 @@ namespace BansheeEngine
 				md.mParamPickingAlphaFragParams->getParam("colorIndex", md.mParamPickingAlphaColor);
 				md.mParamPickingAlphaFragParams->getTextureParam("mainTexture", md.mParamPickingAlphaTexture);
 
-				GpuParamFloat alphaCutoffParam;
+				GpuParamFloatCore alphaCutoffParam;
 				md.mParamPickingAlphaFragParams->getParam("alphaCutoff", alphaCutoffParam);
 				alphaCutoffParam.set(ALPHA_CUTOFF);
 			}
@@ -254,7 +254,7 @@ namespace BansheeEngine
 			{
 				md.mParamPickingAlphaWVP.set(renderable.wvpTransform);
 				md.mParamPickingAlphaColor.set(color);
-				md.mParamPickingAlphaTexture.set(renderable.mainTexture);
+				md.mParamPickingAlphaTexture.set(renderable.mainTexture->getCore());
 
 				rs.bindGpuParams(GPT_VERTEX_PROGRAM, md.mParamPickingAlphaVertParams);
 				rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, md.mParamPickingAlphaFragParams);

+ 2 - 2
BansheeGLRenderSystem/Include/BsGLGpuParamBlockBuffer.h

@@ -16,12 +16,12 @@ namespace BansheeEngine
 		/**
 		 * @copydoc GpuParamBlockBufferCore::writeData
 		 */
-		void writeData(const UINT8* data);
+		void writeToGPU(const UINT8* data);
 
 		/**
 		 * @copydoc GpuParamBlockBufferCore::readData
 		 */
-		void readData(UINT8* data) const;
+		void readFromGPU(UINT8* data) const;
 
 		/**
 		 * @brief	Returns internal OpenGL uniform buffer handle.

+ 1 - 1
BansheeGLRenderSystem/Include/BsGLRenderSystem.h

@@ -107,7 +107,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc RenderSystem::bindGpuParams()
 		 */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& params);
 
 		/**
 		 * @copydoc RenderSystem::beginFrame()

+ 2 - 2
BansheeGLRenderSystem/Source/BsGLGpuParamBlockBuffer.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 		GpuParamBlockBufferCore::destroy();
 	}
 
-	void GLGpuParamBlockBufferCore::writeData(const UINT8* data)
+	void GLGpuParamBlockBufferCore::writeToGPU(const UINT8* data)
 	{
 		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
 		glBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, data);
@@ -43,7 +43,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_GpuParamBuffer);
 	}
 
-	void GLGpuParamBlockBufferCore::readData(UINT8* data) const
+	void GLGpuParamBlockBufferCore::readFromGPU(UINT8* data) const
 	{
 		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
 		glGetBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, (GLvoid*)data);

+ 11 - 12
BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp

@@ -246,7 +246,7 @@ namespace BansheeEngine
 		RenderSystem::unbindGpuProgram(gptype);
 	}
 
-	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr bindableParams)
+	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, const SPtr<GpuParamsCore>& bindableParams)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -257,34 +257,34 @@ namespace BansheeEngine
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
 		{
-			HTexture texture = bindableParams->getTexture(iter->second.slot);
+			SPtr<TextureCore> texture = bindableParams->getTexture(iter->second.slot);
 
 			if (!bindableParams->isLoadStoreTexture(iter->second.slot))
 			{
-				if (!texture.isLoaded())
+				if (texture == nullptr)
 					setTexture(gptype, iter->second.slot, false, nullptr);
 				else
-					setTexture(gptype, iter->second.slot, true, texture->getCore());
+					setTexture(gptype, iter->second.slot, true, texture);
 			}
 			else
 			{
 				const TextureSurface& surface = bindableParams->getLoadStoreSurface(iter->second.slot);
 
-				if (!texture.isLoaded())
+				if (texture == nullptr)
 					setLoadStoreTexture(gptype, iter->second.slot, false, nullptr, surface);
 				else
-					setLoadStoreTexture(gptype, iter->second.slot, true, texture->getCore(), surface);
+					setLoadStoreTexture(gptype, iter->second.slot, true, texture, surface);
 			}
 		}
 
 		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
-			HSamplerState& samplerState = bindableParams->getSamplerState(iter->second.slot);
+			SPtr<SamplerStateCore>& samplerState = bindableParams->getSamplerState(iter->second.slot);
 
 			if(samplerState == nullptr)
 				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault()->getCore());
 			else
-				setSamplerState(gptype, iter->second.slot, samplerState->getCore());
+				setSamplerState(gptype, iter->second.slot, samplerState);
 
 			glProgramUniform1i(glProgram, iter->second.slot, getGLTextureUnit(gptype, iter->second.slot));
 		}
@@ -294,24 +294,23 @@ namespace BansheeEngine
 		UINT32 blockBinding = 0;
 		for(auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
 		{
-			GpuParamBlockBufferPtr paramBlockBuffer = bindableParams->getParamBlockBuffer(iter->second.slot);
+			SPtr<GpuParamBlockBufferCore> paramBlockBuffer = bindableParams->getParamBlockBuffer(iter->second.slot);
 			if(paramBlockBuffer == nullptr)
 				continue;
 
-			SPtr<GpuParamBlockBufferCore> paramBlockBufferCore = paramBlockBuffer->getCore();
 			if(iter->second.slot == 0)
 			{
 				// 0 means uniforms are not in block, in which case we handle it specially
 				if (uniformBufferData == nullptr && paramBlockBuffer->getSize() > 0)
 				{
 					uniformBufferData = (UINT8*)bs_alloc<ScratchAlloc>(paramBlockBuffer->getSize());
-					paramBlockBufferCore->readData(uniformBufferData);
+					paramBlockBuffer->readFromGPU(uniformBufferData);
 				}
 
 				continue;
 			}
 
-			const GLGpuParamBlockBufferCore* glParamBlockBuffer = static_cast<const GLGpuParamBlockBufferCore*>(paramBlockBufferCore.get());
+			const GLGpuParamBlockBufferCore* glParamBlockBuffer = static_cast<const GLGpuParamBlockBufferCore*>(paramBlockBuffer.get());
 
 			UINT32 globalBlockBinding = getGLUniformBlockBinding(gptype, blockBinding);
 			glUniformBlockBinding(glProgram, iter->second.slot - 1, globalBlockBinding);

+ 2 - 2
BansheeGLRenderSystem/Source/GLSL/include/BsGLSLGpuProgram.h

@@ -37,9 +37,9 @@ namespace BansheeEngine
 		const UINT32 getProgramID() const { return mProgramID; }
 
 		/**
-		 * @copydoc	GpuProgramCore::createParameters
+		 * @copydoc	GpuProgramCore::hasColumnMajorMatrices
 		 */
-		GpuParamsPtr createParameters();
+		bool hasColumnMajorMatrices() const { return true; }
 
 	private:
 		friend class GLSLProgramFactory;

+ 0 - 7
BansheeGLRenderSystem/Source/GLSL/src/BsGLSLGpuProgram.cpp

@@ -215,12 +215,5 @@ namespace BansheeEngine
 		RenderSystem* rs = BansheeEngine::RenderSystem::instancePtr();
 		return rs->getCapabilities()->isShaderProfileSupported("glsl");
 	}
-
-	GpuParamsPtr GLSLGpuProgramCore::createParameters()
-	{
-		GpuParamsPtr params = bs_shared_ptr<GpuParams, PoolAlloc>(std::ref(mParametersDesc), true);
-
-		return params;
-	}
 }
 

+ 8 - 8
BansheeRenderer/Include/BsBansheeLitTexRenderableController.h

@@ -23,10 +23,10 @@ namespace BansheeEngine
 		 */
 		struct PerObjectData
 		{
-			GpuParamBlockBufferPtr perObjectParamBuffer;
+			SPtr<GpuParamBlockBufferCore> perObjectParamBuffer;
 
 			bool hasWVPParam = false;
-			GpuParamMat4 wvpParam;
+			GpuParamMat4Core wvpParam;
 
 			Vector<MaterialProxy::BufferBindInfo> perObjectBuffers;
 		};
@@ -73,13 +73,13 @@ namespace BansheeEngine
 		GpuParamDataDesc lightDirParamDesc;
 		GpuParamDataDesc wvpParamDesc;
 
-		GpuParamBlockBufferPtr staticParamBuffer;
-		GpuParamBlockBufferPtr perFrameParamBuffer;
+		SPtr<GpuParamBlockBufferCore> staticParamBuffer;
+		SPtr<GpuParamBlockBufferCore> perFrameParamBuffer;
 
-		GpuParamsPtr staticParams;
-		GpuParamsPtr perFrameParams;
+		SPtr<GpuParamsCore> staticParams;
+		SPtr<GpuParamsCore> perFrameParams;
 
-		GpuParamVec4 lightDirParam;
-		GpuParamFloat timeParam;
+		GpuParamVec4Core lightDirParam;
+		GpuParamFloatCore timeParam;
 	};
 }

+ 0 - 11
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -122,17 +122,6 @@ namespace BansheeEngine
 		 */
 		void addToRenderQueue(CameraProxyPtr proxy, RenderQueuePtr renderQueue);
 
-		/**
-		 * @brief	Updates a material proxy with new parameter data. Usually called when parameters are manually
-		 *			updated from the sim thread.
-		 *
-		 * @param	proxy		Material proxy to update.
-		 * @param	dirtyParams	A list of parameter buffers that need updating.
-		 *
-		 * @note	Core thread only.
-		 */
-		void updateMaterialProxy(MaterialProxyPtr proxy, MaterialProxy::DirtyParamsInfo* dirtyParams);
-
 		/**
 		 * @brief	Performs rendering over all camera proxies.
 		 *

+ 7 - 11
BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp

@@ -107,11 +107,11 @@ namespace BansheeEngine
 			BS_EXCEPT(InternalErrorException, "Invalid default shader.");
 
 		// Create global GPU param buffers and get parameter handles
-		staticParams = bs_shared_ptr<GpuParams>(staticParamsDesc, false);
-		perFrameParams = bs_shared_ptr<GpuParams>(perFrameParamsDesc, false);
+		staticParams = GpuParamsCore::create(staticParamsDesc, false);
+		perFrameParams = GpuParamsCore::create(perFrameParamsDesc, false);
 
-		staticParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(staticParamBlockDesc.blockSize * sizeof(UINT32));
-		perFrameParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(perFrameParamBlockDesc.blockSize * sizeof(UINT32));
+		staticParamBuffer = HardwareBufferCoreManager::instance().createGpuParamBlockBuffer(staticParamBlockDesc.blockSize * sizeof(UINT32));
+		perFrameParamBuffer = HardwareBufferCoreManager::instance().createGpuParamBlockBuffer(perFrameParamBlockDesc.blockSize * sizeof(UINT32));
 
 		staticParams->setParamBlockBuffer(staticParamBlockDesc.slot, staticParamBuffer);
 		perFrameParams->setParamBlockBuffer(perFrameParamBlockDesc.slot, perFrameParamBuffer);
@@ -206,7 +206,7 @@ namespace BansheeEngine
 					if (findIter->second.blockSize == perObjectParamBlockDesc.blockSize)
 					{
 						if (rendererData->perObjectParamBuffer == nullptr)
-							rendererData->perObjectParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(perObjectParamBlockDesc.blockSize * sizeof(UINT32));
+							rendererData->perObjectParamBuffer = HardwareBufferCoreManager::instance().createGpuParamBlockBuffer(perObjectParamBlockDesc.blockSize * sizeof(UINT32));
 
 						rendererData->perObjectBuffers.push_back(MaterialProxy::BufferBindInfo(idx, findIter->second.slot, rendererData->perObjectParamBuffer));
 
@@ -237,7 +237,7 @@ namespace BansheeEngine
 		const PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element->rendererData);
 		for (auto& perObjectBuffer : rendererData->perObjectBuffers)
 		{
-			GpuParamsPtr params = element->material->params[perObjectBuffer.paramsIdx];
+			SPtr<GpuParamsCore> params = element->material->params[perObjectBuffer.paramsIdx];
 
 			params->setParamBlockBuffer(perObjectBuffer.slotIdx, rendererData->perObjectParamBuffer);
 		}
@@ -259,11 +259,7 @@ namespace BansheeEngine
 			rendererData->wvpParam.set(wvpMatrix);
 
 		if (rendererData->perObjectParamBuffer != nullptr)
-		{
-			GpuParamBlockPtr paramBlock = rendererData->perObjectParamBuffer->getParamBlock();
-			if (paramBlock->isDirty())
-				paramBlock->uploadToBuffer(rendererData->perObjectParamBuffer);
-		}
+			rendererData->perObjectParamBuffer->flushToGPU();
 	}
 
 	ShaderPtr LitTexRenderableController::createDefaultShader()

+ 0 - 54
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -245,20 +245,6 @@ namespace BansheeEngine
 
 					dirtySceneObjects.push_back(renderableSO);
 				}
-
-				if (!addedNewProxy && proxy != nullptr)
-				{
-					for (UINT32 i = 0; i < (UINT32)proxy->renderableElements.size(); i++)
-					{
-						HMaterial mat = renderable->getMaterial(i);
-						if (mat != nullptr && mat.isLoaded() && mat->_isCoreDirty(MaterialDirtyFlag::Params))
-						{
-							gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateMaterialProxy, this,
-								proxy->renderableElements[i]->material, mat->_getDirtyProxyParams(frameAlloc)));
-							mat->_markCoreClean(MaterialDirtyFlag::Params);
-						}
-					}
-				}
 			}
 			else // If inactive we remove the proxy until re-activated
 			{
@@ -357,34 +343,17 @@ namespace BansheeEngine
 				// and only update when they actually change. That might also cause
 				// issue if material/mesh is used both in draw list and a Renderable
 
-				MaterialProxy::DirtyParamsInfo* dirtyParams = nullptr;
-				if (drawOp.material->_isCoreDirty(MaterialDirtyFlag::Params))
-				{
-					dirtyParams = drawOp.material->_getDirtyProxyParams(frameAlloc);
-				}
-
 				if (drawOp.material->_isCoreDirty(MaterialDirtyFlag::Proxy))
 				{
 					drawOp.material->_setActiveProxy(drawOp.material->_createProxy());
 					drawOp.material->_markCoreClean(MaterialDirtyFlag::Proxy);
 					drawOp.material->_markCoreClean(MaterialDirtyFlag::Material);
 				}
-				else
-				{
-					if (dirtyParams != nullptr)
-						drawOp.material->_markCoreClean(MaterialDirtyFlag::Params);
-				}
 
 				MaterialProxyPtr materialProxy = drawOp.material->_getActiveProxy();
 				SPtr<MeshCoreBase> meshCore = drawOp.mesh->getCore();
 				SubMesh subMesh = meshCore->getProperties().getSubMesh(drawOp.submeshIdx);
 
-				if (dirtyParams != nullptr)
-				{
-					gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateMaterialProxy, this,
-						materialProxy, dirtyParams));
-				}
-
 				float distanceToCamera = (cameraSO->getPosition() - drawOp.worldPosition).length();
 				renderQueue->add(materialProxy, meshCore, subMesh, distanceToCamera);
 			}
@@ -401,29 +370,6 @@ namespace BansheeEngine
 		cameraRenderQueue->add(*renderQueue);
 	}
 
-	void BansheeRenderer::updateMaterialProxy(MaterialProxyPtr proxy, MaterialProxy::DirtyParamsInfo* dirtyParams)
-	{
-		for (UINT32 i = 0; i < (UINT32)dirtyParams->numEntries; i++)
-		{
-			UINT32 paramsIdx = dirtyParams->entries[i].paramsIdx;
-
-			if (proxy->params[paramsIdx] == nullptr) 
-			{
-				assert(false); // This shouldn't happen. New params can only be added due to shader 
-							   // change and that should trigger new material proxy creation
-				continue;
-			}
-
-			proxy->params[dirtyParams->entries[i].paramsIdx]->_updateFromCopy(dirtyParams->entries[i].params);
-		}
-
-		// Refresh buffers set by renderer in case any were changed
-		for (auto& rendererBuffer : proxy->rendererBuffers)
-			proxy->params[rendererBuffer.paramsIdx]->setParamBlockBuffer(rendererBuffer.slotIdx, rendererBuffer.buffer);
-
-		MaterialProxy::DirtyParamsInfo::destroy(dirtyParams);
-	}
-
 	void BansheeRenderer::renderAllCore(float time)
 	{
 		THROW_IF_NOT_CORE_THREAD;

+ 25 - 2
TODO.txt

@@ -4,14 +4,37 @@ TODO - CoreObject refactor:
 Resource
  - Material -> Remove MaterialProxy
  - Shader -> Remove ShaderProxy
-GpuBuffer
-GpuParamBlockBuffer
 
 Also:
  - Make CameraHandler a Coreobject and remove CameraProxy
  - Make RenderableHandler a CoreObject and remove CameraProxy
  - Rename CoreObject initialize_internal and destroy_internal to initializeCore/destroyCore and make them private
 
+GpuParams refactor:
+
+Missing:
+ GpuParams::createCore
+ GpuParams::getCore
+
+ GpuParam versions for Core objects
+ Sync methods
+
+I need to ensure renderer buffers get set properly after GpuParams are synced
+ - This used to up in updateMaterialProxy along with updating dirty params but since syncing
+   is now internal to GpuParams I need to figure out a better way of doing it.
+   (In case user overrides Renderer buffers)
+    - Likely just an extra field on GPuParamsCore
+
+
+- Other:
+ - PerObjectData should store core version of GpuParamBlockBuffer
+
+Should I force CoreObject sync whenever submitCoreAccessors is called?
+ - This way I ensure the data is up to date. e.g. if user updates GpuParams and immediately performs
+   some rendering use CoreAccessor that update will not register.
+ - Also I can properly handle cases where sim thread needs to access core thread data immediately (e.g. RenderWindow HWND)
+ - I'd have to remove submit() calls from CoreAccessors themselves and leave just the one on CoreThread
+
 Disallow CoreObject creation from core thread
  - Add asserts in CoreObject::destroy and CoreObject::initialize
  - Possibly also add asserts to CoreThread::queueCommand and CoreThread::queueReturnCommand