Browse Source

Neater GpuBuffer creation

BearishSun 9 years ago
parent
commit
046cd0b6a2

+ 22 - 2
Source/BansheeCore/Include/BsCommonTypes.h

@@ -159,11 +159,11 @@ namespace BansheeEngine
 	enum GpuBufferUsage 
 	enum GpuBufferUsage 
 	{
 	{
 		/** 
 		/** 
-		 * Signifies that you don't plan on modifying the buffer often (or at all)	after creation. Modifying such buffer 
+		 * Signifies that you don't plan on modifying the buffer often (or at all) after creation. Modifying such buffer 
 		 * will involve a larger performance hit.
 		 * will involve a larger performance hit.
 		 */
 		 */
         GBU_STATIC = 1,
         GBU_STATIC = 1,
-		/** Signifies that you will modify this buffer fairly often. */
+		/** Signifies that you will modify this buffer fairly often (e.g. every frame). */
 		GBU_DYNAMIC = 2
 		GBU_DYNAMIC = 2
 	};
 	};
 
 
@@ -241,6 +241,26 @@ namespace BansheeEngine
 		GVU_RANDOMWRITE = 0x08
 		GVU_RANDOMWRITE = 0x08
 	};
 	};
 
 
+	/** Combineable set of bits that describe a set of physical GPU's. */
+	enum GpuDeviceFlags
+	{
+		/** 
+		 * Use the default set of devices. This may be the primary device or multiple devices. Cannot be used together with
+		 * other device flags. 
+		 */
+		GDF_DEFAULT = 0,
+		/** Use only the primary GPU. */
+		GDF_PRIMARY = 0x01,
+		/** Use the second GPU. */
+		GDF_GPU2 = 0x02,
+		/** Use the third GPU. */
+		GDF_GPU3 = 0x04,
+		/** Use the fourth GPU. */
+		GDF_GPU4 = 0x08,
+		/** Use the fifth GPU. */
+		GDF_GPU5 = 0x10
+	};
+
 	/** Type of parameter block usages. Signifies how often will parameter blocks be changed. */
 	/** Type of parameter block usages. Signifies how often will parameter blocks be changed. */
 	enum GpuParamBlockUsage
 	enum GpuParamBlockUsage
 	{
 	{

+ 54 - 26
Source/BansheeCore/Include/BsGpuBuffer.h

@@ -12,6 +12,43 @@ namespace BansheeEngine
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
+	/** 
+	 * Descriptor structure used for initialization of GpuBuffer. 
+	 * 
+	 * @note	
+	 * Be aware that due to some render API restrictions some of these settings cannot be used together, and if so you 
+	 * will receive an assert in debug mode.
+	 */
+	struct GPU_BUFFER_DESC
+	{
+		/** Number of elements in the buffer. */
+		UINT32 elementCount; 
+
+		/** 
+		 * Size of each individual element in the buffer, in bytes. Only needed if using non-standard buffer. If using
+		 * standard buffers element size is calculated from format and this must be zero.
+		 */
+		UINT32 elementSize;
+
+		/** Type of the buffer. Determines how is buffer seen by the GPU program and in what ways can it be used. */
+		GpuBufferType type;
+
+		/** Format if the data in the buffer. Only relevant for standard buffers, must be BF_UNKNOWN otherwise. */
+		GpuBufferFormat format;
+
+		/** Usage that tells the hardware how will be buffer be used. */
+		GpuBufferUsage usage;
+
+		/** When true allows the GPU to write to the resource. Must be enabled if buffer type is GBT_APPENDCONSUME. */
+		bool randomGpuWrite = false;
+
+		/**
+		 * When true binds a counter that can be used from a GPU program on the buffer. Can only be used in combination
+		 * with GBT_STRUCTURED and randomGpuWrite must be enabled.
+		 */
+		bool useCounter = false;
+	};
+
 	/** 
 	/** 
 	 * Information about a GpuBuffer. Allows core and non-core versions of GpuBuffer to share the same structure for 
 	 * Information about a GpuBuffer. Allows core and non-core versions of GpuBuffer to share the same structure for 
 	 * properties. 
 	 * properties. 
@@ -19,41 +56,36 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GpuBufferProperties
 	class BS_CORE_EXPORT GpuBufferProperties
 	{
 	{
 	public:
 	public:
-		GpuBufferProperties(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format,
-			GpuBufferUsage usage, bool randomGpuWrite, bool useCounter);
+		GpuBufferProperties(const GPU_BUFFER_DESC& desc);
 
 
 		/**
 		/**
 		 * Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created for the buffer, 
 		 * Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created for the buffer, 
 		 * and how is data read or modified in it.
 		 * and how is data read or modified in it.
 		 */
 		 */
-		GpuBufferType getType() const { return mType; }
+		GpuBufferType getType() const { return mDesc.type; }
 
 
 		/** Returns format used by the buffer. Only relevant for standard buffers. */
 		/** Returns format used by the buffer. Only relevant for standard buffers. */
-		GpuBufferFormat getFormat() const { return mFormat; }
+		GpuBufferFormat getFormat() const { return mDesc.format; }
 
 
 		/** Returns buffer usage which determines how are planning on updating the buffer contents. */
 		/** Returns buffer usage which determines how are planning on updating the buffer contents. */
-		GpuBufferUsage getUsage() const { return mUsage; }
+		GpuBufferUsage getUsage() const { return mDesc.usage; }
 
 
 		/** Return whether the buffer supports random reads and writes within the GPU programs. */
 		/** Return whether the buffer supports random reads and writes within the GPU programs. */
-		bool getRandomGpuWrite() const { return mRandomGpuWrite; }
+		bool getRandomGpuWrite() const { return mDesc.randomGpuWrite; }
 
 
 		/**	Returns whether the buffer supports counter use within GPU programs. */
 		/**	Returns whether the buffer supports counter use within GPU programs. */
-		bool getUseCounter() const { return mUseCounter; }
+		bool getUseCounter() const { return mDesc.useCounter; }
 
 
 		/**	Returns number of elements in the buffer. */
 		/**	Returns number of elements in the buffer. */
-		UINT32 getElementCount() const { return mElementCount; }
+		UINT32 getElementCount() const { return mDesc.elementCount; }
 
 
 		/**	Returns size of a single element in the buffer in bytes. */
 		/**	Returns size of a single element in the buffer in bytes. */
-		UINT32 getElementSize() const { return mElementSize; }
+		UINT32 getElementSize() const { return mDesc.elementSize; }
 
 
 	protected:
 	protected:
-		GpuBufferType mType;
-		GpuBufferUsage mUsage;
-		GpuBufferFormat mFormat;
-		bool mRandomGpuWrite;
-		bool mUseCounter;
-		UINT32 mElementCount;
-		UINT32 mElementSize;
+		friend class GpuBuffer;
+
+		GPU_BUFFER_DESC mDesc;
 	};
 	};
 
 
 	/**
 	/**
@@ -88,14 +120,12 @@ namespace BansheeEngine
 		static UINT32 getFormatSize(GpuBufferFormat format);
 		static UINT32 getFormatSize(GpuBufferFormat format);
 
 
 		/** @copydoc HardwareBufferManager::createGpuBuffer */
 		/** @copydoc HardwareBufferManager::createGpuBuffer */
