Pārlūkot izejas kodu

Added DX11 HardwareBufferManager & VertexDeclaration
Made indexes 32bit

Marko Pintera 13 gadi atpakaļ
vecāks
revīzija
6156f0c7a1
25 mainītis faili ar 592 papildinājumiem un 104 dzēšanām
  1. 4 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj
  2. 12 0
      CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters
  3. 15 8
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h
  4. 50 0
      CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h
  5. 1 1
      CamelotD3D11RenderSystem/Include/CmD3D11HardwareVertexBuffer.h
  6. 2 0
      CamelotD3D11RenderSystem/Include/CmD3D11Prerequisites.h
  7. 61 0
      CamelotD3D11RenderSystem/Include/CmD3D11VertexDeclaration.h
  8. 63 38
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp
  9. 68 0
      CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp
  10. 2 2
      CamelotD3D11RenderSystem/Source/CmD3D11HardwareVertexBuffer.cpp
  11. 137 0
      CamelotD3D11RenderSystem/Source/CmD3D11VertexDeclaration.cpp
  12. 15 3
      CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h
  13. 8 3
      CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp
  14. 14 3
      CamelotGLRenderer/Include/CmGLDefaultHardwareBufferManager.h
  15. 15 3
      CamelotGLRenderer/Include/CmGLHardwareBufferManager.h
  16. 6 1
      CamelotGLRenderer/Source/CmGLDefaultHardwareBufferManager.cpp
  17. 6 3
      CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp
  18. 1 0
      CamelotRenderer.sln
  19. 30 3
      CamelotRenderer/Include/CmDefaultHardwareBufferManager.h
  20. 18 23
      CamelotRenderer/Include/CmHardwareBufferManager.h
  21. 1 0
      CamelotRenderer/Include/CmPrerequisites.h
  22. 57 1
      CamelotRenderer/Source/CmDefaultHardwareBufferManager.cpp
  23. 0 9
      CamelotRenderer/Source/CmHardwareBufferManager.cpp
  24. 3 3
      CamelotRenderer/Source/CmMesh.cpp
  25. 3 0
      CamelotRenderer/TODO.txt

+ 4 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj

@@ -146,6 +146,7 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Include\CmD3D11HardwareBufferManager.h" />
     <ClInclude Include="Include\CmD3D11HardwareConstantBuffer.h" />
     <ClInclude Include="Include\CmD3D11HardwareConstantBuffer.h" />
     <ClInclude Include="Include\CmD3D11Device.h" />
     <ClInclude Include="Include\CmD3D11Device.h" />
     <ClInclude Include="Include\CmD3D11Driver.h" />
     <ClInclude Include="Include\CmD3D11Driver.h" />
@@ -158,6 +159,7 @@
     <ClInclude Include="Include\CmD3D11Mappings.h" />
     <ClInclude Include="Include\CmD3D11Mappings.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11Prerequisites.h" />
     <ClInclude Include="Include\CmD3D11HardwareVertexBuffer.h" />
     <ClInclude Include="Include\CmD3D11HardwareVertexBuffer.h" />
+    <ClInclude Include="Include\CmD3D11VertexDeclaration.h" />
     <ClInclude Include="Include\CmD3D11VideoMode.h" />
     <ClInclude Include="Include\CmD3D11VideoMode.h" />
     <ClInclude Include="Include\CmD3D11VideoModeList.h" />
     <ClInclude Include="Include\CmD3D11VideoModeList.h" />
   </ItemGroup>
   </ItemGroup>
@@ -168,11 +170,13 @@
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp" />
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp" />
     <ClCompile Include="Source\CmD3D11GpuProgramManager.cpp" />
     <ClCompile Include="Source\CmD3D11GpuProgramManager.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareBuffer.cpp" />
+    <ClCompile Include="Source\CmD3D11HardwareBufferManager.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareConstantBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareConstantBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HLSLProgram.cpp" />
     <ClCompile Include="Source\CmD3D11HLSLProgram.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareIndexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareIndexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11Mappings.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareVertexBuffer.cpp" />
     <ClCompile Include="Source\CmD3D11HardwareVertexBuffer.cpp" />
+    <ClCompile Include="Source\CmD3D11VertexDeclaration.cpp" />
     <ClCompile Include="Source\CmD3D11VideoMode.cpp" />
     <ClCompile Include="Source\CmD3D11VideoMode.cpp" />
     <ClCompile Include="Source\CmD3D11VideoModeList.cpp" />
     <ClCompile Include="Source\CmD3D11VideoModeList.cpp" />
   </ItemGroup>
   </ItemGroup>

+ 12 - 0
CamelotD3D11RenderSystem/CamelotD3D11RenderSystem.vcxproj.filters

@@ -57,6 +57,12 @@
     <ClInclude Include="Include\CmD3D11HardwareConstantBuffer.h">
     <ClInclude Include="Include\CmD3D11HardwareConstantBuffer.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmD3D11HardwareBufferManager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmD3D11VertexDeclaration.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
     <ClCompile Include="Source\CmD3D11GpuProgram.cpp">
@@ -98,5 +104,11 @@
     <ClCompile Include="Source\CmD3D11HardwareConstantBuffer.cpp">
     <ClCompile Include="Source\CmD3D11HardwareConstantBuffer.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmD3D11HardwareBufferManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmD3D11VertexDeclaration.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 15 - 8
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h

@@ -13,14 +13,21 @@ namespace CamelotEngine
 		const String& getLanguage() const;
 		const String& getLanguage() const;
 		bool isSupported() const;
 		bool isSupported() const;
 
 
-		/** Sets whether matrix packing in column-major order. */ 
-		void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; }
-		/** Gets whether matrix packed in column-major order. */
-		bool getColumnMajorMatrices(void) const { return mColumnMajorMatrices; }
-		/** Sets whether backwards compatibility is enabled. */ 
-		void setEnableBackwardsCompatibility(bool enableBackwardsCompatibility) { mEnableBackwardsCompatibility = enableBackwardsCompatibility; }
-		/** Gets whether backwards compatibility is enabled. */
-		bool getEnableBackwardsCompatibility(void) const { return mEnableBackwardsCompatibility; }
+		/** Sets whether matrix packing in column-major order. */ 
+		void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; }
+		/** Gets whether matrix packed in column-major order. */
+		bool getColumnMajorMatrices() const { return mColumnMajorMatrices; }
+		/** Sets whether backwards compatibility is enabled. */ 
+		void setEnableBackwardsCompatibility(bool enableBackwardsCompatibility) { mEnableBackwardsCompatibility = enableBackwardsCompatibility; }
+		/** Gets whether backwards compatibility is enabled. */
+		bool getEnableBackwardsCompatibility() const { return mEnableBackwardsCompatibility; }
+
+		const HLSLMicroCode& getMicroCode() const;
+		unsigned int getNumInputs() const;
+		unsigned int getNumOutputs() const;
+
+		const D3D11_SIGNATURE_PARAMETER_DESC& getInputParamDesc(unsigned int index) const;
+		const D3D11_SIGNATURE_PARAMETER_DESC& getOutputParamDesc(unsigned int index) const;
 
 
 	protected:
 	protected:
 		friend class D3D11HLSLProgramFactory;
 		friend class D3D11HLSLProgramFactory;

