Ver código fonte

Param buffer updates are now queued on the proper deferred context and are in general handled better

Marko Pintera 12 anos atrás
pai
commit
b0f44650c9
46 arquivos alterados com 707 adições e 428 exclusões
  1. 0 2
      BansheeForwardRenderer/Source/BsForwardRenderer.cpp
  2. 5 5
      CamelotClient/CamelotClient.cpp
  3. 5 0
      CamelotCore/CamelotCore.vcxproj
  4. 15 0
      CamelotCore/CamelotCore.vcxproj.filters
  5. 1 1
      CamelotCore/Include/CmDeferredRenderContext.h
  6. 24 0
      CamelotCore/Include/CmGpuBufferData.h
  7. 10 64
      CamelotCore/Include/CmGpuParamBlock.h
  8. 70 0
      CamelotCore/Include/CmGpuParamBlockBuffer.h
  9. 34 6
      CamelotCore/Include/CmGpuParams.h
  10. 2 2
      CamelotCore/Include/CmHardwareBufferManager.h
  11. 13 0
      CamelotCore/Include/CmIGpuBuffer.h
  12. 1 1
      CamelotCore/Include/CmMaterial.h
  13. 5 0
      CamelotCore/Include/CmPrerequisites.h
  14. 1 1
      CamelotCore/Include/CmRenderSystem.h
  15. 1 1
      CamelotCore/Source/CmDeferredRenderContext.cpp
  16. 41 0
      CamelotCore/Source/CmGpuBufferData.cpp
  17. 12 87
      CamelotCore/Source/CmGpuParamBlock.cpp
  18. 49 0
      CamelotCore/Source/CmGpuParamBlockBuffer.cpp
  19. 70 18
      CamelotCore/Source/CmGpuParams.cpp
  20. 4 3
      CamelotCore/Source/CmHardwareBufferManager.cpp
  21. 33 38
      CamelotCore/Source/CmMaterial.cpp
  22. 7 6
      CamelotCore/Source/CmPass.cpp
  23. 2 2
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  24. 6 6
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  25. 0 33
      CamelotD3D11RenderSystem/Include/CmD3D11GpuParamBlock.h
  26. 39 0
      CamelotD3D11RenderSystem/Include/CmD3D11GpuParamBlockBuffer.h
  27. 2 2
      CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h
  28. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h
  29. 16 9
      CamelotD3D11RenderSystem/Source/CmD3D11GpuParamBlockBuffer.cpp
  30. 4 4
      CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp
  31. 13 9
      CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp
  32. 2 2
      CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h
  33. 1 1
      CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h
  34. 4 4
      CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp
  35. 36 13
      CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp
  36. 2 2
      CamelotGLRenderer/CamelotGLRenderer.vcxproj
  37. 6 6
      CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters
  38. 0 34
      CamelotGLRenderer/Include/CmGLGpuParamBlock.h
  39. 39 0
      CamelotGLRenderer/Include/CmGLGpuParamBlockBuffer.h
  40. 2 2
      CamelotGLRenderer/Include/CmGLHardwareBufferManager.h
  41. 1 1
      CamelotGLRenderer/Include/CmGLRenderSystem.h
  42. 0 39
      CamelotGLRenderer/Source/CmGLGpuParamBlock.cpp
  43. 47 0
      CamelotGLRenderer/Source/CmGLGpuParamBlockBuffer.cpp
  44. 4 4
      CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp
  45. 30 15
      CamelotGLRenderer/Source/CmGLRenderSystem.cpp
  46. 47 4
      TODO.txt

+ 0 - 2
BansheeForwardRenderer/Source/BsForwardRenderer.cpp