-		static SPtr<GpuBuffer> create(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		static SPtr<GpuBuffer> create(const GPU_BUFFER_DESC& desc);
 
 
 	protected:
 	protected:
 		friend class HardwareBufferManager;
 		friend class HardwareBufferManager;
 
 
-		GpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format, GpuBufferUsage usage,
-			bool randomGpuWrite = false, bool useCounter = false);
+		GpuBuffer(const GPU_BUFFER_DESC& desc);
 
 
 		/** @copydoc CoreObject::createCore */
 		/** @copydoc CoreObject::createCore */
 		SPtr<CoreObjectCore> createCore() const override;
 		SPtr<CoreObjectCore> createCore() const override;
@@ -195,13 +225,11 @@ namespace BansheeEngine
 		 */
 		 */
 		static void releaseView(GpuBufferView* view);
 		static void releaseView(GpuBufferView* view);
 
 
-		/** @copydoc HardwareBufferManager::createGpuBuffer */
-		static SPtr<GpuBufferCore> create(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		/** @copydoc HardwareBufferCoreManager::createGpuBuffer */
+		static SPtr<GpuBufferCore> create(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 
 	protected:
 	protected:
-		GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format,
-			GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		GpuBufferCore(const GPU_BUFFER_DESC& desc, UINT32 deviceMask);
 
 
 		/** Creates an empty view for the current buffer. */
 		/** Creates an empty view for the current buffer. */
 		virtual GpuBufferView* createView() = 0;
 		virtual GpuBufferView* createView() = 0;
@@ -223,7 +251,7 @@ namespace BansheeEngine
 			UINT32 refCount;
 			UINT32 refCount;
 		};
 		};
 
 