+ 50 - 0
CamelotD3D11RenderSystem/Include/CmD3D11HardwareBufferManager.h

@@ -0,0 +1,50 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmHardwareBufferManager.h"
+
+namespace CamelotEngine
+{
+	class CM_D3D11_EXPORT D3D11HardwareBufferManagerBase : public HardwareBufferManagerBase
+	{
+	public:
+		D3D11HardwareBufferManagerBase(D3D11Device& device);
+		~D3D11HardwareBufferManagerBase();
+
+		/**
+		 * @brief	Creates a hardware vertex buffer.
+		 */
+		HardwareVertexBufferPtr createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut = false);
+		
+		/**
+		 * @brief	Creates a hardware index buffer.
+		 */
+		HardwareIndexBufferPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage);
+		
+		/**
+		 * @brief	Creates a hardware index buffer.
+		 */
+		HardwareConstantBufferPtr createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage);
+
+	protected:     
+		/// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs
+		VertexDeclarationPtr createVertexDeclarationImpl(void);
+		/// Internal method for destroys a vertex declaration, may be overridden by certain rendering APIs
+		void destroyVertexDeclarationImpl(VertexDeclaration* decl);
+
+		D3D11Device& mDevice;
+	};
+
+	class CM_D3D11_EXPORT D3D11HardwareBufferManager : public HardwareBufferManager
+	{
+	public:
+		D3D11HardwareBufferManager(D3D11Device& device)
+			: HardwareBufferManager(new D3D11HardwareBufferManagerBase(device)) 
+		{ }
+
+		~D3D11HardwareBufferManager()
+		{
+			delete mImpl;
+		}
+	};
+}

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HardwareVertexBuffer.h

@@ -10,7 +10,7 @@ namespace CamelotEngine
 	{
 	{
 	public:
 	public:
 		D3D11HardwareVertexBuffer(D3D11Device& device, HardwareBufferManagerBase* mgr, UINT32 vertexSize, UINT32 numVertices, 
 		D3D11HardwareVertexBuffer(D3D11Device& device, HardwareBufferManagerBase* mgr, UINT32 vertexSize, UINT32 numVertices, 
-			HardwareBuffer::Usage usage, bool useSystemMem);
+			HardwareBuffer::Usage usage, bool useSystemMem, bool streamOut);
 		~D3D11HardwareVertexBuffer();
 		~D3D11HardwareVertexBuffer();
 
 
 		/**
 		/**

+ 2 - 0
CamelotD3D11RenderSystem/Include/CmD3D11Prerequisites.h

@@ -50,6 +50,8 @@ namespace CamelotEngine
 		TID_D3D9_HLSLProgram = 12000
 		TID_D3D9_HLSLProgram = 12000
 	};
 	};
 
 
+	typedef vector<char*>::type HLSLMicroCode;
+
 // Should we ask D3D to manage vertex/index buffers automatically?
 // Should we ask D3D to manage vertex/index buffers automatically?
 // Doing so avoids lost devices, but also has a performance impact
 // Doing so avoids lost devices, but also has a performance impact
 // which is unacceptably bad when using very large buffers
 // which is unacceptably bad when using very large buffers

+ 61 - 0
CamelotD3D11RenderSystem/Include/CmD3D11VertexDeclaration.h

@@ -0,0 +1,61 @@
+#pragma once
+
+#include "CmD3D11Prerequisites.h"
+#include "CmHardwareVertexBuffer.h"
+
+namespace CamelotEngine
+{
+	class D3D11VertexDeclaration : public VertexDeclaration
+	{
+	protected:
+		mutable bool mNeedsRebuild;
+
+		map<D3D11Device*, ID3D11InputLayout*>::type mLayoutPerDevice;
+	public:
+		D3D11VertexDeclaration();
+		~D3D11VertexDeclaration();
+
+		/**
+		 * @copydoc VertexDeclaration::addElement
+		 */
+		const VertexElement& addElement(unsigned short source, UINT32 offset, VertexElementType theType,
+			VertexElementSemantic semantic, unsigned short index = 0);
+
+		/**
+		 * @copydoc VertexDeclaration::insertElement
+		 */
+		const VertexElement& insertElement(unsigned short atPosition,
+			unsigned short source, UINT32 offset, VertexElementType theType,
+			VertexElementSemantic semantic, unsigned short index = 0);
+
+		/**
+		 * @copydoc VertexDeclaration::removeElement(unsigned short)
+		 */
+		void removeElement(unsigned short elem_index);
+
+		/**
+		 * @copydoc VertexDeclaration::removeElement(VertexElementSemantic, unsigned short)
+		 */
+		void removeElement(VertexElementSemantic semantic, unsigned short index = 0);
+
+		/**
+		 * @copydoc VertexDeclaration::removeAllElements
+		 */
+		void removeAllElements(void);
+
+		/**
+		 * @copydoc VertexDeclaration::modifyElement
+		 */
+		void modifyElement(unsigned short elem_index, unsigned short source, UINT32 offset, VertexElementType theType,
+			VertexElementSemantic semantic, unsigned short index = 0);
+
+		/**
+		 * @brief	Gets the D3D11 input layout.
+		 * 			
+		 * @note	Recreates the layout if it way previously modified or if this is the first time
+		 * 			this method is called.
+		 */
+		ID3D11InputLayout* getD3DLayout(D3D11Device& device, D3D11HLSLProgram& programToBindTo);
+	};
+
+}

+ 63 - 38
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp

@@ -33,50 +33,75 @@ namespace CamelotEngine
 
 
 	ID3DBlob* D3D11HLSLProgram::compileMicrocode()
 	ID3DBlob* D3D11HLSLProgram::compileMicrocode()
 	{
 	{
-		// TODO - Preprocessor defines aren't supported
-
-		UINT compileFlags = 0;
-#if defined(CM_DEBUG_MODE)
-		compileFlags |= D3DCOMPILE_DEBUG;
-		compileFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
-#endif
-
-		if (mColumnMajorMatrices)
-			compileFlags |= D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR;
-		else
-			compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
-
-		if (mEnableBackwardsCompatibility)
-			compileFlags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
-
-		ID3DBlob* microCode = nullptr;
-		ID3DBlob* errors = nullptr;
-
-		HRESULT hr = D3DCompile(
-			mSource.c_str(),	// [in] Pointer to the shader in memory. 
-			mSource.size(),		// [in] Size of the shader in memory.  
-			nullptr,			// [in] The name of the file that contains the shader code. 
-			nullptr,			// [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D_SHADER_MACRO. If not used, set this to NULL. 
-			nullptr,			// [in] Optional. Pointer to an ID3DInclude Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include. 
-			mEntryPoint.c_str(),// [in] Name of the shader-entrypoint function where shader execution begins. 
-			mSyntaxCode.c_str(),// [in] A string that specifies the shader model; can be any profile in shader model 4 or higher. 
-			compileFlags,		// [in] Effect compile flags - no D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY at the first try...
-			0,					// [in] Effect compile flags
-			&microCode,			// [out] A pointer to an ID3DBlob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information. 
-			&errors				// [out] A pointer to an ID3DBlob Interface which contains a listing of errors and warnings that occurred during compilation. These errors and warnings are identical to the the debug output from a debugger.
+		// TODO - Preprocessor defines aren't supported
+
+		UINT compileFlags = 0;
+#if defined(CM_DEBUG_MODE)
+		compileFlags |= D3DCOMPILE_DEBUG;
+		compileFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+		if (mColumnMajorMatrices)
+			compileFlags |= D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR;
+		else
+			compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
+
+		if (mEnableBackwardsCompatibility)
+			compileFlags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
+
+		ID3DBlob* microCode = nullptr;
+		ID3DBlob* errors = nullptr;
+
+		HRESULT hr = D3DCompile(
+			mSource.c_str(),	// [in] Pointer to the shader in memory. 
+			mSource.size(),		// [in] Size of the shader in memory.  
+			nullptr,			// [in] The name of the file that contains the shader code. 
+			nullptr,			// [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D_SHADER_MACRO. If not used, set this to NULL. 
+			nullptr,			// [in] Optional. Pointer to an ID3DInclude Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include. 
+			mEntryPoint.c_str(),// [in] Name of the shader-entrypoint function where shader execution begins. 
+			mSyntaxCode.c_str(),// [in] A string that specifies the shader model; can be any profile in shader model 4 or higher. 
+			compileFlags,		// [in] Effect compile flags - no D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY at the first try...
+			0,					// [in] Effect compile flags
+			&microCode,			// [out] A pointer to an ID3DBlob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information. 
+			&errors				// [out] A pointer to an ID3DBlob Interface which contains a listing of errors and warnings that occurred during compilation. These errors and warnings are identical to the the debug output from a debugger.
 			);
 			);
 
 
-		if (FAILED(hr))
-		{
-			String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
-				String(static_cast<const char*>(errors->GetBufferPointer()));
-
-			SAFE_RELEASE(errors);
-			CM_EXCEPT(RenderingAPIException, message);
+		if (FAILED(hr))
+		{
+			String message = "Cannot assemble D3D11 high-level shader. Errors:\n" +
+				String(static_cast<const char*>(errors->GetBufferPointer()));
+
+			SAFE_RELEASE(errors);
+			CM_EXCEPT(RenderingAPIException, message);
 		}
 		}
 
 
 		SAFE_RELEASE(errors);
 		SAFE_RELEASE(errors);
 
 
 		return microCode;
 		return microCode;
 	}
 	}
+
+	const HLSLMicroCode& D3D11HLSLProgram::getMicroCode() const
+	{
+		CM_EXCEPT(NotImplementedException, "Not implemented");
+	}
+
+	unsigned int D3D11HLSLProgram::getNumInputs() const
+	{
+		CM_EXCEPT(NotImplementedException, "Not implemented");
+	}
+
+	unsigned int D3D11HLSLProgram::getNumOutputs() const
+	{
+		CM_EXCEPT(NotImplementedException, "Not implemented");
+	}
+
+	const D3D11_SIGNATURE_PARAMETER_DESC& D3D11HLSLProgram::getInputParamDesc(unsigned int index) const
+	{
+		CM_EXCEPT(NotImplementedException, "Not implemented");
+	}
+
+	const D3D11_SIGNATURE_PARAMETER_DESC& D3D11HLSLProgram::getOutputParamDesc(unsigned int index) const
+	{
+		CM_EXCEPT(NotImplementedException, "Not implemented");
+	}
 }
 }

+ 68 - 0
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBufferManager.cpp

@@ -0,0 +1,68 @@
+#include "CmD3D11HardwareBufferManager.h"
+#include "CmD3D11HardwareVertexBuffer.h"
+#include "CmD3D11HardwareIndexBuffer.h"
+#include "CmD3D11HardwareConstantBuffer.h"
+#include "CmD3D11VertexDeclaration.h"
+
+namespace CamelotEngine
+{
+	D3D11HardwareBufferManagerBase::D3D11HardwareBufferManagerBase(D3D11Device& device)
+		: mDevice(device)
+	{ }
+
+	D3D11HardwareBufferManagerBase::~D3D11HardwareBufferManagerBase()
+	{
+		destroyAllBindings();
+	}
+
+	HardwareVertexBufferPtr D3D11HardwareBufferManagerBase::createVertexBuffer(UINT32 vertexSize, 
+		UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut)
+	{
+		assert (numVerts > 0);
+		D3D11HardwareVertexBuffer* vbuf = new D3D11HardwareVertexBuffer(mDevice,
+			this, vertexSize, numVerts, usage, false, streamOut);
+		{
+			mVertexBuffers.insert(vbuf);
+		}
+
+		return HardwareVertexBufferPtr(vbuf);
+	}
+
+	HardwareIndexBufferPtr D3D11HardwareBufferManagerBase::createIndexBuffer(HardwareIndexBuffer::IndexType itype, 
+		UINT32 numIndexes, HardwareBuffer::Usage usage)
+	{
+		assert (numIndexes > 0);
+
+		D3D11HardwareIndexBuffer* idx = new D3D11HardwareIndexBuffer(mDevice,
+			this, itype, numIndexes, usage, false);
+		{
+
+				mIndexBuffers.insert(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)
+	{
+		return VertexDeclarationPtr(new D3D11VertexDeclaration());
+	}
+
+	void D3D11HardwareBufferManagerBase::destroyVertexDeclarationImpl(VertexDeclaration* decl)
+	{
+		delete decl;
+	}
+}

+ 2 - 2
CamelotD3D11RenderSystem/Source/CmD3D11HardwareVertexBuffer.cpp

@@ -3,10 +3,10 @@
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
 	D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer(D3D11Device& device, HardwareBufferManagerBase* mgr, UINT32 vertexSize, UINT32 numVertices, 
 	D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer(D3D11Device& device, HardwareBufferManagerBase* mgr, UINT32 vertexSize, UINT32 numVertices, 
-		HardwareBuffer::Usage usage, bool useSystemMem)
+		HardwareBuffer::Usage usage, bool useSystemMem, bool streamOut)
 		:HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMem)
 		:HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMem)
 	{
 	{
-		mBuffer = new D3D11HardwareBuffer(D3D11HardwareBuffer::VERTEX_BUFFER, mSizeInBytes, usage, device, useSystemMem, false);
+		mBuffer = new D3D11HardwareBuffer(D3D11HardwareBuffer::VERTEX_BUFFER, mSizeInBytes, usage, device, useSystemMem, streamOut);
 	}
 	}
 
 
 	D3D11HardwareVertexBuffer::~D3D11HardwareVertexBuffer()
 	D3D11HardwareVertexBuffer::~D3D11HardwareVertexBuffer()