@@ -33,8 +33,6 @@ namespace BansheeEngine
 
 	void ForwardRenderer::renderAll() 
 	{
-		
-
 		DeferredRenderContextPtr renderContext = gApplication().getPrimaryRenderContext();
 
 		const vector<HCamera>::type& allCameras = gSceneManager().getAllCameras();

+ 5 - 5
CamelotClient/CamelotClient.cpp

@@ -72,8 +72,8 @@ int CALLBACK WinMain(
 	HSceneObject testModelGO = SceneObject::create("TestMesh");
 	HRenderable testRenderable = testModelGO->addComponent<Renderable>();
 
-	HSceneObject testTextGO = SceneObject::create("TestText");
-	GameObjectHandle<TestTextSprite> textSprite = testTextGO->addComponent<TestTextSprite>();
+	//HSceneObject testTextGO = SceneObject::create("TestText");
+	//GameObjectHandle<TestTextSprite> textSprite = testTextGO->addComponent<TestTextSprite>();
 
 	HFont font;
 	
@@ -96,7 +96,7 @@ int CALLBACK WinMain(
 
 	windowFrameTex.waitUntilLoaded();
 
-	textSprite->init(camera, "Testing in a new row, does this work?", font, 12, windowFrameTex);
+	//textSprite->init(camera, "Testing in a new row, does this work?", font, 12, windowFrameTex);
 
 #if defined DX9
 	///////////////// HLSL 9 SHADERS //////////////////////////
@@ -286,13 +286,13 @@ int CALLBACK WinMain(
 	//// Set the new state for the flag
 	//_CrtSetDbgFlag( tmpFlag );
 	
-	//EditorWindow* newWindow = new EditorWindow("Test window", font, 12);
+	EditorWindow* newWindow = new EditorWindow("Test window", font, 12);
 
 	gBansheeApp().runMainLoop();
 
 	// Release everything before shutdown
 	
-	//delete newWindow;
+	delete newWindow;
 
 	//testMaterial->destroy();
 #ifdef DX11

+ 5 - 0
CamelotCore/CamelotCore.vcxproj

@@ -179,6 +179,8 @@
     <ClInclude Include="Include\CmGameObjectHandle.h" />
     <ClInclude Include="Include\CmGameObject.h" />
     <ClInclude Include="Include\CmGameObjectRTTI.h" />
+    <ClInclude Include="Include\CmGpuBufferData.h" />
+    <ClInclude Include="Include\CmGpuParamBlockBuffer.h" />
     <ClInclude Include="Include\CmSceneObjectRTTI.h" />
     <ClInclude Include="Include\CmMemAllocCategories.h" />
     <ClInclude Include="Include\CmApplication.h" />
@@ -279,6 +281,7 @@
     <ClInclude Include="Include\CmComponent.h" />
     <ClInclude Include="Include\CmShader.h" />
     <ClInclude Include="Include\CmBlendState.h" />
+    <ClInclude Include="Include\CmIGpuBuffer.h" />
     <ClInclude Include="Include\stdafx.h" />
     <ClInclude Include="Include\targetver.h" />
     <ClInclude Include="Include\CmVertexDeclarationRTTI.h" />
@@ -303,8 +306,10 @@
     <ClCompile Include="Source\CmFontImportOptions.cpp" />
     <ClCompile Include="Source\CmFontManager.cpp" />
     <ClCompile Include="Source\CmGpuBuffer.cpp" />
+    <ClCompile Include="Source\CmGpuBufferData.cpp" />
     <ClCompile Include="Source\CmGpuBufferView.cpp" />
     <ClCompile Include="Source\CmGpuParamBlock.cpp" />
+    <ClCompile Include="Source\CmGpuParamBlockBuffer.cpp" />
     <ClCompile Include="Source\CmGpuParams.cpp" />
     <ClCompile Include="Source\CmGpuProgInclude.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />

+ 15 - 0
CamelotCore/CamelotCore.vcxproj.filters

@@ -414,6 +414,15 @@
     <ClInclude Include="Include\CmGameObjectRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmIGpuBuffer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmGpuBufferData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmGpuParamBlockBuffer.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmApplication.cpp">
@@ -638,5 +647,11 @@
     <ClCompile Include="Source\CmGameObject.cpp">
       <Filter>Source Files\Scene</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmGpuBufferData.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmGpuParamBlockBuffer.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 1
CamelotCore/Include/CmDeferredRenderContext.h

@@ -76,7 +76,7 @@ namespace CamelotFramework
 		/** @copydoc RenderSystem::unbindGpuProgram() */
 		void unbindGpuProgram(GpuProgramType gptype);
 		/** @copydoc RenderSystem::bindGpuParams() */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
 
 		/** @copydoc RenderSystem::beginFrame() */
 		void beginFrame(void);

+ 24 - 0
CamelotCore/Include/CmGpuBufferData.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotFramework
+{
+	class CM_EXPORT GpuBufferData
+	{
+	public:
+		GpuBufferData();
+		~GpuBufferData();
+
+		UINT8* getData() const;
+
+	protected:
+		void initialize(UINT32 size);
+
+		void lock();
+		void unlock();
+
+		UINT8* mData;
+		bool mLocked;
+	};
+}

+ 10 - 64
CamelotCore/Include/CmGpuParamBlock.h

@@ -6,85 +6,31 @@
 
 namespace CamelotFramework
 {
-	/**
-	 * @brief	Represents an actual GPU buffer. 
-	 * 			Should only be accessed directly from render thread.
-	 */
-	class CM_EXPORT GpuParamBlockBuffer
+	class CM_EXPORT GpuParamBlock
 	{
 	public:
-		GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage);
-		virtual ~GpuParamBlockBuffer();
+		GpuParamBlock(UINT32 size);
+		GpuParamBlock(GpuParamBlock* otherBlock);
 
-		/**
-		 * @brief	Writes all of the data to the buffer.
-		 * 			Data size must be the same size as the buffer;
-		 */
-		virtual void writeAll(const void* data);
-
-		const UINT8* getDataPtr(UINT32 offset) const;
-		UINT32 getSize() const { return mSize; }
-
-	protected:
-		GpuParamBlockUsage mUsage;
-		UINT8* mData;
-		UINT32 mSize;
-	};
-
-	class CM_EXPORT GpuParamBlock : public CoreObject
-	{
-	public:
-		GpuParamBlock();
 		virtual ~GpuParamBlock();
 
-		void initialize(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage);
-
 		void write(UINT32 offset, const void* data, UINT32 size);
 		void zeroOut(UINT32 offset, UINT32 size);
 
 		/**
-		 * @brief	Returns a buffer that may be bound as a material parameter.
+		 * @brief	Uploads the current data to the specified buffer, and marks the block a non-dirty.
+		 * 			Should only be called from the render thread.
 		 */
-		const GpuParamBlockBuffer* getBindableBuffer() const { return mBuffer; }
+		void uploadToBuffer(GpuParamBlockBufferPtr buffer);
 
-		/**
-		 * @brief	Updates the internal buffer. You must call this if you want the buffer to be
-		 * 			up to date after making changes to it. Buffer won't be touched if there were no changes
-		 * 			so feel free to call this often.
-		 * 			
-		 * @note	This will only queue the buffer update on the render thread.
-		 */
-		void updateBuffer();
+		UINT32 getSize() const { return mSize; }
+		UINT8* getData() const { return mData; }
+		bool isDirty() const { return mDirty; }
 
-		static GpuParamBlockPtr create(const GpuParamBlockDesc& desc);
+		void setDirty() { mDirty = true; }
 	protected:
-		friend class HardwareBufferManager;
-
-		GpuParamBlockBuffer* mBuffer;
-		GpuParamBlockUsage mUsage;
-
 		UINT8* mData;
 		UINT32 mSize;
 		bool mDirty;
-
-		/**
-		 * @copydoc CoreGpuObject::initialize_internal.
-		 */
-		virtual void initialize_internal();
-
-		/**
-		 * @copydoc CoreGpuObject::destroy_internal.
-		 */
-		virtual void destroy_internal();
-
-		/**
-		 * @brief	Creates new GPU parameter buffer. Derived classes should
-		 * 			return their own specific buffer implementations.
-		 * 			
-		 * @note	Should only be called from the render thread.
-		 */
-		virtual GpuParamBlockBuffer* createBuffer() const;
-
-		void updateBuffer_internal(UINT8* data);
 	};
 }

+ 70 - 0
CamelotCore/Include/CmGpuParamBlockBuffer.h

@@ -0,0 +1,70 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmCommonEnums.h"
+#include "CmCoreObject.h"
+
+namespace CamelotFramework
+{
+	/**
+	 * @brief	Represents an actual GPU buffer. 
+	 * 			Should only be accessed directly from render thread.
+	 */
+	class CM_EXPORT GpuParamBlockBuffer : public CoreObject
+	{
+	public:
+		GpuParamBlockBuffer();
+		virtual ~GpuParamBlockBuffer();
+
+		void initialize(UINT32 size, GpuParamBlockUsage usage);
+
+		/**
+		 * @brief	Writes all of the data to the buffer.
+		 * 			Data size must be the same size as the buffer;
+		 */
+		virtual void writeData(const UINT8* data) = 0;
+
+		/**
+		 * @brief	Copies data from the internal buffer to a pre-allocated array. 
+		 * 			Be aware this generally isn't a very fast operation.
+		 *
+		 * @param [in,out]	data	Array where the data will be written to. Must be of
+		 * 							"getSize()" bytes.
+		 */
+		virtual void readData(UINT8* data) const = 0;
+
+		UINT32 getSize() const { return mSize; }
+
+	protected:
+		GpuParamBlockUsage mUsage;
+		UINT32 mSize;
+	};
+
+	class CM_EXPORT GenericGpuParamBlockBuffer : public GpuParamBlockBuffer
+	{
+	public:
+		/**
+		 * @brief	Writes all of the data to the buffer.
+		 * 			Data size must be the same size as the buffer;
+		 */
+		void writeData(const UINT8* data);
+
+		/**
+		 * @copydoc GpuParamBlockBuffer::readAll.
+		 */
+		void readData(UINT8* data) const;
+
+	protected:
+		UINT8* mData;
+
+		/**
+		 * @copydoc CoreGpuObject::initialize_internal.
+		 */
+		virtual void initialize_internal();
+
+		/**
+		 * @copydoc CoreGpuObject::destroy_internal.
+		 */
+		virtual void destroy_internal();
+	};
+}

+ 34 - 6
CamelotCore/Include/CmGpuParams.h

@@ -8,12 +8,13 @@ namespace CamelotFramework
 	{
 	public:
 		GpuParams(GpuParamDesc& paramDesc);
+		~GpuParams();
 
-		GpuParamBlockPtr getParamBlock(UINT32 slot) const;
-		GpuParamBlockPtr getParamBlock(const String& name) const;
+		GpuParamBlockBufferPtr getParamBlockBuffer(UINT32 slot) const;
+		GpuParamBlockBufferPtr getParamBlockBuffer(const String& name) const;
 
-		void setParamBlock(UINT32 slot, GpuParamBlockPtr paramBlock);
-		void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
+		void setParamBlockBuffer(UINT32 slot, GpuParamBlockBufferPtr paramBlockBuffer);
+		void setParamBlockBuffer(const String& name, GpuParamBlockBufferPtr paramBlockBuffer);
 
 		const GpuParamDesc& getParamDesc() const { return mParamDesc; }
 		UINT32 getDataParamSize(const String& name) const;
@@ -52,16 +53,43 @@ namespace CamelotFramework
 
 		void setTransposeMatrices(bool transpose) { mTransposeMatrices = transpose; }
 
-		void updateParamBuffers();
+		/**
+		 * @brief	Updates all used hardware parameter buffers. Should ONLY be called from render thread.
+		 */
+		void updateHardwareBuffers();
+
+		/**
+		 * @brief	Creates the copy of this object in a special way. Should only be called
+		 * 			internally by deferred render context when passing gpu params to the render thread.
+		 */
+		static BindableGpuParams createBindableCopy(GpuParamsPtr params);
 
+		/**
+		 * @brief	Needs to be called on any copy created with "createCopyForDeferred" before the object is deleted.
+		 */
+		static void releaseBindableCopy(BindableGpuParams& bindableParams);
 	private:
 		GpuParamDesc& mParamDesc;
 		bool mTransposeMatrices;
 
 		GpuParamDataDesc* getParamDesc(const String& name) const;
 
-		vector<GpuParamBlockPtr>::type mParamBlocks;
+		vector<GpuParamBlock*>::type mParamBlocks;
+		vector<GpuParamBlockBufferPtr>::type mParamBlockBuffers;
 		vector<HTexture>::type mTextures;
 		vector<HSamplerState>::type mSamplerStates;
 	};
+
+	class CM_EXPORT BindableGpuParams
+	{
+	public:
+		GpuParams& getParams() const { return *mParams; }
+
+	private:
+		friend class GpuParams;
+
+		BindableGpuParams(GpuParams* params);
+
+		GpuParams *mParams;
+	};
 }

+ 2 - 2
CamelotCore/Include/CmHardwareBufferManager.h

@@ -95,7 +95,7 @@ namespace CamelotFramework {
 		 *
 		 * @return	The new GPU parameter block.
 		 */
-		virtual GpuParamBlockPtr createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage = GPBU_STATIC);
+		virtual GpuParamBlockBufferPtr createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
 
 		/**
 		 * @brief	Creates a generic buffer that can be passed as a parameter to a shader.
@@ -119,7 +119,7 @@ namespace CamelotFramework {
 		virtual VertexDeclarationPtr createVertexDeclarationImpl();
 		virtual VertexBufferPtr createVertexBufferImpl(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false) = 0;
 		virtual IndexBufferPtr createIndexBufferImpl(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage) = 0;
-		virtual GpuParamBlockPtr createGpuParamBlockImpl() = 0;
+		virtual GpuParamBlockBufferPtr createGpuParamBlockBufferImpl() = 0;
 		virtual GpuBufferPtr createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferUsage usage, 
 			bool randomGpuWrite = false, bool useCounter = false) = 0;
 	};

+ 13 - 0
CamelotCore/Include/CmIGpuBuffer.h

@@ -0,0 +1,13 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotFramework
+{
+	class CM_EXPORT IGpuBuffer
+	{
+	public:
+		virtual void setData(GpuBufferDataPtr data) = 0;
+		virtual GpuBufferDataPtr getData() const = 0;
+	};
+}

+ 1 - 1
CamelotCore/Include/CmMaterial.h

@@ -78,7 +78,7 @@ namespace CamelotFramework
 		void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0);
 		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0);
 
-		void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
+		//void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
 
 		HTexture getTexture(const String& name) const;
 		HSamplerState getSamplerState(const String& name) const;

+ 5 - 0
CamelotCore/Include/CmPrerequisites.h

@@ -137,6 +137,7 @@ namespace CamelotFramework {
 	class RasterizerState;
 	class BlendState;
 	class GpuParamBlock;
+	class GpuParamBlockBuffer;
 	class GpuParams;
 	struct GpuParamDesc;
 	struct GpuParamDataDesc;
@@ -148,6 +149,8 @@ namespace CamelotFramework {
 	class ImportOptions;
 	struct FontData;
 	class GameObject;
+	class GpuBufferData;
+	class BindableGpuParams;
 	// Asset import
 	class SpecificImporter;
 	class Importer;
@@ -209,6 +212,7 @@ namespace CamelotFramework
 	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;
 	typedef std::shared_ptr<Viewport> ViewportPtr;
@@ -217,6 +221,7 @@ namespace CamelotFramework
 	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
 	typedef std::shared_ptr<Font> FontPtr;
 	typedef std::shared_ptr<InputHandler> InputHandlerPtr;
+	typedef std::shared_ptr<GpuBufferData> GpuBufferDataPtr;
 }
 
 /************************************************************************/

+ 1 - 1
CamelotCore/Include/CmRenderSystem.h

@@ -223,7 +223,7 @@ namespace CamelotFramework
 		@param gptype The type of program to bind the parameters to
 		@param params The parameters to bind
 		*/
-		virtual void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params) = 0;
+		virtual void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params) = 0;
 
 		/** Unbinds GpuPrograms of a given GpuProgramType.
 		@remarks

+ 1 - 1
CamelotCore/Source/CmDeferredRenderContext.cpp

@@ -110,7 +110,7 @@ namespace CamelotFramework
 		mCommandQueue->queue(boost::bind(&RenderSystem::unbindGpuProgram, mRenderSystem, gptype));
 	}
 
-	void DeferredRenderContext::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
+	void DeferredRenderContext::bindGpuParams(GpuProgramType gptype, BindableGpuParams& params)
 	{
 		mCommandQueue->queue(boost::bind(&RenderSystem::bindGpuParams, mRenderSystem, gptype, params));
 	}

+ 41 - 0
CamelotCore/Source/CmGpuBufferData.cpp

@@ -0,0 +1,41 @@
+#include "CmGpuBufferData.h"
+#include "CmException.h"
+
+namespace CamelotFramework
+{
+	GpuBufferData::GpuBufferData()
+		:mData(nullptr), mLocked(false)
+	{
+
+	}
+
+	GpuBufferData::~GpuBufferData()
+	{
+		if(mData != nullptr)
+			CM_DELETE_BYTES(mData, ScratchAlloc);
+	}
+
+	UINT8* GpuBufferData::getData() const
+	{
+		if(mLocked)
+			CM_EXCEPT(InternalErrorException, "You are not allowed to access buffer data when the buffer is locked.");
+
+		return mData;
+	}
+
+	void GpuBufferData::initialize(UINT32 size)
+	{
+		mData = CM_NEW_BYTES(size, ScratchAlloc);
+	}
+
+	void GpuBufferData::lock()
+	{
+		mLocked = true;
+	}
+
+	void GpuBufferData::unlock()
+	{
+		mLocked = false;
+	}
+
+}

+ 12 - 87
CamelotCore/Source/CmGpuParamBlock.cpp

@@ -1,44 +1,24 @@
 #include "CmGpuParamBlock.h"
 #include "CmGpuParamDesc.h"
+#include "CmGpuParamBlockBuffer.h"
 #include "CmHardwareBufferManager.h"
 #include "CmException.h"
 
 namespace CamelotFramework
 {
-	GpuParamBlockBuffer::GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage)
-		:mData(CM_NEW_BYTES(size, ScratchAlloc)), mSize(size), mUsage(usage)
+	GpuParamBlock::GpuParamBlock(UINT32 size)
+		:mDirty(true), mData(nullptr), mSize(size)
 	{
+		mData = CM_NEW_BYTES(mSize, ScratchAlloc);
 		memset(mData, 0, mSize);
 	}
 
-	GpuParamBlockBuffer::~GpuParamBlockBuffer()
-	{
-		if(mData != nullptr)
-			CM_DELETE_BYTES(mData, ScratchAlloc);
-	}
-
-	void GpuParamBlockBuffer::writeAll(const void* data)
-	{
-		memcpy(mData, data, mSize);
-	}
-
-	const UINT8* GpuParamBlockBuffer::getDataPtr(UINT32 offset) const
-	{
-#if CM_DEBUG_MODE
-		if(offset < 0 || offset >= mSize)
-		{
-			CM_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
-				"Available range: 0 .. " + toString(mSize) + ". " \
-				"Wanted range: " + toString(offset) + " .. " + toString(offset) + ".");
-		}
-#endif
-
-		return &mData[offset];
-	}
-
-	GpuParamBlock::GpuParamBlock()
-		:mDirty(true), mUsage(GPBU_DYNAMIC), mData(nullptr), mBuffer(nullptr)
+	GpuParamBlock::GpuParamBlock(GpuParamBlock* otherBlock)
 	{
+		mSize = otherBlock->mSize;
+		mData = CM_NEW_BYTES(mSize, ScratchAlloc);
+		write(0, otherBlock->getData(), otherBlock->getSize());
+		mDirty = otherBlock->mDirty;
 	}
 
 	GpuParamBlock::~GpuParamBlock()
@@ -47,37 +27,6 @@ namespace CamelotFramework
 			CM_DELETE_BYTES(mData, ScratchAlloc);
 	}
 
-	void GpuParamBlock::initialize(const GpuParamBlockDesc& desc, GpuParamBlockUsage usage)
-	{
-		mSize = desc.blockSize * sizeof(UINT32);
-		mData = CM_NEW_BYTES(mSize, ScratchAlloc);
-		memset(mData, 0, mSize);
-
-		mUsage = usage;
-
-		CoreObject::initialize();
-	}
-
-	void GpuParamBlock::initialize_internal()
-	{
-		mBuffer = createBuffer();
-
-		CoreObject::initialize_internal();
-	}
-
-	void GpuParamBlock::destroy_internal()
-	{
-		if(mBuffer != nullptr)
-			CM_DELETE(mBuffer, GpuParamBlockBuffer, PoolAlloc);
-
-		CoreObject::destroy_internal();
-	}
-
-	GpuParamBlockBuffer* GpuParamBlock::createBuffer() const
-	{
-		return CM_NEW(GpuParamBlockBuffer, PoolAlloc) GpuParamBlockBuffer(mSize, mUsage);
-	}
-
 	void GpuParamBlock::write(UINT32 offset, const void* data, UINT32 size)
 	{
 #if CM_DEBUG_MODE
@@ -110,33 +59,9 @@ namespace CamelotFramework
 		mDirty = true;
 	}
 
-	void GpuParamBlock::updateBuffer()
-	{
-		if(mDirty)
-		{
-			mDirty = false;
-
-			// Need to copy the data, as non-render threads might modify
-			// the data before render thread has a chance to process it
-			// TODO - Use an allocator
-			UINT8* dataCopy = CM_NEW_BYTES(mSize, ScratchAlloc);
-			memcpy(dataCopy, mData, mSize);
-
-			queueGpuCommand(getThisPtr(), boost::bind(&GpuParamBlock::updateBuffer_internal, this, dataCopy));
-		}
-	}
-
-	void GpuParamBlock::updateBuffer_internal(UINT8* data)
-	{
-		assert(mBuffer != nullptr);
-
-		mBuffer->writeAll(data);
-
-		CM_DELETE_BYTES(data, ScratchAlloc);
-	}
-
-	GpuParamBlockPtr GpuParamBlock::create(const GpuParamBlockDesc& desc)
+	void GpuParamBlock::uploadToBuffer(GpuParamBlockBufferPtr buffer)
 	{
-		return HardwareBufferManager::instance().createGpuParamBlock(desc);
+		buffer->writeData(mData);
+		mDirty = false;
 	}
 }

+ 49 - 0
CamelotCore/Source/CmGpuParamBlockBuffer.cpp

@@ -0,0 +1,49 @@
+#include "CmGpuParamBlockBuffer.h"
+
+namespace CamelotFramework
+{
+	GpuParamBlockBuffer::GpuParamBlockBuffer()
+		:mSize(0), mUsage(GPBU_DYNAMIC)
+	{
+
+	}
+
+	GpuParamBlockBuffer::~GpuParamBlockBuffer()
+	{
+
+	}
+
+	void GpuParamBlockBuffer::initialize(UINT32 size, GpuParamBlockUsage usage)
+	{
+		mSize = size;
+		mUsage = usage;
+
+		CoreObject::initialize();
+	}
+
+	void GenericGpuParamBlockBuffer::writeData(const UINT8* data)
+	{
+		memcpy(mData, data, mSize);
+	}
+
+	void GenericGpuParamBlockBuffer::readData(UINT8* data) const
+	{
+		memcpy(data, mData, mSize);
+	}
+
+	void GenericGpuParamBlockBuffer::initialize_internal()
+	{
+		mData = CM_NEW_BYTES(mSize, ScratchAlloc);
+		memset(mData, 0, mSize);
+
+		GpuParamBlockBuffer::initialize_internal();
+	}
+
+	void GenericGpuParamBlockBuffer::destroy_internal()
+	{
+		if(mData != nullptr)
+			CM_DELETE_BYTES(mData, ScratchAlloc);
+
+		GpuParamBlockBuffer::destroy_internal();
+	}
+}

+ 70 - 18
CamelotCore/Source/CmGpuParams.cpp

@@ -1,6 +1,7 @@
 #include "CmGpuParams.h"
 #include "CmGpuParamDesc.h"
 #include "CmGpuParamBlock.h"
+#include "CmGpuParamBlockBuffer.h"
 #include "CmVector2.h"
 #include "CmDebug.h"
 #include "CmException.h"
@@ -17,7 +18,8 @@ namespace CamelotFramework
 				numParamBlockSlots = iter->second.slot + 1;
 		}
 
-		mParamBlocks.resize(numParamBlockSlots);
+		mParamBlocks.resize(numParamBlockSlots, nullptr);
+		mParamBlockBuffers.resize(numParamBlockSlots);
 
 		UINT32 numTextureSlots = 0;
 		for(auto iter = mParamDesc.textures.begin(); iter != mParamDesc.textures.end(); ++iter)
@@ -38,7 +40,15 @@ namespace CamelotFramework
 		mSamplerStates.resize(numSamplerSlots);
 	}
 
-	GpuParamBlockPtr GpuParams::getParamBlock(UINT32 slot) const
+	GpuParams::~GpuParams()
+	{
+		for(auto& paramBlock : mParamBlocks)
+		{
+			CM_DELETE(paramBlock, GpuParamBlock, PoolAlloc);
+		}
+	}
+
+	GpuParamBlockBufferPtr GpuParams::getParamBlockBuffer(UINT32 slot) const
 	{
 		if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
 		{
@@ -46,10 +56,10 @@ namespace CamelotFramework
 				toString(mParamBlocks.size() - 1) + ". Requested: " + toString(slot));
 		}
 
-		return mParamBlocks[slot];
+		return mParamBlockBuffers[slot];
 	}
 
-	GpuParamBlockPtr GpuParams::getParamBlock(const String& name) const
+	GpuParamBlockBufferPtr GpuParams::getParamBlockBuffer(const String& name) const
 	{
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 
@@ -59,10 +69,10 @@ namespace CamelotFramework
 			return nullptr;
 		}
 
-		return mParamBlocks[iterFind->second.slot];
+		return mParamBlockBuffers[iterFind->second.slot];
 	}
 
-	void GpuParams::setParamBlock(UINT32 slot, GpuParamBlockPtr paramBlock)
+	void GpuParams::setParamBlockBuffer(UINT32 slot, GpuParamBlockBufferPtr paramBlockBuffer)
 	{
 		if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
 		{
@@ -70,10 +80,14 @@ namespace CamelotFramework
 				toString(mParamBlocks.size() - 1) + ". Requested: " + toString(slot));
 		}
 
-		mParamBlocks[slot] = paramBlock;
+		if(mParamBlocks[slot] != nullptr)
+			CM_DELETE(mParamBlocks[slot], GpuParamBlock, PoolAlloc);
+
+		mParamBlocks[slot] = CM_NEW(GpuParamBlock, PoolAlloc) GpuParamBlock(paramBlockBuffer->getSize());
+		mParamBlockBuffers[slot] = paramBlockBuffer;
 	}
 
-	void GpuParams::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
+	void GpuParams::setParamBlockBuffer(const String& name, GpuParamBlockBufferPtr paramBlockBuffer)
 	{
 		auto iterFind = mParamDesc.paramBlocks.find(name);
 
@@ -83,7 +97,11 @@ namespace CamelotFramework
 			return;
 		}
 
-		mParamBlocks[iterFind->second.slot] = paramBlock;
+		if(mParamBlocks[iterFind->second.slot] != nullptr)
+			CM_DELETE(mParamBlocks[iterFind->second.slot], GpuParamBlock, PoolAlloc);
+
+		mParamBlocks[iterFind->second.slot] = CM_NEW(GpuParamBlock, PoolAlloc) GpuParamBlock(paramBlockBuffer->getSize());
+		mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
 	}
 
 	UINT32 GpuParams::getDataParamSize(const String& name) const
@@ -211,7 +229,7 @@ namespace CamelotFramework
 				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
 		}
 
-		GpuParamBlockPtr paramBlock = mParamBlocks[desc->paramBlockSlot];
+		GpuParamBlock* paramBlock = mParamBlocks[desc->paramBlockSlot];
 
 		if(paramBlock == nullptr)
 		{
@@ -275,21 +293,55 @@ namespace CamelotFramework
 		return mSamplerStates[slot];
 	}
 
-	void GpuParams::updateParamBuffers()
+	GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const
+	{
+		auto paramIter = mParamDesc.params.find(name);
+		if(paramIter != mParamDesc.params.end())
+			return &paramIter->second;
+
+		return nullptr;
+	}
+
+	BindableGpuParams GpuParams::createBindableCopy(GpuParamsPtr params)
+	{
+		GpuParams* copy = CM_NEW(GpuParams, ScratchAlloc) GpuParams(params->mParamDesc);
+
+		copy->mTransposeMatrices = params->mTransposeMatrices;
+		copy->mSamplerStates = params->mSamplerStates;
+		copy->mTextures = params->mTextures;
+		copy->mParamBlockBuffers =params-> mParamBlockBuffers;
+
+		copy->mParamBlocks.clear();
+		for(auto& paramBlock : params->mParamBlocks)
+		{
+			GpuParamBlock* blockCopy = CM_NEW(GpuParamBlock, ScratchAlloc) GpuParamBlock(paramBlock);
+
+			copy->mParamBlocks.push_back(blockCopy);
+		}
+
+		return BindableGpuParams(copy);
+	}
+
+	void GpuParams::updateHardwareBuffers()
 	{
 		for(size_t i = 0; i < mParamBlocks.size(); i++)
 		{
-			if(mParamBlocks[i] != nullptr)
-				mParamBlocks[i]->updateBuffer();
+			if(mParamBlocks[i] != nullptr && mParamBlockBuffers[i] != nullptr)
+			{
+				if(mParamBlocks[i]->isDirty())
+					mParamBlocks[i]->uploadToBuffer(mParamBlockBuffers[i]);
+			}
 		}
 	}
 
-	GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const
+	void GpuParams::releaseBindableCopy(BindableGpuParams& bindableParams)
+	{
+		CM_DELETE(bindableParams.mParams, GpuParams, ScratchAlloc);
+	}
+
+	BindableGpuParams::BindableGpuParams(GpuParams* params)
+		:mParams(params)
 	{
-		auto paramIter = mParamDesc.params.find(name);
-		if(paramIter != mParamDesc.params.end())
-			return &paramIter->second;
 
-		return nullptr;
 	}
 }

+ 4 - 3
CamelotCore/Source/CmHardwareBufferManager.cpp

@@ -31,6 +31,7 @@ THE SOFTWARE.
 #include "CmIndexData.h"
 #include "CmGpuBuffer.h"
 #include "CmVertexDeclaration.h"
+#include "CmGpuParamBlockBuffer.h"
 
 namespace CamelotFramework {
     //-----------------------------------------------------------------------
@@ -71,11 +72,11 @@ namespace CamelotFramework {
 
 	}
 	//-----------------------------------------------------------------------
-	GpuParamBlockPtr HardwareBufferManager::createGpuParamBlock(const GpuParamBlockDesc& paramDesc, GpuParamBlockUsage usage)
+	GpuParamBlockBufferPtr HardwareBufferManager::createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage)
 	{
-		GpuParamBlockPtr paramBlockPtr = createGpuParamBlockImpl();
+		GpuParamBlockBufferPtr paramBlockPtr = createGpuParamBlockBufferImpl();
 		paramBlockPtr->setThisPtr(paramBlockPtr);
-		paramBlockPtr->initialize(paramDesc, usage);
+		paramBlockPtr->initialize(size, usage);
 
 		return paramBlockPtr;
 	}

+ 33 - 38
CamelotCore/Source/CmMaterial.cpp

@@ -112,7 +112,7 @@ namespace CamelotFramework
 
 			set<String>::type validShareableParamBlocks = determineValidShareableParamBlocks(allParamDescs);
 			map<String, String>::type paramToParamBlockMap = determineParameterToBlockMapping(allParamDescs);
-			map<String, GpuParamBlockPtr>::type paramBlocks;
+			map<String, GpuParamBlockBufferPtr>::type paramBlockBuffers;
 
 			// Create param blocks
 			const map<String, SHADER_PARAM_BLOCK_DESC>::type& shaderDesc = mShader->getParamBlocks();
@@ -140,11 +140,11 @@ namespace CamelotFramework
 					}
 				}
 
-				GpuParamBlockPtr newParamBlockBuffer;
+				GpuParamBlockBufferPtr newParamBlockBuffer;
 				if(!isShared)
-					newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlock(blockDesc, usage);
+					newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(blockDesc.blockSize * sizeof(UINT32), usage);
 
-				paramBlocks[*iter] = newParamBlockBuffer;
+				paramBlockBuffers[*iter] = newParamBlockBuffer;
 				mValidShareableParamBlocks.insert(*iter);
 			}
 
@@ -286,9 +286,9 @@ namespace CamelotFramework
 							const String& paramBlockName = *iterBlock;
 							if(paramPtr->hasParamBlock(paramBlockName))
 							{
-								GpuParamBlockPtr blockBuffer = paramBlocks[paramBlockName];
+								GpuParamBlockBufferPtr blockBuffer = paramBlockBuffers[paramBlockName];
 
-								paramPtr->setParamBlock(paramBlockName, blockBuffer);
+								paramPtr->setParamBlockBuffer(paramBlockName, blockBuffer);
 							}
 						}
 
@@ -298,8 +298,9 @@ namespace CamelotFramework
 						{
 							if(!iterBlockDesc->second.isShareable)
 							{
-								GpuParamBlockPtr newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlock(iterBlockDesc->second);
-								paramPtr->setParamBlock(iterBlockDesc->first, newParamBlockBuffer);
+								GpuParamBlockBufferPtr newParamBlockBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(iterBlockDesc->second.blockSize * sizeof(UINT32));
+
+								paramPtr->setParamBlockBuffer(iterBlockDesc->first, newParamBlockBuffer);
 							}
 						}
 					}
@@ -734,30 +735,30 @@ namespace CamelotFramework
 		savedValue[arrayIdx] = StructData(value, size);
 	}
 
-	void Material::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
-	{
-		auto iterFind = mValidShareableParamBlocks.find(name);
-		if(iterFind == mValidShareableParamBlocks.end())
-		{
-			LOGWRN("Material doesn't have a parameter block named " + name);
-			return;
-		}
-
-		for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
-		{
-			PassParametersPtr params = *iter;
-
-			for(UINT32 i = 0; i < params->getNumParams(); i++)
-			{
-				GpuParamsPtr& paramPtr = params->getParamByIdx(i);
-				if(paramPtr)
-				{
-					if(paramPtr->hasParamBlock(name))
-						paramPtr->setParam(name, paramBlock);
-				}
-			}
-		}
-	}
+	//void Material::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
+	//{
+	//	auto iterFind = mValidShareableParamBlocks.find(name);
+	//	if(iterFind == mValidShareableParamBlocks.end())
+	//	{
+	//		LOGWRN("Material doesn't have a parameter block named " + name);
+	//		return;
+	//	}
+
+	//	for(auto iter = mParametersPerPass.begin(); iter != mParametersPerPass.end(); ++iter)
+	//	{
+	//		PassParametersPtr params = *iter;
+
+	//		for(UINT32 i = 0; i < params->getNumParams(); i++)
+	//		{
+	//			GpuParamsPtr& paramPtr = params->getParamByIdx(i);
+	//			if(paramPtr)
+	//			{
+	//				if(paramPtr->hasParamBlock(name))
+	//					paramPtr->setParam(name, paramBlock);
+	//			}
+	//		}
+	//	}
+	//}
 
 	UINT32 Material::getNumPasses() const
 	{
@@ -781,12 +782,6 @@ namespace CamelotFramework
 
 		PassParametersPtr params = mParametersPerPass[passIdx];
 
-		for(UINT32 i = 0; i < params->getNumParams(); i++)
-		{
-			if(params->getParamByIdx(i) != nullptr)
-				params->getParamByIdx(i)->updateParamBuffers();
-		}
-
 		return params;
 	}
 

+ 7 - 6
CamelotCore/Source/CmPass.cpp

@@ -5,6 +5,7 @@
 #include "CmPassRTTI.h"
 #include "CmDeferredRenderContext.h"
 #include "CmMaterial.h"
+#include "CmGpuParams.h"
 #include "CmException.h"
 
 namespace CamelotFramework
@@ -166,27 +167,27 @@ namespace CamelotFramework
 	{
 		HGpuProgram vertProgram = getVertexProgram();
 		if(vertProgram)
-			renderContext->bindGpuParams(GPT_VERTEX_PROGRAM, params->mVertParams);
+			renderContext->bindGpuParams(GPT_VERTEX_PROGRAM, GpuParams::createBindableCopy(params->mVertParams));
 
 		HGpuProgram fragProgram = getFragmentProgram();
 		if(fragProgram)
-			renderContext->bindGpuParams(GPT_FRAGMENT_PROGRAM, params->mFragParams);
+			renderContext->bindGpuParams(GPT_FRAGMENT_PROGRAM, GpuParams::createBindableCopy(params->mFragParams));
 
 		HGpuProgram geomProgram = getGeometryProgram();
 		if(geomProgram)
-			renderContext->bindGpuParams(GPT_GEOMETRY_PROGRAM, params->mGeomParams);
+			renderContext->bindGpuParams(GPT_GEOMETRY_PROGRAM, GpuParams::createBindableCopy(params->mGeomParams));
 
 		HGpuProgram hullProgram = getHullProgram();
 		if(hullProgram)
-			renderContext->bindGpuParams(GPT_HULL_PROGRAM, params->mHullParams);
+			renderContext->bindGpuParams(GPT_HULL_PROGRAM, GpuParams::createBindableCopy(params->mHullParams));
 
 		HGpuProgram domainProgram = getDomainProgram();
 		if(domainProgram)
-			renderContext->bindGpuParams(GPT_DOMAIN_PROGRAM, params->mDomainParams);
+			renderContext->bindGpuParams(GPT_DOMAIN_PROGRAM, GpuParams::createBindableCopy(params->mDomainParams));
 
 		HGpuProgram computeProgram = getComputeProgram();
 		if(computeProgram)
-			renderContext->bindGpuParams(GPT_COMPUTE_PROGRAM, params->mComputeParams);
+			renderContext->bindGpuParams(GPT_COMPUTE_PROGRAM, GpuParams::createBindableCopy(params->mComputeParams));
 	}
 	//----------------------------------------------------------------------
 	RTTITypeBase* Pass::getRTTIStatic()

+ 2 - 2
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -168,7 +168,7 @@
     <ClInclude Include="Include\CmD3D11HLSLProgramRTTI.h" />
     <ClInclude Include="Include\CmD3D11Mappings.h" />
     <ClInclude Include="Include\CmD3D11MultiRenderTexture.h" />
-    <ClInclude Include="Include\CmD3D11GpuParamBlock.h" />
+    <ClInclude Include="Include\CmD3D11GpuParamBlockBuffer.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11TextureView.h" />
     <ClInclude Include="Include\CmD3D11VertexBuffer.h" />
@@ -194,7 +194,7 @@
     <ClCompile Include="Source\CmD3D11DriverList.cpp" />
     <ClCompile Include="Source\CmD3D11GpuBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11GpuBufferView.cpp" />
-    <ClCompile Include="Source\CmD3D11GpuParamBlock.cpp" />
+    <ClCompile Include="Source\CmD3D11GpuParamBlockBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp" />
     <ClCompile Include="Source\CmD3D11GpuProgramManager.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareBuffer.cpp" />

+ 6 - 6
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -105,9 +105,6 @@
     <ClInclude Include="Include\CmD3D11VertexBuffer.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmD3D11GpuParamBlock.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmD3D11InputLayoutManager.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -123,6 +120,9 @@
     <ClInclude Include="Include\CmD3D11TextureView.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11GpuParamBlockBuffer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -209,9 +209,6 @@
     <ClCompile Include="Source\CmD3D11Plugin.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmD3D11GpuParamBlock.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmD3D11InputLayoutManager.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -227,5 +224,8 @@
     <ClCompile Include="Source\CmD3D11TextureView.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11GpuParamBlockBuffer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 0 - 33
CamelotD3D11RenderSystem/Include/CmD3D11GpuParamBlock.h

@@ -1,33 +0,0 @@
-#pragma once
-
-#include "CmD3D11Prerequisites.h"
-#include "CmGpuParamBlock.h"
-
-namespace CamelotFramework
-{
-	class CM_D3D11_EXPORT D3D11GpuParamBlockBuffer : public GpuParamBlockBuffer
-	{
-	public:
-		D3D11GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage);
-		~D3D11GpuParamBlockBuffer();
-
-		/**
-		 * @copydoc CpuParamBlockBuffer::writeAll.
-		 */
-		void writeAll(const void* data);
-
-		ID3D11Buffer* getD3D11Buffer() const;
-
-	private:
-		D3D11HardwareBuffer* mBuffer;
-	};
-
-	class CM_D3D11_EXPORT D3D11GpuParamBlock : public GpuParamBlock
-	{
-	protected:
-		/**
-		 * @copydoc GpuParamBlock::createBuffer.
-		 */
-		GpuParamBlockBuffer* createBuffer() const;
-	};
-}

