Explorar el Código

Started on GpuParam re-implementation

Marko Pintera hace 13 años
padre
commit
970391f0a6

+ 0 - 2
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h

@@ -72,8 +72,6 @@ namespace CamelotEngine
 		vector<D3D11_SIGNATURE_PARAMETER_DESC>::type mInputParameters;
 		vector<D3D11_SIGNATURE_PARAMETER_DESC>::type mInputParameters;
 		vector<D3D11_SIGNATURE_PARAMETER_DESC>::type mOutputParameters;
 		vector<D3D11_SIGNATURE_PARAMETER_DESC>::type mOutputParameters;
 
 
-		vector<HardwareConstantBufferPtr>::type mConstantBuffers;
-
 		/**
 		/**
 		 * @brief	Compiles the shader from source and generates the microcode.
 		 * @brief	Compiles the shader from source and generates the microcode.
 		 */
 		 */

+ 0 - 5
CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h

@@ -20,11 +20,6 @@ namespace CamelotEngine
 		 * @brief	Creates a hardware index buffer.
 		 * @brief	Creates a hardware index buffer.
 		 */
 		 */
 		HardwareIndexBufferPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage);
 		HardwareIndexBufferPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage);
-		
-		/**
-		 * @brief	Creates a hardware index buffer.
-		 */
-		HardwareConstantBufferPtr createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage);
 
 
 	protected:     
 	protected:     
 		/// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs
 		/// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs

+ 1 - 8
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp

@@ -80,7 +80,6 @@ namespace CamelotEngine
 		mShaderBuffers.clear();
 		mShaderBuffers.clear();
 		mInputParameters.clear();
 		mInputParameters.clear();
 		mOutputParameters.clear();
 		mOutputParameters.clear();
-		mConstantBuffers.clear();
 		mMicrocode.clear();
 		mMicrocode.clear();
 	}
 	}
 
 
@@ -452,13 +451,7 @@ namespace CamelotEngine
 
 
 	void D3D11HLSLProgram::createConstantBuffers()
 	void D3D11HLSLProgram::createConstantBuffers()
 	{
 	{
-		mConstantBuffers.clear();
-
-		for(auto shaderBufferIter = mShaderBuffers.begin(); shaderBufferIter != mShaderBuffers.end(); ++shaderBufferIter)
-		{
-			HardwareConstantBufferPtr constantBuffer = HardwareBufferManager::instance().createConstantBuffer(shaderBufferIter->desc.Size, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
-			mConstantBuffers.push_back(constantBuffer);
-		}
+		// TODO - Do I still need this?
 	}
 	}
 
 
 	/************************************************************************/
 	/************************************************************************/

+ 0 - 13
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp

@@ -43,19 +43,6 @@ namespace CamelotEngine
 		return HardwareIndexBufferPtr(idx);
 		return HardwareIndexBufferPtr(idx);
 	}
 	}
 
 