-		UnorderedMap<GPU_BUFFER_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
+		UnorderedMap<GPU_BUFFER_VIEW_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
 		GpuBufferProperties mProperties;
 		GpuBufferProperties mProperties;
 	};
 	};
 
 

+ 6 - 6
Source/BansheeCore/Include/BsGpuBufferView.h

@@ -15,7 +15,7 @@ namespace BansheeEngine
 	 *
 	 *
 	 * @see		GpuBuffer
 	 * @see		GpuBuffer
 	 */
 	 */
-	struct BS_CORE_EXPORT GPU_BUFFER_DESC
+	struct BS_CORE_EXPORT GPU_BUFFER_VIEW_DESC
 	{
 	{
 		UINT32 firstElement;
 		UINT32 firstElement;
 		UINT32 elementWidth;
 		UINT32 elementWidth;
@@ -40,13 +40,13 @@ namespace BansheeEngine
 		class HashFunction
 		class HashFunction
 		{
 		{
 		public:
 		public:
-			size_t operator()(const GPU_BUFFER_DESC& key) const;
+			size_t operator()(const GPU_BUFFER_VIEW_DESC& key) const;
 		};
 		};
 
 
 		class EqualFunction
 		class EqualFunction
 		{
 		{
 		public:
 		public:
-			bool operator()(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const;
+			bool operator()(const GPU_BUFFER_VIEW_DESC& a, const GPU_BUFFER_VIEW_DESC& b) const;
 		};
 		};
 
 
 		GpuBufferView();
 		GpuBufferView();
@@ -56,10 +56,10 @@ namespace BansheeEngine
 		 * Initializes the view with the specified buffer and a set of parameters describing the view to create. Must be 
 		 * Initializes the view with the specified buffer and a set of parameters describing the view to create. Must be 
 		 * called right after construction.
 		 * called right after construction.
 		 */
 		 */
-		virtual void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_DESC& desc);
+		virtual void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_VIEW_DESC& desc);
 
 
 		/** Returns a descriptor structure used for creating the view. */
 		/** Returns a descriptor structure used for creating the view. */
-		const GPU_BUFFER_DESC& getDesc() const { return mDesc; }
+		const GPU_BUFFER_VIEW_DESC& getDesc() const { return mDesc; }
 
 
 		/**	Returns the buffer this view was created for. */
 		/**	Returns the buffer this view was created for. */
 		SPtr<GpuBufferCore> getBuffer() const { return mBuffer; }
 		SPtr<GpuBufferCore> getBuffer() const { return mBuffer; }
@@ -80,7 +80,7 @@ namespace BansheeEngine
 		GpuViewUsage getUsage() const { return mDesc.usage; }
 		GpuViewUsage getUsage() const { return mDesc.usage; }
 
 
 	protected:
 	protected:
-		GPU_BUFFER_DESC mDesc;
+		GPU_BUFFER_VIEW_DESC mDesc;
 		SPtr<GpuBufferCore> mBuffer;
 		SPtr<GpuBufferCore> mBuffer;
 	};
 	};
 
 

+ 9 - 21
Source/BansheeCore/Include/BsHardwareBufferManager.h

@@ -7,10 +7,12 @@
 #include "BsVertexBuffer.h"
 #include "BsVertexBuffer.h"
 #include "BsIndexBuffer.h"
 #include "BsIndexBuffer.h"
 #include "BsVertexDeclaration.h"
 #include "BsVertexDeclaration.h"
-#include "BsGpuParams.h"
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	struct GPU_BUFFER_DESC;
+	struct GPU_PARAMS_DESC;
+
 	/** @addtogroup RenderAPI-Internal
 	/** @addtogroup RenderAPI-Internal
 	 *  @{
 	 *  @{
 	 */
 	 */
@@ -60,24 +62,11 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * Creates a generic buffer that can be passed as a parameter to a GPU program. This type of buffer can hold various 
 		 * Creates a generic buffer that can be passed as a parameter to a GPU program. This type of buffer can hold various 
-		 * type of data and can be used for various purposes. See "GpuBufferType" for explanation of different buffer types.
-		 *
-		 * @param[in]	elementCount  	Number of elements in the buffer. 
-		 * @param[in]	elementSize   	Size of each individual element in the buffer, in bytes. Only needed if using
-		 *								non-standard buffer. If using standard buffer element size is calculated from
-		 *								format.
-		 * @param[in]	type		  	Type of the buffer.
-		 * @param[in]	format			Format if the data in the buffer. Only relevant for standard buffers.
-		 * @param[in]	usage		  	Usage that tells the hardware how will be buffer be used. 
-		 * @param[in]	randomGpuWrite	(optional) Allows the GPU to write to the resource.
-		 * @param[in]	useCounter	  	(optional) Binds a counter that can be used from a GPU program on the buffer.
+		 * type of data and can be used for various purposes. See GpuBufferType for explanation of different buffer types.
 		 *
 		 *