+ 39 - 0
CamelotD3D11RenderSystem/Include/CmD3D11GpuParamBlockBuffer.h

@@ -0,0 +1,39 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmGpuParamBlockBuffer.h"
+
+namespace CamelotFramework
+{
+	class CM_D3D11_EXPORT D3D11GpuParamBlockBuffer : public GpuParamBlockBuffer
+	{
+	public:
+		D3D11GpuParamBlockBuffer();
+
+		/**
+		 * @brief	Writes all of the data to the buffer.
+		 * 			Data size must be the same size as the buffer;
+		 */
+		void writeData(const UINT8* data);
+
+		/**
+		 * @copydoc GpuParamBlockBuffer::readAll.
+		 */
+		void readData(UINT8* data) const;
+
+		ID3D11Buffer* getD3D11Buffer() const;
+	protected:
+		/**
+		 * @copydoc CoreGpuObject::initialize_internal.
+		 */
+		virtual void initialize_internal();
+
+		/**
+		 * @copydoc CoreGpuObject::destroy_internal.
+		 */
+		virtual void destroy_internal();
+
+	private:
+		D3D11HardwareBuffer* mBuffer;
+	};
+}

+ 2 - 2
CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h

@@ -24,8 +24,8 @@ namespace CamelotFramework
 		 */
 		IndexBufferPtr createIndexBufferImpl(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
 
-		/** @copydoc HardwareBufferManager::createGpuParamBlock */
-		GpuParamBlockPtr createGpuParamBlockImpl();
+		/** @copydoc HardwareBufferManager::createGpuParamBlockBufferImpl */
+		GpuParamBlockBufferPtr createGpuParamBlockBufferImpl();
 
 		/**
 		 * @copydoc HardwareBufferManager::createGenericBufferImpl

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h

@@ -52,7 +52,7 @@ namespace CamelotFramework
 		/** @copydoc RenderSystem::unbindGpuProgram() */
 		void unbindGpuProgram(GpuProgramType gptype);
 		/** @copydoc RenderSystem::bindGpuParams() */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
 		
 		void setClipPlanesImpl(const PlaneList& clipPlanes);
 

+ 16 - 9
CamelotD3D11RenderSystem/Source/CmD3D11GpuParamBlock.cpp → CamelotD3D11RenderSystem/Source/CmD3D11GpuParamBlockBuffer.cpp

@@ -1,12 +1,17 @@
-#include "CmD3D11GpuParamBlock.h"
+#include "CmD3D11GpuParamBlockBuffer.h"
 #include "CmD3D11HardwareBuffer.h"
 #include "CmD3D11RenderSystem.h"
 #include "CmD3D11Device.h"
 
 namespace CamelotFramework
 {
-	D3D11GpuParamBlockBuffer::D3D11GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage)
-		:GpuParamBlockBuffer(size, usage), mBuffer(nullptr)
+	D3D11GpuParamBlockBuffer::D3D11GpuParamBlockBuffer()
+		:mBuffer(nullptr)
+	{
+
+	}
+
+	void D3D11GpuParamBlockBuffer::initialize_internal()
 	{
 		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
 		D3D11Device& device = d3d11rs->getPrimaryDevice();
@@ -17,12 +22,16 @@ namespace CamelotFramework
 			mBuffer = CM_NEW(D3D11HardwareBuffer, PoolAlloc) D3D11HardwareBuffer(D3D11HardwareBuffer::BT_CONSTANT, GBU_DYNAMIC, 1, mSize, device);
 		else
 			CM_EXCEPT(InternalErrorException, "Invalid gpu param block usage.");
+
+		GpuParamBlockBuffer::initialize_internal();
 	}
 
-	D3D11GpuParamBlockBuffer::~D3D11GpuParamBlockBuffer()
+	void D3D11GpuParamBlockBuffer::destroy_internal()
 	{
 		if(mBuffer != nullptr)
 			CM_DELETE(mBuffer, D3D11HardwareBuffer, PoolAlloc);
+
+		GpuParamBlockBuffer::destroy_internal();
 	}
 
 	ID3D11Buffer* D3D11GpuParamBlockBuffer::getD3D11Buffer() const
@@ -30,15 +39,13 @@ namespace CamelotFramework
 		return mBuffer->getD3DBuffer();
 	}
 