-	HardwareConstantBufferPtr 
-		D3D11HardwareBufferManagerBase::createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage)
-	{
-		assert (sizeBytes > 0);
-		D3D11HardwareConstantBuffer* cnstBuf = new D3D11HardwareConstantBuffer(mDevice, this, sizeBytes, usage, false);
-
-		{
-			mConstantBuffers.insert(cnstBuf);
-		}
-
-		return HardwareConstantBufferPtr(cnstBuf);
-	}	
-
 	VertexDeclarationPtr D3D11HardwareBufferManagerBase::createVertexDeclarationImpl(void)
 	VertexDeclarationPtr D3D11HardwareBufferManagerBase::createVertexDeclarationImpl(void)
 	{
 	{
 		return VertexDeclarationPtr(new D3D11VertexDeclaration());
 		return VertexDeclarationPtr(new D3D11VertexDeclaration());

+ 269 - 3
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -80,6 +80,272 @@ namespace CamelotEngine {
 
 
 
 
 	};
 	};
+
+	class D3D9HLSLParamParser
+	{
+	public:
+		D3D9HLSLParamParser(LPD3DXCONSTANTTABLE constTable)
+			:mpConstTable(constTable), mCurrentBufferSize(0)
+		{ }
+
+		GpuParamDesc buildParameterDescriptions();
+		void processParameter(GpuParamBlockDesc& blockDesc, D3DXHANDLE parent, String prefix, UINT32 index);
+		void populateParamMemberDesc(GpuParamMemberDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc);
+
+	private:
+		LPD3DXCONSTANTTABLE mpConstTable;
+		GpuParamDesc mParamDesc;
+		UINT32 mCurrentBufferSize;
+	};
+
+	GpuParamDesc D3D9HLSLParamParser::buildParameterDescriptions()
+	{
+		// Derive parameter names from const table
+		assert(mpConstTable && "Program not loaded!");
+
+		// Get contents of the constant table
+		D3DXCONSTANTTABLE_DESC desc;
+		HRESULT hr = mpConstTable->GetDesc(&desc);
+
+		if (FAILED(hr))
+			CM_EXCEPT(InternalErrorException, "Cannot retrieve constant descriptions from HLSL program.");
+		
+		// DX9 has no concept of parameter blocks so we just put all members in one global block
+		String name = "Globals";
+		mParamDesc.paramBlocks.insert(std::make_pair(name, GpuParamBlockDesc()));
+		GpuParamBlockDesc& blockDesc = mParamDesc.paramBlocks[name];
+		blockDesc.name = name;
+		blockDesc.slot = 0;
+
+		// Iterate over the constants
+		for (UINT32 i = 0; i < desc.Constants; ++i)
+		{
+			// Recursively descend through the structure levels
+			processParameter(blockDesc, NULL, "", i);
+		}
+
+		return mParamDesc;
+	}
+
+	void D3D9HLSLParamParser::processParameter(GpuParamBlockDesc& blockDesc, D3DXHANDLE parent, String prefix, UINT32 index)
+	{
+		D3DXHANDLE hConstant = mpConstTable->GetConstant(parent, index);
+
+		// Since D3D HLSL doesn't deal with naming of array and struct parameters
+		// automatically, we have to do it by hand
+
+		D3DXCONSTANT_DESC desc;
+		UINT32 numParams = 1;
+		HRESULT hr = mpConstTable->GetConstantDesc(hConstant, &desc, &numParams);
+		if (FAILED(hr))
+		{
+			CM_EXCEPT(InternalErrorException, "Cannot retrieve constant description from HLSL program.");
+		}
+
+		String paramName = desc.Name;
+		// trim the odd '$' which appears at the start of the names in HLSL
+		if (paramName.at(0) == '$')
+			paramName.erase(paramName.begin());
+
+		// Also trim the '[0]' suffix if it exists, we will add our own indexing later
+		if (StringUtil::endsWith(paramName, "[0]", false))
+			paramName.erase(paramName.size() - 3);
+
+		if (desc.Class == D3DXPC_STRUCT)
+		{
+			// work out a new prefix for nested members, if it's an array, we need an index
+			prefix = prefix + paramName + ".";
+			// Cascade into struct
+			for (UINT32 i = 0; i < desc.StructMembers; ++i)
+			{
+				processParameter(blockDesc, hConstant, prefix, i);
+			}
+		}
+		else
+		{
+			// Process params
+			if (desc.Type == D3DXPT_FLOAT || desc.Type == D3DXPT_INT || desc.Type == D3DXPT_BOOL)
+			{
+				GpuParamMemberDesc memberDesc;
+				memberDesc.gpuMemOffset = desc.RegisterIndex;
+				memberDesc.cpuMemOffset = mCurrentBufferSize;
+				memberDesc.paramBlockSlot = blockDesc.slot;
+				memberDesc.arraySize = 1;
+
+				String name = prefix + paramName;
+				memberDesc.name = name;
+
+				populateParamMemberDesc(memberDesc, desc);
+				mParamDesc.params.insert(std::make_pair(name, memberDesc));
+
+				mCurrentBufferSize += memberDesc.elementSize * memberDesc.arraySize;
+			}
+
+			if(desc.Type == D3DXPT_SAMPLER1D || desc.Type == D3DXPT_SAMPLER2D || desc.Type == D3DXPT_SAMPLER3D || desc.Type == D3DXPT_SAMPLERCUBE)
+			{
+				GpuParamSpecialDesc samplerDesc;
+				samplerDesc.name = paramName;
+				samplerDesc.slot = desc.RegisterIndex;
+
+				GpuParamSpecialDesc textureDesc;
+				textureDesc.name = paramName;
+				textureDesc.slot = desc.RegisterIndex;
+
+				switch(desc.Type)
+				{
+				case D3DXPT_SAMPLER1D:
+					samplerDesc.type = GST_SAMPLER1D;
+					textureDesc.type = GST_TEXTURE1D;
+					break;
+				case D3DXPT_SAMPLER2D:
+					samplerDesc.type = GST_SAMPLER2D;
+					textureDesc.type = GST_TEXTURE2D;
+					break;
+				case D3DXPT_SAMPLER3D:
+					samplerDesc.type = GST_SAMPLER3D;
+					textureDesc.type = GST_TEXTURE3D;
+					break;
+				case D3DXPT_SAMPLERCUBE:
+					samplerDesc.type = GST_SAMPLERCUBE;
+					textureDesc.type = GST_TEXTURECUBE;
+					break;
+				}
+
+				mParamDesc.samplers.insert(std::make_pair(paramName, samplerDesc));
+				mParamDesc.textures.insert(std::make_pair(paramName, textureDesc));
+			}
+		}
+	}
+
+	void D3D9HLSLParamParser::populateParamMemberDesc(GpuParamMemberDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc)
+	{
+		memberDesc.arraySize = d3dDesc.Elements;
+		switch(d3dDesc.Type)
+		{
+		case D3DXPT_INT:
+			switch(d3dDesc.Columns)
+			{
+			case 1:
+				memberDesc.type = GMT_INT1;
+				memberDesc.elementSize = 4;
+				break;
+			case 2:
+				memberDesc.type = GMT_INT2;
+				memberDesc.elementSize = 4;
+				break;
+			case 3:
+				memberDesc.type = GMT_INT3;
+				memberDesc.elementSize = 4;
+				break;
+			case 4:
+				memberDesc.type = GMT_INT4;
+				memberDesc.elementSize = 4;
+				break;
+			} // columns
+			break;
+		case D3DXPT_FLOAT:
+			switch(d3dDesc.Class)
+			{
+			case D3DXPC_MATRIX_COLUMNS:
+			case D3DXPC_MATRIX_ROWS:
+				{
+					int firstDim, secondDim;
+					firstDim = d3dDesc.RegisterCount / d3dDesc.Elements;
+
+					if (d3dDesc.Class == D3DXPC_MATRIX_ROWS)
+						secondDim = d3dDesc.Columns;
+					else
+						secondDim = d3dDesc.Rows;
+
+					switch(firstDim)
+					{
+					case 2:
+						switch(secondDim)
+						{
+						case 2:
+							memberDesc.type = GMT_MATRIX_2X2;
+							memberDesc.elementSize = 8; // HLSL always packs
+							break;
+						case 3:
+							memberDesc.type = GMT_MATRIX_2X3;
+							memberDesc.elementSize = 8; // HLSL always packs
+							break;
+						case 4:
+							memberDesc.type = GMT_MATRIX_2X4;
+							memberDesc.elementSize = 8; 
+							break;
+						} // columns
+						break;
+					case 3:
+						switch(secondDim)
+						{
+						case 2:
+							memberDesc.type = GMT_MATRIX_3X2;
+							memberDesc.elementSize = 12; // HLSL always packs
+							break;
+						case 3:
+							memberDesc.type = GMT_MATRIX_3X3;
+							memberDesc.elementSize = 12; // HLSL always packs
+							break;
+						case 4:
+							memberDesc.type = GMT_MATRIX_3X4;
+							memberDesc.elementSize = 12; 
+							break;
+						} // columns
+						break;
+					case 4:
+						switch(secondDim)
+						{
+						case 2:
+							memberDesc.type = GMT_MATRIX_4X2;
+							memberDesc.elementSize = 16; // HLSL always packs
+							break;
+						case 3:
+							memberDesc.type = GMT_MATRIX_4X3;
+							memberDesc.elementSize = 16; // HLSL always packs
+							break;
+						case 4:
+							memberDesc.type = GMT_MATRIX_4X4;
+							memberDesc.elementSize = 16; 
+							break;
+						} // secondDim
+						break;
+
+					} // firstDim
+				}
+				break;
+			case D3DXPC_SCALAR:
+			case D3DXPC_VECTOR:
+				switch(d3dDesc.Columns)
+				{
+				case 1:
+					memberDesc.type = GMT_FLOAT1;
+					memberDesc.elementSize = 4;
+					break;
+				case 2:
+					memberDesc.type = GMT_FLOAT2;
+					memberDesc.elementSize = 4;
+					break;
+				case 3:
+					memberDesc.type = GMT_FLOAT3;
+					memberDesc.elementSize = 4;
+					break;
+				case 4:
+					memberDesc.type = GMT_FLOAT4;
+					memberDesc.elementSize = 4;
+					break;
+				} // columns
+				break;
+			}
+		case D3DXPT_BOOL:
+			memberDesc.type = GMT_BOOL;
+			memberDesc.elementSize = 1;
+			break;
+		default:
+			break;
+		};
+	}
+
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void D3D9HLSLProgram::loadFromSource(void)
     void D3D9HLSLProgram::loadFromSource(void)
     {
     {
@@ -248,6 +514,8 @@ namespace CamelotEngine {
 
 
 		HighLevelGpuProgram::unload_internal();
 		HighLevelGpuProgram::unload_internal();
     }
     }
+	//-----------------------------------------------------------------------
+
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void D3D9HLSLProgram::buildConstantDefinitions() const
     void D3D9HLSLProgram::buildConstantDefinitions() const
     {
     {
@@ -269,15 +537,13 @@ namespace CamelotEngine {
             // Recursively descend through the structure levels
             // Recursively descend through the structure levels
             processParamElement(NULL, "", i);
             processParamElement(NULL, "", i);
         }
         }
-
-        
     }
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void D3D9HLSLProgram::processParamElement(D3DXHANDLE parent, String prefix, 
     void D3D9HLSLProgram::processParamElement(D3DXHANDLE parent, String prefix, 
         unsigned int index) const
         unsigned int index) const
     {
     {
         D3DXHANDLE hConstant = mpConstTable->GetConstant(parent, index);
         D3DXHANDLE hConstant = mpConstTable->GetConstant(parent, index);
-
+		
         // Since D3D HLSL doesn't deal with naming of array and struct parameters
         // Since D3D HLSL doesn't deal with naming of array and struct parameters
         // automatically, we have to do it by hand
         // automatically, we have to do it by hand
 
 

+ 5 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -192,6 +192,9 @@
     <ClInclude Include="Include\CmDepthStencilBuffer.h" />
     <ClInclude Include="Include\CmDepthStencilBuffer.h" />
     <ClInclude Include="Include\CmDepthStencilStateRTTI.h" />
     <ClInclude Include="Include\CmDepthStencilStateRTTI.h" />
     <ClInclude Include="Include\CmDepthStencilState.h" />
     <ClInclude Include="Include\CmDepthStencilState.h" />
+    <ClInclude Include="Include\CmGpuParamBlock.h" />
+    <ClInclude Include="Include\CmGpuParamDesc.h" />
+    <ClInclude Include="Include\CmGpuParams.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
@@ -276,6 +279,8 @@
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
     <ClCompile Include="Source\CmDeferredRenderContext.cpp" />
     <ClCompile Include="Source\CmDepthStencilBuffer.cpp" />
     <ClCompile Include="Source\CmDepthStencilBuffer.cpp" />
     <ClCompile Include="Source\CmDepthStencilState.cpp" />
     <ClCompile Include="Source\CmDepthStencilState.cpp" />
+    <ClCompile Include="Source\CmGpuParamBlock.cpp" />
+    <ClCompile Include="Source\CmGpuParams.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />

+ 15 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -350,6 +350,15 @@
     <ClInclude Include="Include\CmMultiRenderTexture.h">
     <ClInclude Include="Include\CmMultiRenderTexture.h">
       <Filter>Header Files\RenderSystem</Filter>
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmGpuParamDesc.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmGpuParams.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmGpuParamBlock.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -526,5 +535,11 @@
     <ClCompile Include="Source\CmMultiRenderTexture.cpp">
     <ClCompile Include="Source\CmMultiRenderTexture.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmGpuParams.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmGpuParamBlock.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 22 - 0
CamelotRenderer/Include/CmGpuParamBlock.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotEngine
+{
+	class GpuParamBlock
+	{
+	public:
+		GpuParamBlock(UINT32 size);
+		~GpuParamBlock();
+
+		void write(UINT32 offset, const void* data, UINT32 size);
+		void zeroOut(UINT32 offset, UINT32 size);
+
+		virtual void updateIfDirty();
+	private:
+		bool mDirty;
+		UINT8* mData;
+		UINT32 mSize;
+	};
+}

+ 78 - 0
CamelotRenderer/Include/CmGpuParamDesc.h

@@ -0,0 +1,78 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmGpuProgramParams.h" // TODO - Only here because I need some type definitions (GpuConstantType) - Remove later
+
+namespace CamelotEngine
+{
+	enum GpuMemberType
+	{
+		GMT_FLOAT1 = 1,
+		GMT_FLOAT2 = 2,
+		GMT_FLOAT3 = 3,
+		GMT_FLOAT4 = 4,
+		GMT_MATRIX_2X2 = 11,
+		GMT_MATRIX_2X3 = 12,
+		GMT_MATRIX_2X4 = 13,
+		GMT_MATRIX_3X2 = 14,
+		GMT_MATRIX_3X3 = 15,
+		GMT_MATRIX_3X4 = 16,
+		GMT_MATRIX_4X2 = 17,
+		GMT_MATRIX_4X3 = 18,
+		GMT_MATRIX_4X4 = 19,
+		GMT_INT1 = 20,
+		GMT_INT2 = 21,
+		GMT_INT3 = 22,
+		GMT_INT4 = 23,
+		GMT_BOOL = 24,
+		GMT_UNKNOWN = 99
+	};
+
+	enum GpuSpecialType
+	{
+		GST_SAMPLER1D = 1,
+		GST_SAMPLER2D = 2,
+		GST_SAMPLER3D = 3,
+		GST_SAMPLERCUBE = 4,
+		GST_TEXTURE1D = 11,
+		GST_TEXTURE2D = 12,
+		GST_TEXTURE3D = 13,
+		GST_TEXTURECUBE = 14
+	};
+
+	struct GpuParamMemberDesc
+	{
+		String name;
+		UINT32 elementSize; // Multiple of 4 bytes
+		UINT32 arraySize;
+		GpuMemberType type;
+
+		UINT32 paramBlockSlot;
+		UINT32 gpuMemOffset;
+		UINT32 cpuMemOffset;
+	};
+
+	struct GpuParamSpecialDesc
+	{
+		String name;
+		GpuSpecialType type;
+
+		UINT32 slot;
+	};
+
+	struct GpuParamBlockDesc
+	{
+		String name;
+		UINT32 slot;
+	};
+
+	struct GpuParamDesc
+	{
+		map<String, GpuParamBlockDesc>::type paramBlocks;
+		map<String, GpuParamMemberDesc>::type params;
+
+		map<String, GpuParamSpecialDesc>::type samplers;
+		map<String, GpuParamSpecialDesc>::type textures;
+		map<String, GpuParamSpecialDesc>::type buffers;
+	};
+}

+ 58 - 0
CamelotRenderer/Include/CmGpuParams.h

@@ -0,0 +1,58 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotEngine
+{
+	class GpuParams
+	{
+	public:
+		GpuParams(GpuParamDesc& paramDesc);
+
+		GpuParamBlockPtr getParamBlock(UINT32 index) const;
+		GpuParamBlockPtr getParamBlock(const String& name) const;
+
+		void setParamBlock(UINT32 index, GpuParamBlockPtr paramBlock);
+		void setParamBlock(const String& name, GpuParamBlockPtr paramBlock);
+
+		bool hasParam(const String& name) const;
+		bool hasTexture(const String& name) const;
+		bool hasSamplerState(const String& name) const;
+
+		void setParam(const String& name, float value, UINT32 arrayIndex = 0);
+		void setParam(const String& name, int value, UINT32 arrayIndex = 0);
+		void setParam(const String& name, bool value, UINT32 arrayIndex = 0);
+		void setParam(const String& name, const Vector4& vec, UINT32 arrayIndex = 0);
+		void setParam(const String& name, const Vector3& vec, UINT32 arrayIndex = 0);
+		void setParam(const String& name, const Vector2& vec, UINT32 arrayIndex = 0);
+		void setParam(const String& name, const Matrix4& mat, UINT32 arrayIndex = 0);
+		void setParam(const String& name, const Matrix3& mat, UINT32 arrayIndex = 0);
+		void setParam(const String& name, const Color& color, UINT32 arrayIndex = 0);
+
+		/**
+		 * @brief	Sets a parameter.
+		 *
+		 * @param	name	  	Name of the parameter.
+		 * @param	value	  	Parameter data.
+		 * @param	size	  	Size of the provided data. It can be exact size or lower than the exact size of the wanted field.
+		 * 						If it's lower unused bytes will be set to 0. 
+		 * @param	arrayIndex	(optional) zero-based index of the array.
+		 */
+		void setParam(const String& name, const void* value, UINT32 sizeBytes, UINT32 arrayIndex = 0);
+
+		void setTexture(const String& name, TextureHandle val);
+		void setSamplerState(const String& name, SamplerStatePtr val);
+
+		void setTransposeMatrices(bool transpose) { mTransposeMatrices = transpose; }
+
+	private:
+		GpuParamDesc& mParamDesc;
+		bool mTransposeMatrices;
+
+		GpuParamMemberDesc* getParamDesc(const String& name) const;
+
+		vector<GpuParamBlockPtr>::type mParamBlocks;
+		vector<TextureHandle>::type mTextures;
+		vector<SamplerStatePtr>::type mSamplerStates;
+	};
+}

+ 6 - 0
CamelotRenderer/Include/CmGpuProgram.h

@@ -34,6 +34,7 @@ THE SOFTWARE.
 #include "CmGpuProgramParams.h"
 #include "CmGpuProgramParams.h"
 #include "CmRenderSystemCapabilities.h"
 #include "CmRenderSystemCapabilities.h"
 #include "CmResource.h"
 #include "CmResource.h"
+#include "CmGpuParamDesc.h"
 
 
 namespace CamelotEngine {
 namespace CamelotEngine {
 
 
@@ -106,6 +107,11 @@ namespace CamelotEngine {
 		*/
 		*/
 		mutable GpuNamedConstantsPtr mConstantDefs;
 		mutable GpuNamedConstantsPtr mConstantDefs;
 
 
+		/**
+		 * @brief	Contains information about all parameters in a shader.
+		 */
+		GpuParamDesc mParametersDesc;
+
         /** Internal method returns whether required capabilities for this program is supported.
         /** Internal method returns whether required capabilities for this program is supported.
         */
         */
         bool isRequiredCapabilitiesSupported(void) const;
         bool isRequiredCapabilitiesSupported(void) const;

+ 0 - 16
CamelotRenderer/Include/CmHardwareBufferManager.h

@@ -67,7 +67,6 @@ namespace CamelotEngine {
 		typedef set<HardwareConstantBuffer*>::type ConstantBufferList;
 		typedef set<HardwareConstantBuffer*>::type ConstantBufferList;
         VertexBufferList mVertexBuffers;
         VertexBufferList mVertexBuffers;
         IndexBufferList mIndexBuffers;
         IndexBufferList mIndexBuffers;
-		ConstantBufferList mConstantBuffers;
 
 
 		typedef set<VertexBufferBinding*>::type VertexBufferBindingList;
 		typedef set<VertexBufferBinding*>::type VertexBufferBindingList;
 		VertexBufferBindingList mVertexBufferBindings;
 		VertexBufferBindingList mVertexBufferBindings;
@@ -124,13 +123,6 @@ namespace CamelotEngine {
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
 			HardwareBuffer::Usage usage) = 0;
 			HardwareBuffer::Usage usage) = 0;
 
 
-		/** Create a hardware constant buffer.
-		@param sizeBytes Size of the buffer, in bytes.
-        @param usage One or more members of the HardwareBuffer::Usage enumeration.
-        */
-		virtual HardwareConstantBufferPtr 
-            createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage) = 0;
-
         /** Creates a new vertex declaration. */
         /** Creates a new vertex declaration. */
         virtual VertexDeclarationPtr createVertexDeclaration(void);
         virtual VertexDeclarationPtr createVertexDeclaration(void);
 
 
@@ -143,8 +135,6 @@ namespace CamelotEngine {
 		void _notifyVertexBufferDestroyed(HardwareVertexBuffer* buf);
 		void _notifyVertexBufferDestroyed(HardwareVertexBuffer* buf);
 		/// Notification that a hardware index buffer has been destroyed
 		/// Notification that a hardware index buffer has been destroyed
 		void _notifyIndexBufferDestroyed(HardwareIndexBuffer* buf);
 		void _notifyIndexBufferDestroyed(HardwareIndexBuffer* buf);
-		/// Notification that a hardware constant buffer has been destroyed
-		void _notifyConstantBufferDestroyed(HardwareConstantBuffer* buf);
 	};
 	};
 
 
     /** Singleton wrapper for hardware buffer manager. */
     /** Singleton wrapper for hardware buffer manager. */
@@ -167,12 +157,6 @@ namespace CamelotEngine {
 			return mImpl->createIndexBuffer(itype, numIndexes, usage);
 			return mImpl->createIndexBuffer(itype, numIndexes, usage);
 		}
 		}
 
 
-		/** @copydoc HardwareBufferManagerInterface::createConstantBuffer */
-		HardwareConstantBufferPtr createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage)
-		{
-			return mImpl->createConstantBuffer(sizeBytes, usage);
-		}
-
 		/** @copydoc HardwareBufferManagerInterface::createVertexDeclaration */
 		/** @copydoc HardwareBufferManagerInterface::createVertexDeclaration */
 		virtual VertexDeclarationPtr createVertexDeclaration(void)
 		virtual VertexDeclarationPtr createVertexDeclaration(void)
 		{
 		{

+ 4 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -115,6 +115,9 @@ namespace CamelotEngine {
 	class RenderStateManager;
 	class RenderStateManager;
 	class RasterizerState;
 	class RasterizerState;
 	class BlendState;
 	class BlendState;
+	class GpuParamBlock;
+	struct GpuParamDesc;
+	struct GpuParamMemberDesc;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
 	class Importer;
 	class Importer;
@@ -171,6 +174,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
 	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
 	typedef std::shared_ptr<DepthStencilBuffer> DepthStencilBufferPtr;
 	typedef std::shared_ptr<DepthStencilBuffer> DepthStencilBufferPtr;
 	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
 	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
+	typedef std::shared_ptr<GpuParamBlock> GpuParamBlockPtr;
 }
 }
 
 
 // All type IDs used for RTTI
 // All type IDs used for RTTI

+ 50 - 0
CamelotRenderer/Source/CmGpuParamBlock.cpp

@@ -0,0 +1,50 @@
+#include "CmGpuParamBlock.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	GpuParamBlock::GpuParamBlock(UINT32 size)
+		:mSize(size), mDirty(true)
+	{
+		mData = new UINT8[size];
+		memset(mData, 0, size);
+	}
+
+	GpuParamBlock::~GpuParamBlock()
+	{
+		delete [] mData;
+	}
+
+	void GpuParamBlock::write(UINT32 offset, const void* data, UINT32 size)
+	{
+		if(offset < 0 || (offset + size) >= mSize)
+		{
+			CM_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+
+		memcpy(mData + offset, data, size);
+
+		mDirty = true;
+	}
+
+	void GpuParamBlock::zeroOut(UINT32 offset, UINT32 size)
+	{
+		if(offset < 0 || (offset + size) >= mSize)
+		{
+			CM_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \
+				"Available range: 0 .. " + toString(mSize) + ". " \
+				"Wanted range: " + toString(offset) + " .. " + toString(offset + size) + ".");
+		}
+
+		memset(mData + offset, 0, size);
+
+		mDirty = true;
+	}
+
+	void GpuParamBlock::updateIfDirty()
+	{
+		// Do nothing
+	}
+}

+ 252 - 0
CamelotRenderer/Source/CmGpuParams.cpp

@@ -0,0 +1,252 @@
+#include "CmGpuParams.h"
+#include "CmGpuParamDesc.h"
+#include "CmGpuParamBlock.h"
+#include "CmVector2.h"
+#include "CmDebug.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	GpuParams::GpuParams(GpuParamDesc& paramDesc)
+		:mParamDesc(paramDesc), mTransposeMatrices(false)
+	{
+		UINT32 maxParamBlockSlot = 0;
+		for(auto iter = mParamDesc.paramBlocks.begin(); iter != mParamDesc.paramBlocks.end(); ++iter)
+		{
+			if(iter->second.slot > maxParamBlockSlot)
+				maxParamBlockSlot = iter->second.slot;
+		}
+
+		mParamBlocks.resize(maxParamBlockSlot + 1);
+
+		UINT32 maxTextureSlot = 0;
+		for(auto iter = mParamDesc.textures.begin(); iter != mParamDesc.textures.end(); ++iter)
+		{
+			if(iter->second.slot > maxTextureSlot)
+				maxTextureSlot = iter->second.slot;
+		}
+
+		mTextures.resize(maxTextureSlot + 1);
+
+		UINT32 maxSamplerSlot = 0;
+		for(auto iter = mParamDesc.samplers.begin(); iter != mParamDesc.samplers.end(); ++iter)
+		{
+			if(iter->second.slot > maxSamplerSlot)
+				maxSamplerSlot = iter->second.slot;
+		}
+
+		mSamplerStates.resize(maxSamplerSlot + 1);
+
+		// TODO - Create ParamBlocks
+	}
+
+	GpuParamBlockPtr GpuParams::getParamBlock(UINT32 index) const
+	{
+		UINT32 idx = 0;
+		
+		for(auto iter = mParamBlocks.begin(); iter != mParamBlocks.end(); ++iter)
+		{
+			if(idx == index)
+				return *iter;
+
+			idx++;
+		}
+
+		return nullptr;
+	}
+
+	GpuParamBlockPtr GpuParams::getParamBlock(const String& name) const
+	{
+		auto iterFind = mParamDesc.paramBlocks.find(name);
+
+		if(iterFind == mParamDesc.paramBlocks.end())
+		{
+			LOGWRN("Cannot find parameter block with the name: " + name);
+			return nullptr;
+		}
+
+		return mParamBlocks[iterFind->second.slot];
+	}
+
+	void GpuParams::setParamBlock(UINT32 index, GpuParamBlockPtr paramBlock)
+	{
+		if(index < 0 || index >= (UINT32)mParamBlocks.size())
+		{
+			CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " + 
+				toString(mParamBlocks.size() - 1) + ". Requested: " + toString(index));
+		}
+
+		mParamBlocks[index] = paramBlock;
+	}
+
+	void GpuParams::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
+	{
+		auto iterFind = mParamDesc.paramBlocks.find(name);
+
+		if(iterFind == mParamDesc.paramBlocks.end())
+		{
+			LOGWRN("Cannot find parameter block with the name: " + name);
+			return;
+		}
+
+		mParamBlocks[iterFind->second.slot] = paramBlock;
+	}
+
+	bool GpuParams::hasParam(const String& name) const
+	{
+		return getParamDesc(name) != nullptr;
+	}
+
+	bool GpuParams::hasTexture(const String& name) const
+	{
+		auto paramIter = mParamDesc.textures.find(name);
+		if(paramIter != mParamDesc.textures.end())
+			return true;
+
+		return false;
+	}
+
+	bool GpuParams::hasSamplerState(const String& name) const
+	{
+		auto paramIter = mParamDesc.samplers.find(name);
+		if(paramIter != mParamDesc.samplers.end())
+			return true;
+
+		return false;
+	}
+
+	void GpuParams::setParam(const String& name, float value, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&value, 1 * sizeof(float), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, int value, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&value, 1 * sizeof(int), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, bool value, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&value, 1 * sizeof(bool), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, const Vector4& vec, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&vec, 4 * sizeof(float), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, const Vector3& vec, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&vec, 3 * sizeof(float), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, const Vector2& vec, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&vec, 2 * sizeof(float), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, const Matrix4& mat, UINT32 arrayIndex)
+	{
+		if (mTransposeMatrices)
+		{
+			Matrix4 transMat = mat.transpose();
+			setParam(name, (void*)&transMat, 16 * sizeof(float), arrayIndex);
+		}
+		else
+		{
+			setParam(name, (void*)&mat, 16 * sizeof(float), arrayIndex);
+		}
+	}
+
+	void GpuParams::setParam(const String& name, const Matrix3& mat, UINT32 arrayIndex)
+	{
+		if (mTransposeMatrices)
+		{
+			Matrix3 transMat = mat.transpose();
+			setParam(name, (void*)&transMat, 9 * sizeof(float), arrayIndex);
+		}
+		else
+		{
+			setParam(name, (void*)&mat, 9 * sizeof(float), arrayIndex);
+		}
+	}
+
+	void GpuParams::setParam(const String& name, const Color& color, UINT32 arrayIndex)
+	{
+		setParam(name, (void*)&color, 4 * sizeof(float), arrayIndex);
+	}
+
+	void GpuParams::setParam(const String& name, const void* value, UINT32 sizeBytes, UINT32 arrayIndex)
+	{
+		GpuParamMemberDesc* desc = getParamDesc(name);
+
+		if(desc == nullptr)
+		{
+			LOGWRN("Cannot find parameter with the name '" + name + "'");
+			return;
+		}
+
+		if(arrayIndex >= desc->arraySize)
+		{
+			CM_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
+				toString(desc->arraySize) + ". Requested size: " + toString(arrayIndex));
+		}
+
+		UINT32 elementSizeBytes = desc->elementSize * sizeof(UINT32);
+		if(sizeBytes > elementSizeBytes)
+		{
+			CM_EXCEPT(InvalidParametersException, "Provided element size larger than maximum element size. Maximum size: " + 
+				toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
+		}
+
+		GpuParamBlockPtr paramBlock = mParamBlocks[desc->paramBlockSlot];
+
+		if(paramBlock == nullptr)
+		{
+			LOGWRN("Parameter exists but there is no ParamBlock set.");
+			return;
+		}
+
+		paramBlock->write((desc->cpuMemOffset + arrayIndex * desc->elementSize) * sizeof(UINT32), value, sizeBytes);
+
+		// Set unused bytes to 0
+		if(sizeBytes < elementSizeBytes)
+		{
+			UINT32 diffSize = elementSizeBytes - sizeBytes;
+			paramBlock->zeroOut((desc->cpuMemOffset + arrayIndex * desc->elementSize + sizeBytes)  * sizeof(UINT32), diffSize);
+		}
+	}
+
+	void GpuParams::setTexture(const String& name, TextureHandle val)
+	{
+		auto paramIter = mParamDesc.textures.find(name);
+		if(paramIter == mParamDesc.textures.end())
+		{
+			LOGWRN("Texture with the name '" + name + "' doesn't exist.");
+			return;
+		}
+
+		mTextures[paramIter->second.slot] = val;
+	}
+
+	void GpuParams::setSamplerState(const String& name, SamplerStatePtr val)
+	{
+		auto paramIter = mParamDesc.samplers.find(name);
+		if(paramIter == mParamDesc.samplers.end())
+		{
+			LOGWRN("Sampler with the name '" + name + "' doesn't exist.");
+			return;
+		}
+
+		mSamplerStates[paramIter->second.slot] = val;
+	}
+
+	GpuParamMemberDesc* GpuParams::getParamDesc(const String& name) const
+	{
+		auto paramIter = mParamDesc.params.find(name);
+		if(paramIter != mParamDesc.params.end())
+			return &paramIter->second;
+
+		return nullptr;
+	}
+}

+ 1 - 1
CamelotRenderer/Source/CmGpuProgramParams.cpp

@@ -358,7 +358,7 @@ namespace CamelotEngine
 		// remember, raw content access uses raw float count rather than float4
 		// remember, raw content access uses raw float count rather than float4
 		if (mTransposeMatrices)
 		if (mTransposeMatrices)
 		{
 		{
-			Matrix3 t = m.Transpose();
+			Matrix3 t = m.transpose();
 			_writeRawConstants(physicalIndex, t[0], elementCount>9?9:elementCount);
 			_writeRawConstants(physicalIndex, t[0], elementCount>9?9:elementCount);
 		}
 		}
 		else
 		else

+ 0 - 10
CamelotRenderer/Source/CmHardwareBufferManager.cpp

@@ -54,7 +54,6 @@ namespace CamelotEngine {
         // unnecessary work, and we'll destroy everything here.
         // unnecessary work, and we'll destroy everything here.
 		mVertexBuffers.clear();
 		mVertexBuffers.clear();
 		mIndexBuffers.clear();
 		mIndexBuffers.clear();
-		mConstantBuffers.clear();
 
 
         // Destroy everything
         // Destroy everything
         destroyAllBindings();
         destroyAllBindings();
@@ -125,13 +124,4 @@ namespace CamelotEngine {
 			mIndexBuffers.erase(i);
 			mIndexBuffers.erase(i);
 		}
 		}
 	}
 	}