-		 * @note	
-		 * Be aware that due to some render API restrictions some of these settings cannot be used together, and if so you 
-		 * will receive an assert in debug mode.
+		 * @param[in]	desc  	Description of the buffer to create.
 		 */
 		 */
-		SPtr<GpuBuffer> createGpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		SPtr<GpuBuffer> createGpuBuffer(const GPU_BUFFER_DESC& desc);
 
 
 		/** Creates a new vertex declaration from a list of vertex elements. */
 		/** Creates a new vertex declaration from a list of vertex elements. */
 		SPtr<VertexDeclaration> createVertexDeclaration(const SPtr<VertexDataDesc>& desc);
 		SPtr<VertexDeclaration> createVertexDeclaration(const SPtr<VertexDataDesc>& desc);
@@ -114,8 +103,7 @@ namespace BansheeEngine
 			GpuParamBlockUsage usage = GPBU_DYNAMIC);
 			GpuParamBlockUsage usage = GPBU_DYNAMIC);
 
 
 		/** @copydoc HardwareBufferManager::createGpuBuffer */
 		/** @copydoc HardwareBufferManager::createGpuBuffer */
-		SPtr<GpuBufferCore> createGpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		SPtr<GpuBufferCore> createGpuBuffer(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
 
 
 		/** @copydoc HardwareBufferManager::createGpuParams */
 		/** @copydoc HardwareBufferManager::createGpuParams */
 		SPtr<GpuParamsCore> createGpuParams(const GPU_PARAMS_DESC& desc);
 		SPtr<GpuParamsCore> createGpuParams(const GPU_PARAMS_DESC& desc);
@@ -143,8 +131,8 @@ namespace BansheeEngine
 			GpuParamBlockUsage usage = GPBU_DYNAMIC) = 0;
 			GpuParamBlockUsage usage = GPBU_DYNAMIC) = 0;
 
 
 		/** @copydoc createGpuBuffer */
 		/** @copydoc createGpuBuffer */