-	void D3D11GpuParamBlockBuffer::writeAll(const void* data)
+	void D3D11GpuParamBlockBuffer::writeData(const UINT8* data)
 	{
 		mBuffer->writeData(0, mSize, data, true);
-
-		GpuParamBlockBuffer::writeAll(data);
 	}
 
-	GpuParamBlockBuffer* D3D11GpuParamBlock::createBuffer() const
+	void D3D11GpuParamBlockBuffer::readData(UINT8* data) const
 	{
-		return CM_NEW(D3D11GpuParamBlockBuffer, PoolAlloc) D3D11GpuParamBlockBuffer(mSize, mUsage);
+		mBuffer->readData(0, mSize, data);
 	}
 }

+ 4 - 4
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp

@@ -2,7 +2,7 @@
 #include "CmD3D11VertexBuffer.h"
 #include "CmD3D11IndexBuffer.h"
 #include "CmD3D11GpuBuffer.h"
-#include "CmD3D11GpuParamBlock.h"
+#include "CmD3D11GpuParamBlockBuffer.h"
 #include "CmGpuParamDesc.h"
 
 namespace CamelotFramework
@@ -32,11 +32,11 @@ namespace CamelotFramework
 		return IndexBufferPtr(buffer, &CoreObject::_deleteDelayed<D3D11IndexBuffer, PoolAlloc>);
 	}
 