-	//-----------------------------------------------------------------------
-	void HardwareBufferManagerBase::_notifyConstantBufferDestroyed(HardwareConstantBuffer* buf)
-	{
-		ConstantBufferList::iterator i = mConstantBuffers.find(buf);
-		if (i != mConstantBuffers.end())
-		{
-			mConstantBuffers.erase(i);
-		}
-	}
 }
 }

+ 1 - 4
CamelotRenderer/Source/CmHardwareConstantBuffer.cpp

@@ -12,9 +12,6 @@ namespace CamelotEngine
 
 
 	HardwareConstantBuffer::~HardwareConstantBuffer()
 	HardwareConstantBuffer::~HardwareConstantBuffer()
 	{
 	{
-		if (mMgr)
-		{
-			mMgr->_notifyConstantBufferDestroyed(this);
-		}
+
 	}
 	}
 }
 }

+ 32 - 0
CamelotRenderer/TODO.txt

@@ -17,6 +17,38 @@
 
 
 
 
 /////
 /////
+-----------GpuProgramParameters/Pass/Material REFACTOR------------------------------
+
+Material remains a simple structure you use for easily setting all and every type of parameters for every stage.
+ - Each instantiation of Material creates its own unique constant buffers
+  - Attempt to detect duplicates on initialization
+ - Set/GetConstantBuffer allows you to switch out and share constant buffers
+
+GpuParamDesc
+ - Contains a list of all constant buffers with their parameters (param name, type, size, slot, etc.)
+ - Also a list of all textures/buffers/samplers
+ - Each created GpuProgram contains one of these
+
+HardwareBufferManager::createConstantBuffer(GpuParamDesc)
+ - Creates a constant buffer according to the specifications
+
+Pass
+ - Constant buffers are stored on a pass
+ - Supports previously mentioned Set/GetConstantBuffer
+   - When setting check GpuParamDesc of the shader to see if it matches
+ - Also holds a list of Textures/SamplerStates/Buffers
+   - Doesn't make sense to store it in ConstantBuffer since it would just be one per buffer
+
+Possibly keep GpuProgramParams class so it unifies access to ConstantBuffer and Textures/SamplerStates/Buffers?
+
+RenderSystem::bindGpuProgramParameters (maybe rename to something nicer?)
+ - It retrieves Constant buffer from Pass, converts it to a platform specific version and sets the needed parameters
+
+
+Port OpenGL so it uses Uniform buffers
+
+---------------------------------------------------
+
 RenderSystem::setTexture(STAGE, UINT32 slot, Texture)
 RenderSystem::setTexture(STAGE, UINT32 slot, Texture)
 RenderSystem::setBuffer(STAGE, UINT32 slot, Buffer)
 RenderSystem::setBuffer(STAGE, UINT32 slot, Buffer)
 RenderSystem::setSampler(STAGE, UINT32 slot, Sampler)
 RenderSystem::setSampler(STAGE, UINT32 slot, Sampler)