-		virtual SPtr<GpuBufferCore> createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false) = 0;
+		virtual SPtr<GpuBufferCore> createGpuBufferInternal(const GPU_BUFFER_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
 
 
 		/** @copydoc createVertexDeclaration */
 		/** @copydoc createVertexDeclaration */
 		virtual SPtr<VertexDeclarationCore> createVertexDeclarationInternal(const List<VertexElement>& elements);
 		virtual SPtr<VertexDeclarationCore> createVertexDeclarationInternal(const List<VertexElement>& elements);

+ 14 - 24
Source/BansheeCore/Source/BsGpuBuffer.cpp

@@ -7,18 +7,15 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	GpuBufferProperties::GpuBufferProperties(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-		GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
-		: mType(type), mUsage(usage), mFormat(format), mRandomGpuWrite(randomGpuWrite), mUseCounter(useCounter)
-		, mElementCount(elementCount), mElementSize(elementSize)
+	GpuBufferProperties::GpuBufferProperties(const GPU_BUFFER_DESC& desc)
+		: mDesc(desc)
 	{
 	{
-		if(type == GBT_STANDARD)
-			mElementSize = GpuBuffer::getFormatSize(format);
+		if(mDesc.type == GBT_STANDARD)
+			mDesc.elementSize = GpuBuffer::getFormatSize(mDesc.format);
 	}
 	}
 
 
-	GpuBufferCore::GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format, 
-		GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
-		: mProperties(elementCount, elementSize, type, format, usage, randomGpuWrite, useCounter)
+	GpuBufferCore::GpuBufferCore(const GPU_BUFFER_DESC& desc, UINT32 deviceMask)
+		: mProperties(desc)
 	{
 	{
 	}
 	}
 
 
@@ -44,7 +41,7 @@ namespace BansheeEngine
 	{
 	{
 		const auto& props = buffer->getProperties();
 		const auto& props = buffer->getProperties();
 
 
-		GPU_BUFFER_DESC key;
+		GPU_BUFFER_VIEW_DESC key;
 		key.firstElement = firstElement;
 		key.firstElement = firstElement;
 		key.elementWidth = props.getElementSize();
 		key.elementWidth = props.getElementSize();
 		key.numElements = numElements;
 		key.numElements = numElements;
@@ -89,16 +86,13 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	SPtr<GpuBufferCore> GpuBufferCore::create(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
-		GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
+	SPtr<GpuBufferCore> GpuBufferCore::create(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask)
 	{
 	{
-		return HardwareBufferCoreManager::instance().createGpuBuffer(elementCount, 
-			elementSize, type, format, usage, randomGpuWrite, useCounter);
+		return HardwareBufferCoreManager::instance().createGpuBuffer(desc, deviceMask);
 	}
 	}
 
 
-	GpuBuffer::GpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format, 
-		GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
-		:mProperties(elementCount, elementSize, type, format, usage, randomGpuWrite, useCounter)
+	GpuBuffer::GpuBuffer(const GPU_BUFFER_DESC& desc)
+		:mProperties(desc)
 	{  
 	{  
 	}
 	}
 
 
@@ -109,9 +103,7 @@ namespace BansheeEngine
 
 
 	SPtr<CoreObjectCore> GpuBuffer::createCore() const
 	SPtr<CoreObjectCore> GpuBuffer::createCore() const
 	{
 	{
-		return HardwareBufferCoreManager::instance().createGpuBufferInternal(mProperties.getElementCount(), 
-			mProperties.getElementSize(), mProperties.getType(), mProperties.getFormat(), mProperties.getUsage(), 
-			mProperties.getRandomGpuWrite(), mProperties.getUseCounter());
+		return HardwareBufferCoreManager::instance().createGpuBufferInternal(mProperties.mDesc);
 	}
 	}
 
 
 	UINT32 GpuBuffer::getFormatSize(GpuBufferFormat format)
 	UINT32 GpuBuffer::getFormatSize(GpuBufferFormat format)
@@ -164,10 +156,8 @@ namespace BansheeEngine
 		return lookup[(UINT32)format];
 		return lookup[(UINT32)format];
 	}
 	}
 
 
-	SPtr<GpuBuffer> GpuBuffer::create(UINT32 elementCount, UINT32 elementSize, GpuBufferType type,
-		GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
+	SPtr<GpuBuffer> GpuBuffer::create(const GPU_BUFFER_DESC& desc)
 	{
 	{
-		return HardwareBufferManager::instance().createGpuBuffer(elementCount, elementSize, type, format,
-			usage, randomGpuWrite, useCounter);
+		return HardwareBufferManager::instance().createGpuBuffer(desc);
 	}
 	}
 }
 }

+ 3 - 3
Source/BansheeCore/Source/BsGpuBufferView.cpp

@@ -4,7 +4,7 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	size_t GpuBufferView::HashFunction::operator()(const GPU_BUFFER_DESC& key) const
+	size_t GpuBufferView::HashFunction::operator()(const GPU_BUFFER_VIEW_DESC& key) const
 	{
 	{
 		size_t seed = 0;
 		size_t seed = 0;
 		hash_combine(seed, key.elementWidth);
 		hash_combine(seed, key.elementWidth);
@@ -18,7 +18,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool GpuBufferView::EqualFunction::operator()
 	bool GpuBufferView::EqualFunction::operator()
-		(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const
+		(const GPU_BUFFER_VIEW_DESC& a, const GPU_BUFFER_VIEW_DESC& b) const
 	{
 	{
 		return a.elementWidth == b.elementWidth && a.firstElement == b.firstElement && a.numElements == b.numElements 
 		return a.elementWidth == b.elementWidth && a.firstElement == b.firstElement && a.numElements == b.numElements 
 			&& a.useCounter == b.useCounter && a.usage == b.usage && a.format == b.format;
 			&& a.useCounter == b.useCounter && a.usage == b.usage && a.format == b.format;
@@ -34,7 +34,7 @@ namespace BansheeEngine
 
 
 	}
 	}
 
 
-	void GpuBufferView::initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_DESC& desc)
+	void GpuBufferView::initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_VIEW_DESC& desc)
 	{
 	{
 		mBuffer = buffer;
 		mBuffer = buffer;
 		mDesc = desc;
 		mDesc = desc;

+ 6 - 8
Source/BansheeCore/Source/BsHardwareBufferManager.cpp

@@ -6,6 +6,7 @@
 #include "BsVertexDeclaration.h"
 #include "BsVertexDeclaration.h"
 #include "BsGpuParamBlockBuffer.h"
 #include "BsGpuParamBlockBuffer.h"
 #include "BsVertexDataDesc.h"
 #include "BsVertexDataDesc.h"
+#include "BsGpuParams.h"
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
@@ -57,11 +58,9 @@ namespace BansheeEngine
 		return paramBlockPtr;
 		return paramBlockPtr;
 	}
 	}
 
 
-	SPtr<GpuBuffer> HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
-		GpuBufferType type, GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
+	SPtr<GpuBuffer> HardwareBufferManager::createGpuBuffer(const GPU_BUFFER_DESC& desc)
 	{
 	{
-		SPtr<GpuBuffer> gbuf = bs_core_ptr<GpuBuffer>(new (bs_alloc<GpuBuffer>()) 
-			GpuBuffer(elementCount, elementSize, type, format, usage, randomGpuWrite, useCounter));
+		SPtr<GpuBuffer> gbuf = bs_core_ptr<GpuBuffer>(new (bs_alloc<GpuBuffer>()) GpuBuffer(desc));
 		gbuf->_setThisPtr(gbuf);
 		gbuf->_setThisPtr(gbuf);
 		gbuf->initialize();
 		gbuf->initialize();
 
 
@@ -129,11 +128,10 @@ namespace BansheeEngine
 		return paramBlockPtr;
 		return paramBlockPtr;
 	}
 	}
 
 
-	SPtr<GpuBufferCore> HardwareBufferCoreManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize,
-		GpuBufferType type, GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
+	SPtr<GpuBufferCore> HardwareBufferCoreManager::createGpuBuffer(const GPU_BUFFER_DESC& desc,
+		GpuDeviceFlags deviceMask)
 	{
 	{
-		SPtr<GpuBufferCore> gbuf = createGpuBufferInternal(elementCount, elementSize, type, format, usage, randomGpuWrite, 
-			useCounter);
+		SPtr<GpuBufferCore> gbuf = createGpuBufferInternal(desc, deviceMask);
 		gbuf->initialize();
 		gbuf->initialize();
 
 
 		return gbuf;
 		return gbuf;

+ 1 - 2
Source/BansheeD3D11RenderAPI/Include/BsD3D11GpuBuffer.h

@@ -46,8 +46,7 @@ namespace BansheeEngine
 	protected:
 	protected:
 		friend class D3D11HardwareBufferCoreManager;
 		friend class D3D11HardwareBufferCoreManager;
 
 
-		D3D11GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format, 
-			GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		D3D11GpuBufferCore(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask);
 
 
 		/** @copydoc GpuBufferCore::createView */
 		/** @copydoc GpuBufferCore::createView */
 		GpuBufferView* createView() override;
 		GpuBufferView* createView() override;

+ 1 - 1
Source/BansheeD3D11RenderAPI/Include/BsD3D11GpuBufferView.h

@@ -22,7 +22,7 @@ namespace BansheeEngine
 		virtual ~D3D11GpuBufferView();
 		virtual ~D3D11GpuBufferView();
 
 
 		/** @copydoc GpuBufferView::initialize */
 		/** @copydoc GpuBufferView::initialize */
-		void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_DESC& desc) override;
+		void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_VIEW_DESC& desc) override;
 
 
 		/** Returns the DX11 shader resource view object for the buffer. */
 		/** Returns the DX11 shader resource view object for the buffer. */
 		ID3D11ShaderResourceView* getSRV() const { return mSRV; }
 		ID3D11ShaderResourceView* getSRV() const { return mSRV; }

+ 2 - 2
Source/BansheeD3D11RenderAPI/Include/BsD3D11HardwareBufferManager.h

@@ -31,8 +31,8 @@ namespace BansheeEngine
 			GpuParamBlockUsage usage = GPBU_DYNAMIC) override;
 			GpuParamBlockUsage usage = GPBU_DYNAMIC) override;
 
 
 		/** @copydoc HardwareBufferCoreManager::createGpuBufferInternal */
 		/** @copydoc HardwareBufferCoreManager::createGpuBufferInternal */
-		SPtr<GpuBufferCore> createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false) override;
+		SPtr<GpuBufferCore> createGpuBufferInternal(const GPU_BUFFER_DESC& desc,
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
 
 
 		D3D11Device& mDevice;
 		D3D11Device& mDevice;
 	};
 	};