-	GpuParamBlockPtr D3D11HardwareBufferManager::createGpuParamBlockImpl()
+	GpuParamBlockBufferPtr D3D11HardwareBufferManager::createGpuParamBlockBufferImpl()
 	{
-		D3D11GpuParamBlock* paramBlock = CM_NEW(D3D11GpuParamBlock, PoolAlloc) D3D11GpuParamBlock();
+		D3D11GpuParamBlockBuffer* paramBlockBuffer = CM_NEW(D3D11GpuParamBlockBuffer, PoolAlloc) D3D11GpuParamBlockBuffer();
 
-		return GpuParamBlockPtr(paramBlock, &CoreObject::_deleteDelayed<D3D11GpuParamBlock, PoolAlloc>);
+		return GpuParamBlockBufferPtr(paramBlockBuffer, &CoreObject::_deleteDelayed<D3D11GpuParamBlockBuffer, PoolAlloc>);
 	}
 
 	GpuBufferPtr D3D11HardwareBufferManager::createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, 

+ 13 - 9
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -17,7 +17,7 @@
 #include "CmD3D11VertexBuffer.h"
 #include "CmD3D11IndexBuffer.h"
 #include "CmD3D11RenderStateManager.h"
-#include "CmD3D11GpuParamBlock.h"
+#include "CmD3D11GpuParamBlockBuffer.h"
 #include "CmD3D11InputLayoutManager.h"
 #include "CmD3D11HLSLProgram.h"
 #include "CmGpuParams.h"