+ 1 - 1
CamelotUtility/Include/CmMatrix3.h

@@ -156,7 +156,7 @@ namespace CamelotEngine
         CM_UTILITY_EXPORT friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix);
         CM_UTILITY_EXPORT friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix);
 
 
         // utilities
         // utilities
-        Matrix3 Transpose () const;
+        Matrix3 transpose () const;
         bool Inverse (Matrix3& rkInverse, float fTolerance = 1e-06) const;
         bool Inverse (Matrix3& rkInverse, float fTolerance = 1e-06) const;
         Matrix3 Inverse (float fTolerance = 1e-06) const;
         Matrix3 Inverse (float fTolerance = 1e-06) const;
         float Determinant () const;
         float Determinant () const;

+ 1 - 1
CamelotUtility/Source/CmMath.cpp

@@ -951,7 +951,7 @@ namespace CamelotEngine
 		orientation.ToRotationMatrix(rot);
 		orientation.ToRotationMatrix(rot);
 
 
 		// Make the translation relative to new axes
 		// Make the translation relative to new axes
-		Matrix3 rotT = rot.Transpose();
+		Matrix3 rotT = rot.transpose();
 		Vector3 trans = -rotT * position;
 		Vector3 trans = -rotT * position;
 
 
 		// Make final matrix
 		// Make final matrix

+ 1 - 1
CamelotUtility/Source/CmMatrix3.cpp

@@ -182,7 +182,7 @@ namespace CamelotEngine
         return kProd;
         return kProd;
     }
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    Matrix3 Matrix3::Transpose () const
+    Matrix3 Matrix3::transpose () const
     {
     {
         Matrix3 kTranspose;
         Matrix3 kTranspose;
         for (size_t iRow = 0; iRow < 3; iRow++)
         for (size_t iRow = 0; iRow < 3; iRow++)