+ 137 - 0
CamelotD3D11RenderSystem/Source/CmD3D11VertexDeclaration.cpp

@@ -0,0 +1,137 @@
+#include "CmD3D11VertexDeclaration.h"
+#include "CmD3D11Mappings.h"
+#include "CmD3D11Device.h"
+#include "CmD3D11HLSLProgram.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	D3D11VertexDeclaration::D3D11VertexDeclaration()
+		:VertexDeclaration()
+	{
+	}
+
+	D3D11VertexDeclaration::~D3D11VertexDeclaration()
+	{
+		for(auto iter = mLayoutPerDevice.begin(); iter != mLayoutPerDevice.end(); ++iter)
+		{
+			if(iter->second != nullptr)
+				iter->second->Release();
+		}
+	}
+
+	const VertexElement& D3D11VertexDeclaration::addElement(unsigned short source, UINT32 offset, VertexElementType theType,
+		VertexElementSemantic semantic, unsigned short index)
+	{
+		mNeedsRebuild = true;
+		return VertexDeclaration::addElement(source, offset, theType, semantic, index);
+	}
+
+	const VertexElement& D3D11VertexDeclaration::insertElement(unsigned short atPosition,
+		unsigned short source, UINT32 offset, VertexElementType theType,
+		VertexElementSemantic semantic, unsigned short index)
+	{
+		mNeedsRebuild = true;
+		return VertexDeclaration::insertElement(atPosition, source, offset, theType, semantic, index);
+	}
+
+	void D3D11VertexDeclaration::removeElement(unsigned short elem_index)
+	{
+		VertexDeclaration::removeElement(elem_index);
+		mNeedsRebuild = true;
+	}
+
+	void D3D11VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
+	{
+		VertexDeclaration::removeElement(semantic, index);
+		mNeedsRebuild = true;
+	}
+
+	void D3D11VertexDeclaration::removeAllElements(void)
+	{
+		VertexDeclaration::removeAllElements();
+		mNeedsRebuild = true;
+	}
+
+	void D3D11VertexDeclaration::modifyElement(unsigned short elem_index, unsigned short source, UINT32 offset, VertexElementType theType,
+		VertexElementSemantic semantic, unsigned short index)
+	{
+		VertexDeclaration::modifyElement(elem_index, source, offset, theType, semantic, index);
+		mNeedsRebuild = true;
+	}
+
+	ID3D11InputLayout* D3D11VertexDeclaration::getD3DLayout(D3D11Device& device, D3D11HLSLProgram& programToBindTo)
+	{
+		if(!mNeedsRebuild)
+		{
+			auto iterFind = mLayoutPerDevice.find(&device);
+
+			if(iterFind == mLayoutPerDevice.end())
+				mNeedsRebuild = true;
+		}
+
+		if(mNeedsRebuild)
+		{
+			size_t numElements = programToBindTo.getNumInputs();
+
+			D3D11_INPUT_ELEMENT_DESC* declElements = new D3D11_INPUT_ELEMENT_DESC[numElements];
+			ZeroMemory(declElements, sizeof(D3D11_INPUT_ELEMENT_DESC) * numElements);
+
+			unsigned int idx;
+			for (idx = 0; idx < numElements; ++idx)
+			{
+				const D3D11_SIGNATURE_PARAMETER_DESC& inputDesc = programToBindTo.getInputParamDesc(idx);
+				VertexElementList::const_iterator i, iend;
+				iend = mElementList.end();
+				bool found = false;
+				for (i = mElementList.begin(); i != iend; ++i)
+				{
+					LPCSTR semanticName			= D3D11Mappings::get(i->getSemantic());
+					UINT semanticIndex			= i->getIndex();
+					if(strcmp(semanticName, inputDesc.SemanticName) == 0
+						&& semanticIndex == inputDesc.SemanticIndex)
+					{
+						found = true;
+						break;
+					}
+				}
+
+				if(!found)
+				{
+					CM_EXCEPT(RenderingAPIException, "Shader signature doesn't match the vertex declaration!");
+				}
+
+				declElements[idx].SemanticName			= inputDesc.SemanticName;
+				declElements[idx].SemanticIndex			= inputDesc.SemanticIndex;
+				declElements[idx].Format				= D3D11Mappings::get(i->getType());
+				declElements[idx].InputSlot				= i->getSource();
+				declElements[idx].AlignedByteOffset		= static_cast<WORD>(i->getOffset());
+				declElements[idx].InputSlotClass		= D3D11_INPUT_PER_VERTEX_DATA;
+				declElements[idx].InstanceDataStepRate	= 0;
+				
+				DWORD dwShaderFlags = 0;
+				const HLSLMicroCode& microCode = programToBindTo.getMicroCode();
+
+				ID3D11InputLayout* inputLayout = nullptr; 
+				HRESULT hr = device.getD3D11Device()->CreateInputLayout( 
+					declElements, 
+					programToBindTo.getNumInputs(), 
+					&microCode[0], 
+					microCode.size(),
+					&inputLayout );
+
+				if (FAILED(hr)|| device.hasError())
+				{
+					String errorDescription = device.getErrorDescription();
+
+					CM_EXCEPT(RenderingAPIException, "Unable to set D3D11 vertex declaration" + errorDescription);
+				}
+
+				mLayoutPerDevice[&device] = inputLayout;
+
+			}
+		}
+
+		return mLayoutPerDevice[&device];
+	}
+}

+ 15 - 3
CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h

@@ -45,12 +45,24 @@ namespace CamelotEngine {
     public:
     public:
         D3D9HardwareBufferManagerBase();
         D3D9HardwareBufferManagerBase();
         ~D3D9HardwareBufferManagerBase();
         ~D3D9HardwareBufferManagerBase();
-        /// Creates a vertex buffer
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createVertexBuffer
+		 */
 		HardwareVertexBufferPtr 
 		HardwareVertexBufferPtr 
-            createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage);
-		/// Create a hardware vertex buffer
+            createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut = false);
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createIndexBuffer
+		 */
 		HardwareIndexBufferPtr 
 		HardwareIndexBufferPtr 
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage);
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage);
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createConstantBuffer
+		 */
+		HardwareConstantBufferPtr 
+			createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage);
     };
     };
 
 
 	/// D3D9HardwareBufferManagerBase as a Singleton
 	/// D3D9HardwareBufferManagerBase as a Singleton

+ 8 - 3
CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp

@@ -44,14 +44,13 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     HardwareVertexBufferPtr 
     HardwareVertexBufferPtr 
     D3D9HardwareBufferManagerBase::
     D3D9HardwareBufferManagerBase::