@@ -457,15 +457,18 @@ namespace CamelotFramework
 		}
 	}
 
-	void D3D11RenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
+	void D3D11RenderSystem::bindGpuParams(GpuProgramType gptype, BindableGpuParams& bindableParams)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
-		const GpuParamDesc& paramDesc = params->getParamDesc();
+		GpuParams& params = bindableParams.getParams();
+		params.updateHardwareBuffers();
 
+		const GpuParamDesc& paramDesc = params.getParamDesc();
+		
 		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
-			HSamplerState& samplerState = params->getSamplerState(iter->second.slot);
+			HSamplerState& samplerState = params.getSamplerState(iter->second.slot);
 
 			if(samplerState == nullptr)
 				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault());
@@ -475,7 +478,7 @@ namespace CamelotFramework
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
 		{
-			HTexture texture = params->getTexture(iter->second.slot);
+			HTexture texture = params.getTexture(iter->second.slot);
 
 			if(!texture.isLoaded())
 				setTexture(gptype, iter->second.slot, false, nullptr);
@@ -489,12 +492,11 @@ namespace CamelotFramework
 
 		for(auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
 		{
-			GpuParamBlockPtr currentBlock = params->getParamBlock(iter->second.slot);
+			GpuParamBlockBufferPtr currentBlockBuffer = params.getParamBlockBuffer(iter->second.slot);
 
-			if(currentBlock != nullptr)
+			if(currentBlockBuffer != nullptr)
 			{
-				const GpuParamBlockBuffer* currentBlockBuffer = currentBlock->getBindableBuffer();
-				const D3D11GpuParamBlockBuffer* d3d11paramBlockBuffer = static_cast<const D3D11GpuParamBlockBuffer*>(currentBlockBuffer);
+				const D3D11GpuParamBlockBuffer* d3d11paramBlockBuffer = static_cast<const D3D11GpuParamBlockBuffer*>(currentBlockBuffer.get());
 				bufferArray[0] = d3d11paramBlockBuffer->getD3D11Buffer();
 			}
 			else
@@ -522,6 +524,8 @@ namespace CamelotFramework
 				break;
 			};
 		}
+
+		GpuParams::releaseBindableCopy(bindableParams);
 	}
 
 	void D3D11RenderSystem::draw(UINT32 vertexCount)

+ 2 - 2
CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h