+ 7 - 6
Source/BansheeD3D11RenderAPI/Source/BsD3D11GpuBuffer.cpp

@@ -11,14 +11,15 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	D3D11GpuBufferCore::D3D11GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-		GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
-		: GpuBufferCore(elementCount, elementSize, type, format, usage, randomGpuWrite, useCounter), mBuffer(nullptr)
+	D3D11GpuBufferCore::D3D11GpuBufferCore(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask)
+		: GpuBufferCore(desc, deviceMask), mBuffer(nullptr)
 	{
 	{
-		if (type != GBT_STANDARD)
-			assert(format == BF_UNKNOWN && "Format must be set to BF_UNKNOWN when using non-standard buffers");
+		if (desc.type != GBT_STANDARD)
+			assert(desc.format == BF_UNKNOWN && "Format must be set to BF_UNKNOWN when using non-standard buffers");
 		else
 		else
-			assert(elementSize == 0 && "No element size can be provided for standard buffer. Size is determined from format.");
+			assert(desc.elementSize == 0 && "No element size can be provided for standard buffer. Size is determined from format.");
+
+		assert((deviceMask == GDF_DEFAULT || deviceMask == GDF_PRIMARY) && "Multiple GPUs not supported natively on DirectX 11.");
 	}
 	}
 
 
 	D3D11GpuBufferCore::~D3D11GpuBufferCore()
 	D3D11GpuBufferCore::~D3D11GpuBufferCore()