-    createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage)
+    createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut)
     {
     {
 		assert (numVerts > 0);
 		assert (numVerts > 0);
 
 
 		D3D9HardwareVertexBuffer* vbuf = new D3D9HardwareVertexBuffer(
 		D3D9HardwareVertexBuffer* vbuf = new D3D9HardwareVertexBuffer(
 			this, vertexSize, numVerts, usage, false);
 			this, vertexSize, numVerts, usage, false);
 		{
 		{
-			CM_LOCK_MUTEX(mVertexBuffersMutex)
 			mVertexBuffers.insert(vbuf);
 			mVertexBuffers.insert(vbuf);
 		}
 		}
         return HardwareVertexBufferPtr(vbuf);
         return HardwareVertexBufferPtr(vbuf);
@@ -65,12 +64,18 @@ namespace CamelotEngine {
 
 
 		D3D9HardwareIndexBuffer* idx = new D3D9HardwareIndexBuffer(this, itype, numIndexes, usage, false);
 		D3D9HardwareIndexBuffer* idx = new D3D9HardwareIndexBuffer(this, itype, numIndexes, usage, false);
 		{
 		{
-			CM_LOCK_MUTEX(mIndexBuffersMutex)
 			mIndexBuffers.insert(idx);
 			mIndexBuffers.insert(idx);
 		}
 		}
 		return HardwareIndexBufferPtr(idx);
 		return HardwareIndexBufferPtr(idx);
             
             
     }
     }
+	//-----------------------------------------------------------------------
+	HardwareConstantBufferPtr 
+		D3D9HardwareBufferManagerBase::
+		createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage)
+	{
+		CM_EXCEPT(RenderingAPIException, "Constant buffers not supported on D3D9.");
+	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     VertexDeclarationPtr D3D9HardwareBufferManagerBase::createVertexDeclarationImpl(void)
     VertexDeclarationPtr D3D9HardwareBufferManagerBase::createVertexDeclarationImpl(void)
     {
     {

+ 14 - 3
CamelotGLRenderer/Include/CmGLDefaultHardwareBufferManager.h

@@ -103,15 +103,26 @@ namespace CamelotEngine {
     public:
     public:
         GLDefaultHardwareBufferManagerBase();
         GLDefaultHardwareBufferManagerBase();
         ~GLDefaultHardwareBufferManagerBase();
         ~GLDefaultHardwareBufferManagerBase();
-        /// Creates a vertex buffer
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createVertexBuffer
+		 */
 		HardwareVertexBufferPtr 
 		HardwareVertexBufferPtr 
             createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, 
             createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, 
-				HardwareBuffer::Usage usage);
-		/// Create a hardware vertex buffer
+				HardwareBuffer::Usage usage, bool streamOut = false);
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createIndexBuffer
+		 */
 		HardwareIndexBufferPtr 
 		HardwareIndexBufferPtr 
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
 				HardwareBuffer::Usage usage);
 				HardwareBuffer::Usage usage);
 
 
+		/**
+		 * @copydoc HardwareBufferManagerBase::createConstantBuffer
+		 */
+		HardwareConstantBufferPtr createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage);
+
     };
     };
 
 
 	/// GLDefaultHardwareBufferManagerBase as a Singleton
 	/// GLDefaultHardwareBufferManagerBase as a Singleton

+ 15 - 3
CamelotGLRenderer/Include/CmGLHardwareBufferManager.h

@@ -48,13 +48,25 @@ namespace CamelotEngine {
     public:
     public:
         GLHardwareBufferManagerBase();
         GLHardwareBufferManagerBase();
         ~GLHardwareBufferManagerBase();
         ~GLHardwareBufferManagerBase();
-        /// Creates a vertex buffer
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createVertexBuffer
+		 */
         HardwareVertexBufferPtr createVertexBuffer(UINT32 vertexSize, 
         HardwareVertexBufferPtr createVertexBuffer(UINT32 vertexSize, 
-            UINT32 numVerts, HardwareBuffer::Usage usage);
-        /// Create a hardware vertex buffer
+            UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut = false);
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createIndexBuffer
+		 */
         HardwareIndexBufferPtr createIndexBuffer(
         HardwareIndexBufferPtr createIndexBuffer(
             HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
             HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
             HardwareBuffer::Usage usage);
             HardwareBuffer::Usage usage);
+
+		/**
+		 * @copydoc HardwareBufferManagerBase::createConstantBuffer
+		 */
+		HardwareConstantBufferPtr createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage);
+
         /// Utility function to get the correct GL usage based on HBU's
         /// Utility function to get the correct GL usage based on HBU's
         static GLenum getGLUsage(unsigned int usage);
         static GLenum getGLUsage(unsigned int usage);
 
 

+ 6 - 1
CamelotGLRenderer/Source/CmGLDefaultHardwareBufferManager.cpp

@@ -152,7 +152,7 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
 	HardwareVertexBufferPtr 
 	HardwareVertexBufferPtr 
         GLDefaultHardwareBufferManagerBase::createVertexBuffer(UINT32 vertexSize, 
         GLDefaultHardwareBufferManagerBase::createVertexBuffer(UINT32 vertexSize, 
-		UINT32 numVerts, HardwareBuffer::Usage usage)
+		UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut)
 	{
 	{
 		return HardwareVertexBufferPtr(
 		return HardwareVertexBufferPtr(
 			new GLDefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage));
 			new GLDefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage));
@@ -165,4 +165,9 @@ namespace CamelotEngine {
 		return HardwareIndexBufferPtr(
 		return HardwareIndexBufferPtr(
 			new GLDefaultHardwareIndexBuffer(itype, numIndexes, usage) );
 			new GLDefaultHardwareIndexBuffer(itype, numIndexes, usage) );
 	}
 	}
+	//---------------------------------------------------------------------
+	HardwareConstantBufferPtr GLDefaultHardwareBufferManagerBase::createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage)
+	{
+		CM_EXCEPT(RenderingAPIException, "Support for constant buffers not implemented yet in OpenGL.");
+	}
 }
 }

+ 6 - 3
CamelotGLRenderer/Source/CmGLHardwareBufferManager.cpp