@@ -54,8 +54,8 @@ namespace CamelotFramework {
 		 */
 		IndexBufferPtr createIndexBufferImpl(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
 
-		/** @copydoc HardwareBufferManager::createGpuParamBlock */
-		GpuParamBlockPtr createGpuParamBlockImpl();
+		/** @copydoc HardwareBufferManager::createGpuParamBlockBufferImpl */
+		GpuParamBlockBufferPtr createGpuParamBlockBufferImpl();
 
 		/**
 		 * @copydoc HardwareBufferManager::createGenericBufferImpl

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -81,7 +81,7 @@ namespace CamelotFramework
 		/**
 		 * @copydoc RenderSystem::bindGpuParams()
 		 */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
 
 		/**
 		 * @copydoc RenderSystem::setVertexBuffer()

+ 4 - 4
CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp

@@ -30,7 +30,7 @@ THE SOFTWARE.
 #include "CmD3D9IndexBuffer.h"
 #include "CmD3D9VertexDeclaration.h"
 #include "CmD3D9GpuBuffer.h"
-#include "CmGpuParamBlock.h"
+#include "CmGpuParamBlockBuffer.h"
 #include "CmException.h"
 
 namespace CamelotFramework 
@@ -60,10 +60,10 @@ namespace CamelotFramework
 		return IndexBufferPtr(buffer, &CoreObject::_deleteDelayed<D3D9IndexBuffer, PoolAlloc>);
     }
 	//-----------------------------------------------------------------------
-	GpuParamBlockPtr D3D9HardwareBufferManager::createGpuParamBlockImpl()
+	GpuParamBlockBufferPtr D3D9HardwareBufferManager::createGpuParamBlockBufferImpl()
 	{
-		GpuParamBlock* paramBlock = CM_NEW(GpuParamBlock, PoolAlloc) GpuParamBlock();
-		return GpuParamBlockPtr(paramBlock, &CoreObject::_deleteDelayed<GpuParamBlock, PoolAlloc>);
+		GpuParamBlockBuffer* paramBlockBuffer = CM_NEW(GenericGpuParamBlockBuffer, PoolAlloc) GenericGpuParamBlockBuffer();
+		return GpuParamBlockBufferPtr(paramBlockBuffer, &CoreObject::_deleteDelayed<GpuParamBlockBuffer, PoolAlloc>);
 	}
 	//-----------------------------------------------------------------------
 	GpuBufferPtr D3D9HardwareBufferManager::createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, 

+ 36 - 13
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -54,7 +54,7 @@ THE SOFTWARE.
 #include "CmDepthStencilState.h"
 #include "CmGpuParams.h"
 #include "CmGpuParamDesc.h"
-#include "CmGpuParamBlock.h"
+#include "CmGpuParamBlockBuffer.h"
 #include "CmDebug.h"
 
 #if CM_DEBUG_MODE
@@ -336,15 +336,17 @@ namespace CamelotFramework
 		RenderSystem::unbindGpuProgram(gptype);
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
+	void D3D9RenderSystem::bindGpuParams(GpuProgramType gptype, BindableGpuParams& bindableParams)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
-		const GpuParamDesc& paramDesc = params->getParamDesc();
+		GpuParams& params = bindableParams.getParams();
+		params.updateHardwareBuffers();
+		const GpuParamDesc& paramDesc = params.getParamDesc();
 
 		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
-			HSamplerState& samplerState = params->getSamplerState(iter->second.slot);
+			HSamplerState& samplerState = params.getSamplerState(iter->second.slot);
 
 			if(samplerState == nullptr)
 				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault());
@@ -354,7 +356,7 @@ namespace CamelotFramework
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
 		{
-			HTexture texture = params->getTexture(iter->second.slot);
+			HTexture texture = params.getTexture(iter->second.slot);
 
 			if(!texture.isLoaded())
 				setTexture(gptype, iter->second.slot, false, nullptr);
@@ -362,6 +364,26 @@ namespace CamelotFramework
 				setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
 		}
 
+		// Read all the buffer data so we can assign it. Not the most efficient way of accessing data
+		// but it is required in order to have standardized buffer interface.
+		std::unordered_map<UINT32, UINT8*> bufferData;
+
+		for(auto& curParam : paramDesc.params)
+		{
+			UINT32 paramBlockSlot = curParam.second.paramBlockSlot;
+			auto iterFind = bufferData.find(paramBlockSlot);
+
+			if(iterFind == bufferData.end())
+			{
+				GpuParamBlockBufferPtr paramBlock = params.getParamBlockBuffer(paramBlockSlot);
+
+				UINT8* data = CM_NEW_BYTES(paramBlock->getSize(), ScratchAlloc);
+				paramBlock->readData(data);
+
+				bufferData[paramBlockSlot] = data;
+			}
+		}
+
 		HRESULT hr;
 
 		switch(gptype)
@@ -372,10 +394,7 @@ namespace CamelotFramework
 				{
 					const GpuParamDataDesc& paramDesc = iter->second;
 
-					GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
-					const GpuParamBlockBuffer* currentBlockBuffer = paramBlock->getBindableBuffer();
-
-					const UINT8* ptrData = currentBlockBuffer->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
+					const UINT8* ptrData = bufferData[paramDesc.paramBlockSlot] + paramDesc.cpuMemOffset * sizeof(UINT32);
 
 					switch(paramDesc.type)
 					{
@@ -426,10 +445,7 @@ namespace CamelotFramework
 				{
 					const GpuParamDataDesc& paramDesc = iter->second;
 
-					GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
-					const GpuParamBlockBuffer* currentBlockBuffer = paramBlock->getBindableBuffer();
-
-					const UINT8* ptrData = currentBlockBuffer->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
+					const UINT8* ptrData = bufferData[paramDesc.paramBlockSlot] + paramDesc.cpuMemOffset * sizeof(UINT32);
 
 					switch(paramDesc.type)
 					{
@@ -475,6 +491,13 @@ namespace CamelotFramework
 			}
 			break;
 		};
+
+		for(auto& curBufferData : bufferData)
+		{
+			CM_DELETE_BYTES(curBufferData.second, ScratchAlloc);
+		}
+
+		GpuParams::releaseBindableCopy(bindableParams);
 	}
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& tex)

+ 2 - 2
CamelotGLRenderer/CamelotGLRenderer.vcxproj

@@ -154,7 +154,7 @@
     <ClInclude Include="Include\CmGLContext.h" />
     <ClInclude Include="Include\CmGLFrameBufferObject.h" />
     <ClInclude Include="Include\CmGLGpuBuffer.h" />
-    <ClInclude Include="Include\CmGLGpuParamBlock.h" />
+    <ClInclude Include="Include\CmGLGpuParamBlockBuffer.h" />
     <ClInclude Include="Include\CmGLGpuProgramManager.h" />
     <ClInclude Include="Include\CmGLHardwareBufferManager.h" />
     <ClInclude Include="Include\CmGLIndexBuffer.h" />
@@ -190,7 +190,7 @@
     <ClCompile Include="Source\CmGLContext.cpp" />
     <ClCompile Include="Source\CmGLFrameBufferObject.cpp" />
     <ClCompile Include="Source\CmGLGpuBuffer.cpp" />
-    <ClCompile Include="Source\CmGLGpuParamBlock.cpp" />
+    <ClCompile Include="Source\CmGLGpuParamBlockBuffer.cpp" />
     <ClCompile Include="Source\CmGLGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGLHardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmGLIndexBuffer.cpp" />

+ 6 - 6
CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters

@@ -99,9 +99,6 @@
     <ClInclude Include="Include\CmGLMultiRenderTexture.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmGLGpuParamBlock.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Source\GLSL\include\CmGLSLParamParser.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -123,6 +120,9 @@
     <ClInclude Include="Include\CmGLGpuBuffer.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmGLGpuParamBlockBuffer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\GLSL\src\CmGLSLExtSupport.cpp">
@@ -194,9 +194,6 @@
     <ClCompile Include="Source\CmGLMultiRenderTexture.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmGLGpuParamBlock.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\GLSL\src\CmGLSLProgramPipelineManager.cpp">
       <Filter>GLSL</Filter>
     </ClCompile>
@@ -215,5 +212,8 @@
     <ClCompile Include="Source\CmGLGpuBuffer.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmGLGpuParamBlockBuffer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 0 - 34
CamelotGLRenderer/Include/CmGLGpuParamBlock.h

@@ -1,34 +0,0 @@
-#pragma once
-
-#include "CmGLPrerequisites.h"
-#include "CmGpuParamBlock.h"
-#include "CmCommonEnums.h"
-
-namespace CamelotFramework
-{
-	class CM_RSGL_EXPORT GLGpuParamBlockBuffer : public GpuParamBlockBuffer
-	{
-	public:
-		GLGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage);
-		~GLGpuParamBlockBuffer();
-
-		/**
-		 * @copydoc CpuParamBlockBuffer::writeAll.
-		 */
-		void writeAll(const void* data);
-
-		GLuint getGLHandle() const { return mGLHandle; }
-
-	private:
-		GLuint mGLHandle;
-	};
-
-	class CM_RSGL_EXPORT GLGpuParamBlock : public GpuParamBlock
-	{
-	protected:
-		/**
-		 * @copydoc GpuParamBlock::createBuffer.
-		 */
-		GpuParamBlockBuffer* createBuffer() const;
-	};
-}

+ 39 - 0
CamelotGLRenderer/Include/CmGLGpuParamBlockBuffer.h

@@ -0,0 +1,39 @@
+#pragma once
+
+#include "CmGLPrerequisites.h"
+#include "CmGpuParamBlockBuffer.h"
+#include "CmCommonEnums.h"
+
+namespace CamelotFramework
+{
+	class CM_RSGL_EXPORT GLGpuParamBlockBuffer : public GpuParamBlockBuffer
+	{
+	public:
+		GLGpuParamBlockBuffer();
+
+		/**
+		 * @copydoc GpuParamBlockBuffer::writeAll.
+		 */
+		void writeData(const UINT8* data);
+
+		/**
+		 * @copydoc GpuParamBlockBuffer::readAll.
+		 */
+		void readData(UINT8* data) const;
+
+		GLuint getGLHandle() const { return mGLHandle; }
+	protected:
+		/**
+		 * @copydoc CoreGpuObject::initialize_internal.
+		 */
+		virtual void initialize_internal();
+
+		/**
+		 * @copydoc CoreGpuObject::destroy_internal.
+		 */
+		virtual void destroy_internal();
+
+	private:
+		GLuint mGLHandle;
+	};
+}

+ 2 - 2
CamelotGLRenderer/Include/CmGLHardwareBufferManager.h

@@ -85,8 +85,8 @@ namespace CamelotFramework {
             IndexBuffer::IndexType itype, UINT32 numIndexes, 
             GpuBufferUsage usage);
 
-		/** @copydoc HardwareBufferManager::createGpuParamBlockImpl */
-		GpuParamBlockPtr createGpuParamBlockImpl();
+		/** @copydoc HardwareBufferManager::createGpuParamBlockBufferImpl */
+		GpuParamBlockBufferPtr createGpuParamBlockBufferImpl();
 
 		/**
 		 * @copydoc HardwareBufferManager::createGenericBufferImpl

+ 1 - 1
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -129,7 +129,7 @@ namespace CamelotFramework {
 		/**
 		 * @copydoc RenderSystem::bindGpuParams()
 		 */