+ 1 - 1
Source/BansheeD3D11RenderAPI/Source/BsD3D11GpuBufferView.cpp

@@ -23,7 +23,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_ResourceView);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_ResourceView);
 	}
 	}
 
 
-	void D3D11GpuBufferView::initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_DESC& desc)
+	void D3D11GpuBufferView::initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_VIEW_DESC& desc)
 	{
 	{
 		GpuBufferView::initialize(buffer, desc);
 		GpuBufferView::initialize(buffer, desc);
 
 

+ 3 - 3
Source/BansheeD3D11RenderAPI/Source/BsD3D11HardwareBufferManager.cpp

@@ -41,11 +41,11 @@ namespace BansheeEngine
 		return paramBlockBufferPtr;
 		return paramBlockBufferPtr;
 	}
 	}
 
 
-	SPtr<GpuBufferCore> D3D11HardwareBufferCoreManager::createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize,
-		GpuBufferType type, GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
+	SPtr<GpuBufferCore> D3D11HardwareBufferCoreManager::createGpuBufferInternal(const GPU_BUFFER_DESC& desc,
+		GpuDeviceFlags deviceMask)
 	{
 	{
 		D3D11GpuBufferCore* buffer = new (bs_alloc<D3D11GpuBufferCore>()) 
 		D3D11GpuBufferCore* buffer = new (bs_alloc<D3D11GpuBufferCore>()) 
-			D3D11GpuBufferCore(elementCount, elementSize, type, format, usage, randomGpuWrite, useCounter);
+			D3D11GpuBufferCore(desc, deviceMask);
 
 
 		SPtr<D3D11GpuBufferCore> bufferPtr = bs_shared_ptr<D3D11GpuBufferCore>(buffer);
 		SPtr<D3D11GpuBufferCore> bufferPtr = bs_shared_ptr<D3D11GpuBufferCore>(buffer);
 		bufferPtr->_setThisPtr(bufferPtr);
 		bufferPtr->_setThisPtr(bufferPtr);

+ 8 - 1
Source/BansheeEngine/Source/BsRenderable.cpp

@@ -205,7 +205,14 @@ namespace BansheeEngine
 
 
 			if (numBones > 0)
 			if (numBones > 0)
 			{
 			{
-				SPtr<GpuBufferCore> buffer = GpuBufferCore::create(numBones * 3, 0, GBT_STANDARD, BF_32X4F, GBU_DYNAMIC);
+				GPU_BUFFER_DESC desc;
+				desc.elementCount = numBones * 3;
+				desc.elementSize = 0;
+				desc.type = GBT_STANDARD;
+				desc.format = BF_32X4F;
+				desc.usage = GBU_DYNAMIC;
+
+				SPtr<GpuBufferCore> buffer = GpuBufferCore::create(desc);
 				UINT8* dest = (UINT8*)buffer->lock(0, numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
 				UINT8* dest = (UINT8*)buffer->lock(0, numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
 
 
 				// Initialize bone transforms to identity, so the object renders properly even if no animation is animating it
 				// Initialize bone transforms to identity, so the object renders properly even if no animation is animating it

+ 1 - 2
Source/BansheeGLRenderAPI/Include/BsGLGpuBuffer.h

@@ -50,8 +50,7 @@ namespace BansheeEngine
 	protected:
 	protected:
 		friend class GLHardwareBufferCoreManager;
 		friend class GLHardwareBufferCoreManager;
 
 
-		GLGpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format,
-			GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+		GLGpuBufferCore(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask);
 
 
 		/** @copydoc GpuBufferCore::initialize */
 		/** @copydoc GpuBufferCore::initialize */
 		void initialize() override;
 		void initialize() override;

+ 4 - 3
Source/BansheeGLRenderAPI/Include/BsGLHardwareBufferManager.h

@@ -30,11 +30,12 @@ namespace BansheeEngine
 		SPtr<IndexBufferCore> createIndexBufferInternal(IndexType itype, UINT32 numIndices, GpuBufferUsage usage) override;
 		SPtr<IndexBufferCore> createIndexBufferInternal(IndexType itype, UINT32 numIndices, GpuBufferUsage usage) override;
 
 
 		/** @copydoc HardwareBufferCoreManager::createGpuParamBlockBufferInternal */
 		/** @copydoc HardwareBufferCoreManager::createGpuParamBlockBufferInternal */
-		SPtr<GpuParamBlockBufferCore> createGpuParamBlockBufferInternal(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC) override;
+		SPtr<GpuParamBlockBufferCore> createGpuParamBlockBufferInternal(UINT32 size, 
+			GpuParamBlockUsage usage = GPBU_DYNAMIC) override;
 
 
 		/** @copydoc HardwareBufferCoreManager::createGpuBufferInternal */
 		/** @copydoc HardwareBufferCoreManager::createGpuBufferInternal */
-		SPtr<GpuBufferCore> createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
-			GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false) override;
+		SPtr<GpuBufferCore> createGpuBufferInternal(const GPU_BUFFER_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
     };
     };
 
 
 	/** @} */
 	/** @} */

+ 7 - 6
Source/BansheeGLRenderAPI/Source/BsGLGpuBuffer.cpp

@@ -8,20 +8,21 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	GLGpuBufferCore::GLGpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferFormat format,
-		GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
-		: GpuBufferCore(elementCount, elementSize, type, format, usage, randomGpuWrite, useCounter), mTextureID(0), mFormat(0)
+	GLGpuBufferCore::GLGpuBufferCore(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask)
+		: GpuBufferCore(desc, deviceMask), mTextureID(0), mFormat(0)
 	{
 	{
-		if(type != GBT_STANDARD)
+		if(desc.type != GBT_STANDARD)
 			LOGERR("Only standard buffers are support on OpenGL.");
 			LOGERR("Only standard buffers are support on OpenGL.");
 
 
-		if (useCounter)
+		if (desc.useCounter)
 			LOGERR("Buffer counters not supported on OpenGL.");
 			LOGERR("Buffer counters not supported on OpenGL.");
 
 
+		assert((deviceMask == GDF_DEFAULT || deviceMask == GDF_PRIMARY) && "Multiple GPUs not supported natively on OpenGL.");
+
 		// Note: Implement OpenGL shader storage buffers, append/consume buffers, transform feedback buffers, 
 		// Note: Implement OpenGL shader storage buffers, append/consume buffers, transform feedback buffers, 
 		// indirect argument buffers and counter buffers
 		// indirect argument buffers and counter buffers
 
 
-		mFormat = GLPixelUtil::getBufferFormat(format);
+		mFormat = GLPixelUtil::getBufferFormat(desc.format);
 	}
 	}
 
 
 	GLGpuBufferCore::~GLGpuBufferCore()
 	GLGpuBufferCore::~GLGpuBufferCore()

+ 3 - 4
Source/BansheeGLRenderAPI/Source/BsGLHardwareBufferManager.cpp

@@ -37,11 +37,10 @@ namespace BansheeEngine
 		return paramBlockBufferPtr;
 		return paramBlockBufferPtr;
 	}
 	}
 
 
-	SPtr<GpuBufferCore> GLHardwareBufferCoreManager::createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize,
-		GpuBufferType type, GpuBufferFormat format, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
+	SPtr<GpuBufferCore> GLHardwareBufferCoreManager::createGpuBufferInternal(const GPU_BUFFER_DESC& desc,
+		GpuDeviceFlags deviceMask)
 	{
 	{
-		GLGpuBufferCore* buffer = new (bs_alloc<GLGpuBufferCore>()) GLGpuBufferCore(elementCount, elementSize, type, format,
-			usage, randomGpuWrite, useCounter);
+		GLGpuBufferCore* buffer = new (bs_alloc<GLGpuBufferCore>()) GLGpuBufferCore(desc, deviceMask);
 
 
 		SPtr<GpuBufferCore> bufferPtr = bs_shared_ptr<GLGpuBufferCore>(buffer);
 		SPtr<GpuBufferCore> bufferPtr = bs_shared_ptr<GLGpuBufferCore>(buffer);
 		bufferPtr->_setThisPtr(bufferPtr);
 		bufferPtr->_setThisPtr(bufferPtr);