@@ -82,12 +82,11 @@ namespace CamelotEngine {
     }
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     HardwareVertexBufferPtr GLHardwareBufferManagerBase::createVertexBuffer(
     HardwareVertexBufferPtr GLHardwareBufferManagerBase::createVertexBuffer(
-        UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage)
+        UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut)
     {
     {
 		GLHardwareVertexBuffer* buf = 
 		GLHardwareVertexBuffer* buf = 
 			new GLHardwareVertexBuffer(this, vertexSize, numVerts, usage);
 			new GLHardwareVertexBuffer(this, vertexSize, numVerts, usage);
 		{
 		{
-			CM_LOCK_MUTEX(mVertexBuffersMutex)
 			mVertexBuffers.insert(buf);
 			mVertexBuffers.insert(buf);
 		}
 		}
 		return HardwareVertexBufferPtr(buf);
 		return HardwareVertexBufferPtr(buf);
@@ -101,11 +100,15 @@ namespace CamelotEngine {
 		GLHardwareIndexBuffer* buf = 
 		GLHardwareIndexBuffer* buf = 
 			new GLHardwareIndexBuffer(this, itype, numIndexes, usage);
 			new GLHardwareIndexBuffer(this, itype, numIndexes, usage);
 		{
 		{
-			CM_LOCK_MUTEX(mIndexBuffersMutex)
 			mIndexBuffers.insert(buf);
 			mIndexBuffers.insert(buf);
 		}
 		}
 		return HardwareIndexBufferPtr(buf);
 		return HardwareIndexBufferPtr(buf);
     }
     }
+	//---------------------------------------------------------------------
+	HardwareConstantBufferPtr GLHardwareBufferManagerBase::createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage)
+	{
+		CM_EXCEPT(RenderingAPIException, "Support for constant buffers not implemented yet in OpenGL.");
+	}
     //---------------------------------------------------------------------
     //---------------------------------------------------------------------
     GLenum GLHardwareBufferManagerBase::getGLUsage(unsigned int usage)
     GLenum GLHardwareBufferManagerBase::getGLUsage(unsigned int usage)
     {
     {

+ 1 - 0
CamelotRenderer.sln

@@ -17,6 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotClient", "CamelotCli
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
 		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
 		{122B7A22-0C62-4B35-B661-EBF3F394EA79} = {122B7A22-0C62-4B35-B661-EBF3F394EA79}
 		{122B7A22-0C62-4B35-B661-EBF3F394EA79} = {122B7A22-0C62-4B35-B661-EBF3F394EA79}
+		{1437BB4E-DDB3-4307-AA41-8C035DA3014B} = {1437BB4E-DDB3-4307-AA41-8C035DA3014B}
 		{F58FF869-2EA6-4FFF-AB84-328C531BA9D9} = {F58FF869-2EA6-4FFF-AB84-328C531BA9D9}
 		{F58FF869-2EA6-4FFF-AB84-328C531BA9D9} = {F58FF869-2EA6-4FFF-AB84-328C531BA9D9}
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC} = {08975177-4A13-4EE7-BB21-3BB92FB3F3CC}
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC} = {08975177-4A13-4EE7-BB21-3BB92FB3F3CC}
 		{7F449698-73DF-4203-9F31-0877DBF01695} = {7F449698-73DF-4203-9F31-0877DBF01695}
 		{7F449698-73DF-4203-9F31-0877DBF01695} = {7F449698-73DF-4203-9F31-0877DBF01695}

+ 30 - 3
CamelotRenderer/Include/CmDefaultHardwareBufferManager.h

@@ -33,6 +33,7 @@ THE SOFTWARE.
 #include "CmHardwareBufferManager.h"
 #include "CmHardwareBufferManager.h"
 #include "CmHardwareVertexBuffer.h"
 #include "CmHardwareVertexBuffer.h"
 #include "CmHardwareIndexBuffer.h"
 #include "CmHardwareIndexBuffer.h"
+#include "CmHardwareConstantBuffer.h"
 
 
 namespace CamelotEngine {
 namespace CamelotEngine {
 	/** \addtogroup Core
 	/** \addtogroup Core
@@ -93,6 +94,29 @@ namespace CamelotEngine {
 
 
     };
     };
 
 
+	/// Specialisation of HardwareConstantBuffer for emulation
+	class CM_EXPORT DefaultHardwareConstantBuffer : public HardwareConstantBuffer
+	{
+	protected:
+		unsigned char* mpData;
+		/** See HardwareBuffer. */
+		void* lockImpl(UINT32 offset, UINT32 length, LockOptions options);
+		/** See HardwareBuffer. */
+		void unlockImpl(void);
+	public:
+		DefaultHardwareConstantBuffer(HardwareBufferManagerBase* mgr, UINT32 sizeBytes, HardwareBuffer::Usage usage);
+		~DefaultHardwareConstantBuffer();
+		/** See HardwareBuffer. */
+		void readData(UINT32 offset, UINT32 length, void* pDest);
+		/** See HardwareBuffer. */
+		void writeData(UINT32 offset, UINT32 length, const void* pSource,
+			bool discardWholeBuffer = false);
+		/** Override HardwareBuffer to turn off all shadowing. */
+		void* lock(UINT32 offset, UINT32 length, LockOptions options);
+		/** Override HardwareBuffer to turn off all shadowing. */
+		void unlock(void);
+	};
+
 	/** Specialisation of HardwareBufferManagerBase to emulate hardware buffers.
 	/** Specialisation of HardwareBufferManagerBase to emulate hardware buffers.
 	@remarks
 	@remarks
 		You might want to instantiate this class if you want to utilise
 		You might want to instantiate this class if you want to utilise
@@ -105,14 +129,17 @@ namespace CamelotEngine {
     public:
     public:
         DefaultHardwareBufferManagerBase();
         DefaultHardwareBufferManagerBase();
         ~DefaultHardwareBufferManagerBase();
         ~DefaultHardwareBufferManagerBase();
-        /// Creates a vertex buffer
+        /// Creates a hardware vertex buffer
 		HardwareVertexBufferPtr 
 		HardwareVertexBufferPtr 
             createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, 
             createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, 
-				HardwareBuffer::Usage usage);
-		/// Create a hardware vertex buffer
+				HardwareBuffer::Usage usage, bool streamOut = false);
+		/// Create a hardware index buffer
 		HardwareIndexBufferPtr 
 		HardwareIndexBufferPtr 
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
             createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, 
 				HardwareBuffer::Usage usage);
 				HardwareBuffer::Usage usage);
+		/// Create a hardware constant buffer
+		HardwareConstantBufferPtr 
+			createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage);
     };
     };
 
 
 	/// DefaultHardwareBufferManager as a Singleton
 	/// DefaultHardwareBufferManager as a Singleton

+ 18 - 23
CamelotRenderer/Include/CmHardwareBufferManager.h

@@ -72,12 +72,6 @@ namespace CamelotEngine {
 		typedef set<VertexBufferBinding*>::type VertexBufferBindingList;
 		typedef set<VertexBufferBinding*>::type VertexBufferBindingList;
 		VertexBufferBindingList mVertexBufferBindings;
 		VertexBufferBindingList mVertexBufferBindings;
 
 
-		// Mutexes
-		CM_MUTEX(mVertexBuffersMutex)
-		CM_MUTEX(mIndexBuffersMutex)
-		CM_MUTEX(mConstantBuffersMutex)
-		CM_MUTEX(mVertexBufferBindingsMutex)
-
         /// Internal method for destroys all vertex buffer bindings
         /// Internal method for destroys all vertex buffer bindings
         virtual void destroyAllBindings(void);
         virtual void destroyAllBindings(void);
 
 
@@ -112,16 +106,11 @@ namespace CamelotEngine {
         @param usage One or more members of the HardwareBuffer::Usage enumeration; you are
         @param usage One or more members of the HardwareBuffer::Usage enumeration; you are
             strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to 
             strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to 
             update regularly, consider HBU_DYNAMIC_WRITE_ONLY and useShadowBuffer=true.
             update regularly, consider HBU_DYNAMIC_WRITE_ONLY and useShadowBuffer=true.
-		@param useShadowBuffer If set to true, this buffer will be 'shadowed' by one stored in 
-            system memory rather than GPU or AGP memory. You should set this flag if you intend 
-            to read data back from the vertex buffer, because reading data from a buffer
-			in the GPU or AGP memory is very expensive, and is in fact impossible if you
-            specify HBU_WRITE_ONLY for the main buffer. If you use this option, all 
-            reads and writes will be done to the shadow buffer, and the shadow buffer will
-            be synchronised with the real buffer at an appropriate time.
+		@param streamOut Whether the vertex buffer will be used for steam out operations of the
+			geometry shader.
         */
         */
 		virtual HardwareVertexBufferPtr 
 		virtual HardwareVertexBufferPtr 
-            createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage) = 0;
+            createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut = false) = 0;
 		/** Create a hardware index buffer.
 		/** Create a hardware index buffer.
         @remarks Note that because buffers can be shared, they are reference
         @remarks Note that because buffers can be shared, they are reference
             counted so you do not need to worry about destroying them this will be done
             counted so you do not need to worry about destroying them this will be done
@@ -130,18 +119,18 @@ namespace CamelotEngine {
 			you need to be able to address
 			you need to be able to address
 		@param numIndexes The number of indexes in the buffer
 		@param numIndexes The number of indexes in the buffer
         @param usage One or more members of the HardwareBuffer::Usage enumeration.
         @param usage One or more members of the HardwareBuffer::Usage enumeration.
-		@param useShadowBuffer If set to true, this buffer will be 'shadowed' by one stored in 
-            system memory rather than GPU or AGP memory. You should set this flag if you intend 
-            to read data back from the index buffer, because reading data from a buffer
-			in the GPU or AGP memory is very expensive, and is in fact impossible if you
-            specify HBU_WRITE_ONLY for the main buffer. If you use this option, all 
-            reads and writes will be done to the shadow buffer, and the shadow buffer will
-            be synchronised with the real buffer at an appropriate time.
         */
         */
 		virtual HardwareIndexBufferPtr 
 		virtual HardwareIndexBufferPtr 
             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);
 
 