-		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
+		void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
 
 		/**
 		 * @copydoc RenderSystem::beginFrame()

+ 0 - 39
CamelotGLRenderer/Source/CmGLGpuParamBlock.cpp

@@ -1,39 +0,0 @@
-#include "CmGLGpuParamBlock.h"
-#include "CmException.h"
-
-namespace CamelotFramework
-{
-	GLGpuParamBlockBuffer::GLGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage)
-		:GpuParamBlockBuffer(size, usage)
-	{
-		glGenBuffers(1, &mGLHandle);
-		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
-		if(mUsage == GPBU_STATIC)
-			glBufferData(GL_UNIFORM_BUFFER, mSize, (GLvoid*)mData, GL_STATIC_DRAW);
-		else if(mUsage == GPBU_DYNAMIC)
-			glBufferData(GL_UNIFORM_BUFFER, mSize, (GLvoid*)mData, GL_DYNAMIC_DRAW);
-		else
-			CM_EXCEPT(InternalErrorException, "Invalid gpu param block usage.");
-
-		glBindBuffer(GL_UNIFORM_BUFFER, 0);
-	}
-
-	GLGpuParamBlockBuffer::~GLGpuParamBlockBuffer()
-	{
-		glDeleteBuffers(1, &mGLHandle);
-	}
-
-	void GLGpuParamBlockBuffer::writeAll(const void* data)
-	{
-		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
-		glBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, data);
-		glBindBuffer(GL_UNIFORM_BUFFER, 0);
-
-		GpuParamBlockBuffer::writeAll(data);
-	}
-
-	GpuParamBlockBuffer* GLGpuParamBlock::createBuffer() const
-	{
-		return CM_NEW(GLGpuParamBlockBuffer, PoolAlloc) GLGpuParamBlockBuffer(mSize, mUsage);
-	}
-}

+ 47 - 0
CamelotGLRenderer/Source/CmGLGpuParamBlockBuffer.cpp

@@ -0,0 +1,47 @@
+#include "CmGLGpuParamBlockBuffer.h"
+#include "CmException.h"
+
+namespace CamelotFramework
+{
+	GLGpuParamBlockBuffer::GLGpuParamBlockBuffer()
+		:mGLHandle(0)
+	{
+	}
+
+	void GLGpuParamBlockBuffer::initialize_internal()
+	{
+		glGenBuffers(1, &mGLHandle);
+		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
+		if(mUsage == GPBU_STATIC)
+			glBufferData(GL_UNIFORM_BUFFER, mSize, nullptr, GL_STATIC_DRAW);
+		else if(mUsage == GPBU_DYNAMIC)
+			glBufferData(GL_UNIFORM_BUFFER, mSize, nullptr, GL_DYNAMIC_DRAW);
+		else
+			CM_EXCEPT(InternalErrorException, "Invalid gpu param block usage.");
+
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+		GpuParamBlockBuffer::initialize_internal();
+	}
+
+	void GLGpuParamBlockBuffer::destroy_internal()
+	{
+		glDeleteBuffers(1, &mGLHandle);
+
+		GpuParamBlockBuffer::destroy_internal();
+	}
+
+	void GLGpuParamBlockBuffer::writeData(const UINT8* data)
+	{
+		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
+		glBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, data);
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+	}
+
+	void GLGpuParamBlockBuffer::readData(UINT8* data) const
+	{
+		glBindBuffer(GL_UNIFORM_BUFFER, mGLHandle);
+		glGetBufferSubData(GL_UNIFORM_BUFFER, 0 , mSize, (GLvoid*)data);
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+	}
+}

+ 4 - 4
CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp

@@ -30,7 +30,7 @@ THE SOFTWARE.
 #include "CmGLIndexBuffer.h"
 #include "CmGLGpuBuffer.h"
 #include "CmHardwareBuffer.h"
-#include "CmGLGpuParamBlock.h"
+#include "CmGLGpuParamBlockBuffer.h"
 #include "CmRenderSystem.h"
 #include "CmRenderSystemCapabilities.h"
 
@@ -96,10 +96,10 @@ namespace CamelotFramework {
 			&CoreObject::_deleteDelayed<GLIndexBuffer, PoolAlloc>);
     }
 	//---------------------------------------------------------------------
-	GpuParamBlockPtr GLHardwareBufferManager::createGpuParamBlockImpl()
+	GpuParamBlockBufferPtr GLHardwareBufferManager::createGpuParamBlockBufferImpl()
 	{
-		return GpuParamBlockPtr(CM_NEW(GLGpuParamBlock, PoolAlloc) GLGpuParamBlock(),
-			&CoreObject::_deleteDelayed<GLGpuParamBlock, PoolAlloc>);
+		return GpuParamBlockBufferPtr(CM_NEW(GLGpuParamBlockBuffer, PoolAlloc) GLGpuParamBlockBuffer(),
+			&CoreObject::_deleteDelayed<GLGpuParamBlockBuffer, PoolAlloc>);
 	}
 	//---------------------------------------------------------------------
 	GpuBufferPtr GLHardwareBufferManager::createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, 

+ 30 - 15
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -49,7 +49,7 @@ THE SOFTWARE.s
 #include "CmGLSLProgramPipelineManager.h"
 #include "CmRenderStateManager.h"
 #include "CmGpuParams.h"
-#include "CmGLGpuParamBlock.h"
+#include "CmGLGpuParamBlockBuffer.h"
 #include "CmDebug.h"
 
 #if CM_DEBUG_MODE
@@ -266,17 +266,19 @@ namespace CamelotFramework
 		RenderSystem::unbindGpuProgram(gptype);
 	}
 	//-----------------------------------------------------------------------------
-	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
+	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, BindableGpuParams& bindableParams)
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 
-		const GpuParamDesc& paramDesc = params->getParamDesc();
+		GpuParams& params = bindableParams.getParams();
+		params.updateHardwareBuffers();
+		const GpuParamDesc& paramDesc = params.getParamDesc();
 		GLSLGpuProgramPtr activeProgram = getActiveProgram(gptype);
 		GLuint glProgram = activeProgram->getGLSLProgram()->getGLHandle();
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
 		{
-			HTexture texture = params->getTexture(iter->second.slot);
+			HTexture texture = params.getTexture(iter->second.slot);
 
 			if(!texture.isLoaded())
 				setTexture(gptype, iter->second.slot, false, nullptr);
@@ -287,7 +289,7 @@ namespace CamelotFramework
 		UINT32 texUnit = 0;
 		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
-			HSamplerState& samplerState = params->getSamplerState(iter->second.slot);
+			HSamplerState& samplerState = params.getSamplerState(iter->second.slot);
 
 			if(samplerState == nullptr)
 				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault());
@@ -299,19 +301,28 @@ namespace CamelotFramework
 			texUnit++;
 		}
 
+		UINT8* uniformBufferData = nullptr;
+
 		UINT32 blockBinding = 0;
 		for(auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
 		{
-			if(iter->second.slot == 0)
+			GpuParamBlockBufferPtr paramBlockBuffer = params.getParamBlockBuffer(iter->second.slot);
+			if(paramBlockBuffer == nullptr)
 				continue;
 
-			GpuParamBlockPtr paramBlock = params->getParamBlock(iter->second.slot);
-			if(paramBlock == nullptr)
+			if(iter->second.slot == 0)
+			{
+				// 0 means uniforms are not in block, in which case we handle it specially
+				if(uniformBufferData == nullptr)
+				{
+					uniformBufferData = CM_NEW_BYTES(paramBlockBuffer->getSize(), ScratchAlloc);
+					paramBlockBuffer->readData(uniformBufferData);
+				}
+
 				continue;
+			}
 
-			GLGpuParamBlockPtr glParamBlock = std::static_pointer_cast<GLGpuParamBlock>(paramBlock);
-			const GpuParamBlockBuffer* paramBlockBuffer = glParamBlock->getBindableBuffer();
-			const GLGpuParamBlockBuffer* glParamBlockBuffer = static_cast<const GLGpuParamBlockBuffer*>(paramBlockBuffer);
+			const GLGpuParamBlockBuffer* glParamBlockBuffer = static_cast<const GLGpuParamBlockBuffer*>(paramBlockBuffer.get());
 
 			UINT32 globalBlockBinding = getGLUniformBlockBinding(gptype, blockBinding);
 			glUniformBlockBinding(glProgram, iter->second.slot - 1, globalBlockBinding);
@@ -324,13 +335,10 @@ namespace CamelotFramework
 		{
 			const GpuParamDataDesc& paramDesc = iter->second;
 
-			GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
-			const GpuParamBlockBuffer* paramBlockBuffer = paramBlock->getBindableBuffer();
-
 			if(paramDesc.paramBlockSlot != 0) // 0 means uniforms are not in a block
 				continue;
 
-			const UINT8* ptrData = paramBlockBuffer->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
+			const UINT8* ptrData = uniformBufferData + paramDesc.cpuMemOffset * sizeof(UINT32);
 
 			switch(paramDesc.type)
 			{
@@ -401,6 +409,13 @@ namespace CamelotFramework
 				break;
 			}
 		}
+
+		if(uniformBufferData != nullptr)
+		{
+			CM_DELETE_BYTES(uniformBufferData, ScratchAlloc);
+		}
+
+		GpuParams::releaseBindableCopy(bindableParams);
 	}
 	//-----------------------------------------------------------------------------
 	void GLRenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)

+ 47 - 4
TODO.txt

@@ -2,15 +2,58 @@
 
 ----------------------------------------------------------------------------------------------
 
-When loading WindowFrameTex manually, it doesn't get released properly
+<<<<<<<Resource update/read>>>>>>>>
+Make sure to update the actual buffer in bindGpuParams
+ - It needs to accept an Unique GpuParams ptr
+ - It needs to call releaseCopyForDeferred when it ends
+
+Material::setParamBlock probably doesn't work anymore (and is atm commented out)
+
+INSTEAD OF createCopyForDeferred create a new BindableGpuParams class which basically just wraps GpuParams, with the difference that it is accepted in render system, and normal GpuParams isn't. Also create a special deleter that automatically calls releaseCopyForDeferred so that it doesn't need to be called manually.
+ - unique_ptr doesn't seem to work for GpuParams so maybe have that class handle that as well.
+ - pass a reference instead? take care with bind so it doesn't store a copy (boost::ref)
+
+
+All data classes (MeshData, PixelData, etc) derive from GpuBufferData class. 
+ - It contains basically just raw bytes.
+ - It has lock/unlock methods (used mostly internally)
+ - Upon submitting GpuBufferData to updateResource it gets locked so user cannot change it anymore
+
+QUESTION: How to deal with GpuBufferData for MeshData?
+ - It updates two separate buffers
+
+QUESTION: How to implement readResource and have the user be able to accurately read the returned data via
+ MeshData/PixelData?
+
+Inherit all buffer classes (texture, mesh, GPUBlock) from IGpuBuffer interface
+
+DeferredRenderContext::updateResource(IGpuBuffer, GpuBufferData)
+AsyncOp DeferredRenderContext::readResource(IGpuBuffer)
+
+--------
+
+Methods to port:
+WRITE:
+ - setRawPixels
+ - setRawPixels_async
+ - setMeshData
+ - GpuParamBlock::updateBuffer
+ - RenderTarget::swapBuffers
+READ:
+ - getMeshData
+ - getRawPixels
+ - getRawPixels_async
+
+--------
+
+Start with just GpuParamBlock and then move to Mesh/Texture later
+
+
 
  - My test model is rendering back faces. I need to flip them.
   - Although more than likely I am loading the model incorrectly since it works in Unity?
   - I probably want to determine front faces based on normals
 
-invalid operation in GL. Most likely created by enabling a certain vertex attrib without disabling it when using another shader. 
-  - try just using text shader without mesh and see if that helps
-
 Immediate TODO:
  - Issue with rendering same object from multiple cameras:
    - Material parameters should be copied after being submitted to the render context