@@ -168,9 +157,9 @@ namespace CamelotEngine {
 		~HardwareBufferManager();
 		~HardwareBufferManager();
 
 
 		/** @copydoc HardwareBufferManagerInterface::createVertexBuffer */
 		/** @copydoc HardwareBufferManagerInterface::createVertexBuffer */
-		HardwareVertexBufferPtr createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage)
+		HardwareVertexBufferPtr createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut = false)
 		{
 		{
-			return mImpl->createVertexBuffer(vertexSize, numVerts, usage);
+			return mImpl->createVertexBuffer(vertexSize, numVerts, usage, streamOut);
 		}
 		}
 		/** @copydoc HardwareBufferManagerInterface::createIndexBuffer */
 		/** @copydoc HardwareBufferManagerInterface::createIndexBuffer */
 		HardwareIndexBufferPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage)
 		HardwareIndexBufferPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, UINT32 numIndexes, HardwareBuffer::Usage usage)
@@ -178,6 +167,12 @@ 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)
 		{
 		{

+ 1 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -149,6 +149,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<RenderSystemContext> RenderSystemContextPtr;
 	typedef std::shared_ptr<RenderSystemContext> RenderSystemContextPtr;
 	typedef std::shared_ptr<Component> ComponentPtr;
 	typedef std::shared_ptr<Component> ComponentPtr;
 	typedef std::shared_ptr<GameObject> GameObjectPtr;
 	typedef std::shared_ptr<GameObject> GameObjectPtr;
+	typedef std::shared_ptr<HardwareConstantBuffer> HardwareConstantBufferPtr;
 }
 }
 
 
 // All type IDs
 // All type IDs

+ 57 - 1
CamelotRenderer/Source/CmDefaultHardwareBufferManager.cpp

@@ -140,6 +140,55 @@ namespace CamelotEngine {
 
 
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
+	DefaultHardwareConstantBuffer::DefaultHardwareConstantBuffer(HardwareBufferManagerBase* mgr, UINT32 sizeBytes, HardwareBuffer::Usage usage)
+		: HardwareConstantBuffer(mgr, sizeBytes, usage, true)
+	{
+		// Allocate aligned memory for better SIMD processing friendly.
+		mpData = static_cast<unsigned char*>(_aligned_malloc(mSizeInBytes, CM_SIMD_ALIGNMENT));
+	}
+	//-----------------------------------------------------------------------
+	DefaultHardwareConstantBuffer::~DefaultHardwareConstantBuffer()
+	{
+		_aligned_free(mpData);
+	}
+	//-----------------------------------------------------------------------
+	void* DefaultHardwareConstantBuffer::lockImpl(UINT32 offset, UINT32 length, LockOptions options)
+	{
+		// Only for use internally, no 'locking' as such
+		return mpData + offset;
+	}
+	//-----------------------------------------------------------------------
+	void DefaultHardwareConstantBuffer::unlockImpl(void)
+	{
+		// Nothing to do
+	}
+	//-----------------------------------------------------------------------
+	void* DefaultHardwareConstantBuffer::lock(UINT32 offset, UINT32 length, LockOptions options)
+	{
+		mIsLocked = true;
+		return mpData + offset;
+	}
+	//-----------------------------------------------------------------------
+	void DefaultHardwareConstantBuffer::unlock(void)
+	{
+		mIsLocked = false;
+		// Nothing to do
+	}
+	//-----------------------------------------------------------------------
+	void DefaultHardwareConstantBuffer::readData(UINT32 offset, UINT32 length, void* pDest)
+	{
+		assert((offset + length) <= mSizeInBytes);
+		memcpy(pDest, mpData + offset, length);
+	}
+	//-----------------------------------------------------------------------
+	void DefaultHardwareConstantBuffer::writeData(UINT32 offset, UINT32 length, const void* pSource,
+		bool discardWholeBuffer)
+	{
+		assert((offset + length) <= mSizeInBytes);
+		// ignore discard, memory is not guaranteed to be zeroised
+		memcpy(mpData + offset, pSource, length);
+
+	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     DefaultHardwareBufferManagerBase::DefaultHardwareBufferManagerBase()
     DefaultHardwareBufferManagerBase::DefaultHardwareBufferManagerBase()
 	{
 	{
@@ -152,7 +201,7 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
 	HardwareVertexBufferPtr 
 	HardwareVertexBufferPtr 
         DefaultHardwareBufferManagerBase::createVertexBuffer(UINT32 vertexSize, 
         DefaultHardwareBufferManagerBase::createVertexBuffer(UINT32 vertexSize, 
-		UINT32 numVerts, HardwareBuffer::Usage usage)
+		UINT32 numVerts, HardwareBuffer::Usage usage, bool streamOut)
 	{
 	{
         DefaultHardwareVertexBuffer* vb = new DefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage);
         DefaultHardwareVertexBuffer* vb = new DefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage);
         return HardwareVertexBufferPtr(vb);
         return HardwareVertexBufferPtr(vb);
@@ -165,4 +214,11 @@ namespace CamelotEngine {
         DefaultHardwareIndexBuffer* ib = new DefaultHardwareIndexBuffer(itype, numIndexes, usage);
         DefaultHardwareIndexBuffer* ib = new DefaultHardwareIndexBuffer(itype, numIndexes, usage);
 		return HardwareIndexBufferPtr(ib);
 		return HardwareIndexBufferPtr(ib);
 	}
 	}
+	//-----------------------------------------------------------------------
+	HardwareConstantBufferPtr 
+		DefaultHardwareBufferManagerBase::createConstantBuffer(UINT32 sizeBytes, HardwareBuffer::Usage usage)
+	{
+		DefaultHardwareConstantBuffer* ib = new DefaultHardwareConstantBuffer(this, sizeBytes, usage);
+		return HardwareConstantBufferPtr(ib);
+	}
 }
 }

+ 0 - 9
CamelotRenderer/Source/CmHardwareBufferManager.cpp

@@ -72,14 +72,12 @@ namespace CamelotEngine {
 	VertexBufferBinding* HardwareBufferManagerBase::createVertexBufferBinding(void)
 	VertexBufferBinding* HardwareBufferManagerBase::createVertexBufferBinding(void)
 	{
 	{
 		VertexBufferBinding* ret = createVertexBufferBindingImpl();
 		VertexBufferBinding* ret = createVertexBufferBindingImpl();
-		CM_LOCK_MUTEX(mVertexBufferBindingsMutex)
 		mVertexBufferBindings.insert(ret);
 		mVertexBufferBindings.insert(ret);
 		return ret;
 		return ret;
 	}
 	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
 	void HardwareBufferManagerBase::destroyVertexBufferBinding(VertexBufferBinding* binding)
 	void HardwareBufferManagerBase::destroyVertexBufferBinding(VertexBufferBinding* binding)
 	{
 	{
-		CM_LOCK_MUTEX(mVertexBufferBindingsMutex)
 		mVertexBufferBindings.erase(binding);
 		mVertexBufferBindings.erase(binding);
 		destroyVertexBufferBindingImpl(binding);
 		destroyVertexBufferBindingImpl(binding);
 	}
 	}
@@ -101,7 +99,6 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void HardwareBufferManagerBase::destroyAllBindings(void)
     void HardwareBufferManagerBase::destroyAllBindings(void)
     {
     {
-		CM_LOCK_MUTEX(mVertexBufferBindingsMutex)
         VertexBufferBindingList::iterator bind;
         VertexBufferBindingList::iterator bind;
         for (bind = mVertexBufferBindings.begin(); bind != mVertexBufferBindings.end(); ++bind)
         for (bind = mVertexBufferBindings.begin(); bind != mVertexBufferBindings.end(); ++bind)
         {
         {
@@ -112,8 +109,6 @@ namespace CamelotEngine {
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	void HardwareBufferManagerBase::_notifyVertexBufferDestroyed(HardwareVertexBuffer* buf)
 	void HardwareBufferManagerBase::_notifyVertexBufferDestroyed(HardwareVertexBuffer* buf)
 	{
 	{
-		CM_LOCK_MUTEX(mVertexBuffersMutex)
-
 		VertexBufferList::iterator i = mVertexBuffers.find(buf);
 		VertexBufferList::iterator i = mVertexBuffers.find(buf);
 		if (i != mVertexBuffers.end())
 		if (i != mVertexBuffers.end())
 		{
 		{
@@ -124,8 +119,6 @@ namespace CamelotEngine {
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	void HardwareBufferManagerBase::_notifyIndexBufferDestroyed(HardwareIndexBuffer* buf)
 	void HardwareBufferManagerBase::_notifyIndexBufferDestroyed(HardwareIndexBuffer* buf)
 	{
 	{
-		CM_LOCK_MUTEX(mIndexBuffersMutex)
-
 		IndexBufferList::iterator i = mIndexBuffers.find(buf);
 		IndexBufferList::iterator i = mIndexBuffers.find(buf);
 		if (i != mIndexBuffers.end())
 		if (i != mIndexBuffers.end())
 		{
 		{
@@ -135,8 +128,6 @@ namespace CamelotEngine {
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	void HardwareBufferManagerBase::_notifyConstantBufferDestroyed(HardwareConstantBuffer* buf)
 	void HardwareBufferManagerBase::_notifyConstantBufferDestroyed(HardwareConstantBuffer* buf)
 	{
 	{
-		CM_LOCK_MUTEX(mConstantBuffersMutex)
-
 		ConstantBufferList::iterator i = mConstantBuffers.find(buf);
 		ConstantBufferList::iterator i = mConstantBuffers.find(buf);
 		if (i != mConstantBuffers.end())
 		if (i != mConstantBuffers.end())
 		{
 		{

+ 3 - 3
CamelotRenderer/Source/CmMesh.cpp

@@ -57,15 +57,15 @@ namespace CamelotEngine
 
 
 		mIndexData->indexCount = meshData->indexCount;
 		mIndexData->indexCount = meshData->indexCount;
 		mIndexData->indexBuffer = HardwareBufferManager::instance().createIndexBuffer(
 		mIndexData->indexBuffer = HardwareBufferManager::instance().createIndexBuffer(
-			HardwareIndexBuffer::IT_16BIT,
+			HardwareIndexBuffer::IT_32BIT,
 			mIndexData->indexCount, 
 			mIndexData->indexCount, 
 			HardwareBuffer::HBU_STATIC_WRITE_ONLY);
 			HardwareBuffer::HBU_STATIC_WRITE_ONLY);
 
 
-		UINT16* idxData = static_cast<UINT16*>(mIndexData->indexBuffer->lock(HardwareBuffer::HBL_NORMAL));
+		UINT32* idxData = static_cast<UINT32*>(mIndexData->indexBuffer->lock(HardwareBuffer::HBL_NORMAL));
 
 
 		for(UINT32 i = 0; i < mIndexData->indexCount; i++)
 		for(UINT32 i = 0; i < mIndexData->indexCount; i++)
 		{
 		{
-			idxData[i] = (UINT16)meshData->index[i];
+			idxData[i] = (UINT32)meshData->index[i];
 		}
 		}
 
 
 		mIndexData->indexBuffer->unlock();
 		mIndexData->indexBuffer->unlock();

+ 3 - 0
CamelotRenderer/TODO.txt

@@ -27,6 +27,9 @@ High-level TODO:
     - No proper support for texture arrays, or multisampled texture resources
     - No proper support for texture arrays, or multisampled texture resources
 	- Staging and immutable buffers. See D3D11Mapping, DWORD D3D11Mappings::get(HardwareBuffer::Usage usage)
 	- Staging and immutable buffers. See D3D11Mapping, DWORD D3D11Mappings::get(HardwareBuffer::Usage usage)
 	- Multiple adapters (multi gpu)
 	- Multiple adapters (multi gpu)
+  - GL equivalents that are missing:
+    - Vertex buffer stream out (Transform Feedback)
+	- GL constant buffers
 
 
 --HARDWARE BUFFERS--
 --HARDWARE BUFFERS--
 New set of HardwareBuffer usage flags:
 New set of HardwareBuffer usage flags: