2
0
Эх сурвалжийг харах

(WIP) Adding command buffer support to OpenGL

BearishSun 9 жил өмнө
parent
commit
c6e8badad9

+ 0 - 34
Source/BansheeCore/Include/BsCommandBuffer.h

@@ -33,38 +33,4 @@ namespace BansheeEngine
 	};
 
 	/** @} */
-
-	/** @addtogroup RenderAPI-Internal
-	 *  @{
-	 */
-
-	/**
-	 * Command buffer implementation for render API's that do not support multi-threaded command generation. Instead all
-	 * commands are stored in an internal buffer, and then sent to the actual render API when the buffer is executed.
-	 */
-	class BS_CORE_EXPORT SimpleCommandBuffer : CommandBuffer
-	{
-	public:
-		/** Registers a new command in the command buffer. */
-		void queueCommand(const std::function<void()> command);
-
-		/** Appends all commands from the secondary buffer into this command buffer. */
-		void appendSecondary(const SPtr<SimpleCommandBuffer>& secondaryBuffer);
-
-		/** Executes all commands in the command buffer. Not supported on secondary buffer. */
-		void executeCommands();
-
-		/** Removes all commands from the command buffer. */
-		void clear();
-
-	private:
-		friend class CommandBufferManager;
-
-		SimpleCommandBuffer(CommandBufferType type, UINT32 deviceIdx, UINT32 syncMask, bool secondary);
-
-		UINT32 mDeviceIdx;
-		Vector<std::function<void()>> mCommands;
-	};
-
-	/** @} */
 }

+ 1 - 1
Source/BansheeCore/Include/BsGpuParams.h

@@ -57,7 +57,7 @@ namespace BansheeEngine
 		GpuParamsBase& operator=(const GpuParamsBase& rhs) = delete;
 
 		/** Returns a description of all stored parameters. */
-		const GpuParamDesc& getParamDesc() const { return *mParamDesc; }
+		SPtr<GpuParamDesc> getParamDesc() const { return mParamDesc; }
 
 		/**
 		 * Returns the size of a data parameter with the specified name, in bytes. Returns 0 if such parameter doesn't exist.

+ 189 - 153
Source/BansheeCore/Include/BsRenderAPI.h

@@ -24,8 +24,8 @@ namespace BansheeEngine
 	class RenderAPIInfo;
 
 	/**
-	 * Version of the render API interface usable from the sim thread. All the commands	get queued on the accessor provided
-	 * to each method and will be executed on the core thread later.
+	 * Provides access to RenderAPICore from the simulation thread. All the commands get queued on the accessor provided
+	 * to each method and get be executed on the core thread later.
 	 *
 	 * @see		RenderAPICore
 	 *
@@ -125,27 +125,6 @@ namespace BansheeEngine
 		 */
 		static void setDrawOperation(CoreAccessor& accessor, DrawOperationType op);
 
-		/** 
-		 * @copydoc RenderAPICore::setClipPlanes() 
-		 *
-		 * @param[in]	accessor	Accessor on which will this command be queued for execution.
-		 */
-		static void setClipPlanes(CoreAccessor& accessor, const PlaneList& clipPlanes);
-
-		/** 
-		 * @copydoc RenderAPICore::addClipPlane(const Plane&) 
-		 *
-		 * @param[in]	accessor	Accessor on which will this command be queued for execution.
-		 */
-		static void addClipPlane(CoreAccessor& accessor, const Plane& p);
-
-		/** 
-		 * @copydoc RenderAPICore::resetClipPlanes() 
-		 *
-		 * @param[in]	accessor	Accessor on which will this command be queued for execution.
-		 */
-		static void resetClipPlanes(CoreAccessor& accessor);
-
 		/** 
 		 * @copydoc RenderAPICore::setScissorRect() 
 		 *
@@ -299,11 +278,22 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/** 
+	 * Primary command buffer. Always available as long as RenderAPI is initialized. 
+	 * 
+	 * @note	Accessible on core thread only, or rendering worker threads if externally synchronized.
+	 */
+	extern BS_CORE_EXPORT SPtr<CommandBuffer> gMainCommandBuffer;
+
 	/**
-	 * Render system provides base functionality for a rendering API like DirectX or OpenGL. Most of the class is abstract
-	 * and specific subclass for each rendering API needs to be implemented.
+	 * Provides low-level API access to rendering commands (internally wrapping DirectX/OpenGL/Vulkan or similar). 
+	 * 
+	 * Methods that accept a CommandBuffer parameter get queued in the provided command buffer, and don't get executed until
+	 * executeCommands() method is called. User is allowed to populate command buffers from non-core threads, but they all 
+	 * must get executed from the core thread.
 	 *
-	 * @note	Core thread only unless specifically noted otherwise on per-method basis.
+	 * @note	Accessible on any thread for methods accepting a CommandBuffer. Otherwise core thread unless specifically
+	 *			noted otherwise on per-method basis.
 	 */
 	class BS_CORE_EXPORT RenderAPICore : public Module<RenderAPICore>
 	{
@@ -332,38 +322,50 @@ namespace BansheeEngine
 		 * @param[in]	gptype			Determines to which GPU program slot to bind the sampler state.
 		 * @param[in]	texUnit			Texture unit index to bind the state to.
 		 * @param[in]	samplerState	Sampler state to bind, or null to unbind.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer
+		 *								must support graphics or compute operations.
 		 *
 		 * @see		SamplerState
 		 */
-		virtual void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SPtr<SamplerStateCore>& samplerState) = 0;
+		virtual void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SPtr<SamplerStateCore>& samplerState, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets a blend state used for all active render targets.
 		 *
-		 * @param[in]	blendState	Blend state to bind, or null to unbind.
+		 * @param[in]	blendState		Blend state to bind, or null to unbind.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer
+		 *								must support graphics operations.
 		 *
 		 * @see		BlendState
 		 */
-		virtual void setBlendState(const SPtr<BlendStateCore>& blendState) = 0;
+		virtual void setBlendState(const SPtr<BlendStateCore>& blendState, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets a state that controls various rasterizer options. 
 		 *
 		 * @param[in]	rasterizerState		Rasterizer state to bind, or null to unbind.
+		 * @param[in]	commandBuffer		Buffer whose subsequent commands will be affected by the state change. Buffer
+		 *									must support graphics operations.
 		 *
 		 * @see		RasterizerState
 		 */
-		virtual void setRasterizerState(const SPtr<RasterizerStateCore>& rasterizerState) = 0;
+		virtual void setRasterizerState(const SPtr<RasterizerStateCore>& rasterizerState, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets a state that controls depth & stencil buffer options.
 		 *
-		 * @param[in]	depthStencilState		Depth-stencil state to bind, or null to unbind.
-		 * @param[in]	stencilRefValue			Stencil reference value to be used for stencil comparisons, if enabled.
+		 * @param[in]	depthStencilState	Depth-stencil state to bind, or null to unbind.
+		 * @param[in]	stencilRefValue		Stencil reference value to be used for stencil comparisons, if enabled.
+		 * @param[in]	commandBuffer		Buffer whose subsequent commands will be affected by the state change. Buffer
+		 *									must support graphics operations.
 		 *
 		 * @see		DepthStencilState
 		 */
-		virtual void setDepthStencilState(const SPtr<DepthStencilStateCore>& depthStencilState, UINT32 stencilRefValue) = 0;
+		virtual void setDepthStencilState(const SPtr<DepthStencilStateCore>& depthStencilState, UINT32 stencilRefValue,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Binds a texture to the pipeline for the specified GPU program type at the specified slot. If the slot matches 
@@ -372,8 +374,11 @@ namespace BansheeEngine
 		 * @param[in]	gptype			Determines to which GPU program slot to bind the texture.
 		 * @param[in]	texUnit			Texture unit index to bind the texture to.
 		 * @param[in]	texture			Texture to bind.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics or compute operations.
 		 */
-		virtual void setTexture(GpuProgramType gptype, UINT16 texUnit, const SPtr<TextureCore>& texture) = 0;
+		virtual void setTexture(GpuProgramType gptype, UINT16 texUnit, const SPtr<TextureCore>& texture,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**	
 		 * Binds a texture that can be used for random load/store operations from a GPU program. 
@@ -382,70 +387,125 @@ namespace BansheeEngine
 		 * @param[in]	texUnit			Texture unit index to bind the texture to.
 		 * @param[in]	texture			Texture to bind.
 		 * @param[in]	surface			Determines which surface of the texture to bind.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics or compute operations.
 		 */
 		virtual void setLoadStoreTexture(GpuProgramType gptype, UINT16 texUnit, const SPtr<TextureCore>& texture, 
-			const TextureSurface& surface) = 0;
+			const TextureSurface& surface, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Binds a buffer that can be used for read or write operations on the GPU.
 		 *
-		 * @param[in]	gptype		Determines to which GPU program slot to bind the buffer.
-		 * @param[in]	unit		GPU program unit index to bind the buffer to.
-		 * @param[in]	buffer		Buffer to bind.
-		 * @param[in]	loadStore	If true the buffer will be bound with support for unordered reads and writes, otherwise
-		 *							it will only be bound for reads.
+		 * @param[in]	gptype			Determines to which GPU program slot to bind the buffer.
+		 * @param[in]	unit			GPU program unit index to bind the buffer to.
+		 * @param[in]	buffer			Buffer to bind.
+		 * @param[in]	loadStore		If true the buffer will be bound with support for unordered reads and writes, 
+		 *								otherwise it will only be bound for reads.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics or compute operations.
 		 */
 		virtual void setBuffer(GpuProgramType gptype, UINT16 unit, const SPtr<GpuBufferCore>& buffer, 
-			bool loadStore = false) = 0;
+			bool loadStore = false, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Signals that rendering for a specific viewport has started. Any draw calls need to be called between beginFrame()
 		 * and endFrame(). 
+		 * 
+		 * @param[in]	commandBuffer	Command buffer in which to start rendering. Buffer must support graphics
+		 *								operations.
 		 */
-		virtual void beginFrame() = 0;
+		virtual void beginFrame(const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 		
-		/** Ends that rendering to a specific viewport has ended. */
-		virtual void endFrame() = 0;
+		/** 
+		 * Ends that rendering to a specific viewport has ended. 
+		 *
+		 * @param[in]	commandBuffer	Command buffer in which to start rendering. Buffer must support graphics
+		 *								operations.
+		 */
+		virtual void endFrame(const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets the active viewport that will be used for all render operations.
 		 *
-		 * @param[in]	area	Area of the viewport, in normalized ([0,1] range) coordinates.
+		 * @param[in]	area			Area of the viewport, in normalized ([0,1] range) coordinates.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics operations.
 		 */
-		virtual void setViewport(const Rect2& area) = 0;
+		virtual void setViewport(const Rect2& area, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
+
+		/**
+		 * Allows you to set up a region in which rendering can take place. Coordinates are in pixels. No rendering will be
+		 * done to render target pixels outside of the provided region.
+		 *
+		 * @param[in]	left			Left border of the scissor rectangle, in pixels.
+		 * @param[in]	top				Top border of the scissor rectangle, in pixels.
+		 * @param[in]	right			Right border of the scissor rectangle, in pixels.
+		 * @param[in]	bottom			Bottom border of the scissor rectangle, in pixels.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics operations.
+		 */
+		virtual void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets the provided vertex buffers starting at the specified source index.	Set buffer to nullptr to clear the 
 		 * buffer at the specified index.
 		 *
-		 * @param[in]	index		Index at which to start binding the vertex buffers.
-		 * @param[in]	buffers		A list of buffers to bind to the pipeline.
-		 * @param[in]	numBuffers	Number of buffers in the @p buffers list.
+		 * @param[in]	index			Index at which to start binding the vertex buffers.
+		 * @param[in]	buffers			A list of buffers to bind to the pipeline.
+		 * @param[in]	numBuffers		Number of buffers in the @p buffers list.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics operations.
 		 */
-		virtual void setVertexBuffers(UINT32 index, SPtr<VertexBufferCore>* buffers, UINT32 numBuffers) = 0;
+		virtual void setVertexBuffers(UINT32 index, SPtr<VertexBufferCore>* buffers, UINT32 numBuffers, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets an index buffer to use when drawing. Indices in an index buffer reference vertices in the vertex buffer, 
 		 * which increases cache coherency and reduces the size of vertex buffers by eliminating duplicate data.
 		 *
-		 * @param[in]	buffer	Index buffer to bind, null to unbine.
+		 * @param[in]	buffer			Index buffer to bind, null to unbind.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics operations.
+		 */
+		virtual void setIndexBuffer(const SPtr<IndexBufferCore>& buffer, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
+
+		/**
+		 * Assigns a parameter buffer containing constants (uniforms) for use in a GPU program.
+		 *
+		 * @param[in]	gptype			Type of GPU program to bind the buffer to.
+		 * @param[in]	slot			Slot to bind the buffer to. The slot is dependant on the GPU program the buffer will
+		 *								be used with.
+		 * @param[in]	buffer			Buffer containing constants (uniforms) for use by the shader.
+		 * @param[in]	paramDesc		Description of all parameters in the buffer. Required mostly for backwards 
+		 *								compatibility.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must
+		 *								support graphics or compute operations.
 		 */
-		virtual void setIndexBuffer(const SPtr<IndexBufferCore>& buffer) = 0;
+		virtual void setParamBuffer(GpuProgramType gptype, UINT32 slot, const SPtr<GpuParamBlockBufferCore>& buffer, 
+			const SPtr<GpuParamDesc>& paramDesc, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Sets the vertex declaration to use when drawing. Vertex declaration is used to decode contents of a single 
 		 * vertex in a vertex buffer.
 		 *
 		 * @param[in]	vertexDeclaration	Vertex declaration to bind.
+		 * @param[in]	commandBuffer		Buffer whose subsequent commands will be affected by the state change. Buffer
+		 *									must support graphics operations.
 		 */
-		virtual void setVertexDeclaration(const SPtr<VertexDeclarationCore>& vertexDeclaration) = 0;
+		virtual void setVertexDeclaration(const SPtr<VertexDeclarationCore>& vertexDeclaration, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/** 
 		 * Sets the draw operation that determines how to interpret the elements of the index or vertex buffers. 
 		 *
-		 * @param[in]	op	Draw operation to enable.
+		 * @param[in]	op				Draw operation to enable.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must 
+		 *								support graphics operations.
 		 */
-		virtual void setDrawOperation(DrawOperationType op) = 0;
+		virtual void setDrawOperation(DrawOperationType op, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Draw an object based on currently bound GPU programs, vertex declaration and vertex buffers. Draws directly from
@@ -455,8 +515,11 @@ namespace BansheeEngine
 		 * @param[in]	vertexCount		Number of vertices to draw.
 		 * @param[in]	instanceCount	Number of times to draw the provided geometry, each time with an (optionally)
 		 *								separate per-instance data.
+		 * @param[in]	commandBuffer	Command buffer in which to queue the draw operation on. Buffer must support graphics
+		 *								operations.
 		 */
-		virtual void draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount = 0) = 0;
+		virtual void draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount = 0, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/** 
 		 * Draw an object based on currently bound GPU programs, vertex declaration, vertex and index buffers. 
@@ -467,133 +530,121 @@ namespace BansheeEngine
 		 * @param[in]	vertexCount		Number of vertices to draw.
 		 * @param[in]	instanceCount	Number of times to draw the provided geometry, each time with an (optionally)
 		 *								separate per-instance data.
+		 * @param[in]	commandBuffer	Command buffer in which to queue the draw operation on. Buffer must support graphics
+		 *								operations.
 		 */
 		virtual void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount, 
-			UINT32 instanceCount = 0) = 0;
+			UINT32 instanceCount = 0, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/** 
 		 * Executes the currently bound compute shader. 
 		 *
-		 * @param[in]	numGroupsX	Number of groups to start in the X direction. Must be in range [1, 65535].
-		 * @param[in]	numGroupsY	Number of groups to start in the Y direction. Must be in range [1, 65535].
-		 * @param[in]	numGroupsZ	Number of groups to start in the Z direction. Must be in range [1, 64].
+		 * @param[in]	numGroupsX		Number of groups to start in the X direction. Must be in range [1, 65535].
+		 * @param[in]	numGroupsY		Number of groups to start in the Y direction. Must be in range [1, 65535].
+		 * @param[in]	numGroupsZ		Number of groups to start in the Z direction. Must be in range [1, 64].
+		 * @param[in]	commandBuffer	Command buffer in which to queue the dispatch operation on. Buffer must support
+		 *								compute or graphics operations.
 		 */
-		virtual void dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY = 1, UINT32 numGroupsZ = 1) = 0;
+		virtual void dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY = 1, UINT32 numGroupsZ = 1, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/** 
 		 * Swap the front and back buffer of the specified render target. 
 		 *
-		 * @param[in]	target	Render target to perform the buffer swap on.
-		 */
-		virtual void swapBuffers(const SPtr<RenderTargetCore>& target);
-
-		/**
-		 * Gets the capabilities of the render system.
-		 *
-		 * @note	Thread safe.
+		 * @param[in]	target			Render target to perform the buffer swap on.
+		 * @param[in]	commandBuffer	Command buffer in which to queue the swap buffer operation on. Buffer must support
+		 *								graphics operations.
 		 */
-		const RenderAPICapabilities& getCapabilities() const;
-
-		/** Returns information about the driver version. */
-		virtual const DriverVersion& getDriverVersion() const;
+		virtual void swapBuffers(const SPtr<RenderTargetCore>& target, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Binds the provided GPU program to the pipeline. Any following draw operations will use this program. 
 		 *
-		 * @param[in]	prg		GPU program to bind. Slot it is bound to is determined by the program type.
+		 * @param[in]	prg				GPU program to bind. Slot it is bound to is determined by the program type.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must 
+		 *								support graphics or compute operations (depending on program type).
 		 *
 		 * @note	You need to bind at least a vertex and a fragment program in order to draw something.
 		 */
-		virtual void bindGpuProgram(const SPtr<GpuProgramCore>& prg);
-
-		/**
-		 * Assigns a parameter buffer containing constants (uniforms) for use in a GPU program.
-		 *
-		 * @param[in]	gptype		Type of GPU program to bind the buffer to.
-		 * @param[in]	slot		Slot to bind the buffer to. The slot is dependant on the GPU program the buffer will be used
-		 *							with.
-		 * @param[in]	buffer		Buffer containing constants (uniforms) for use by the shader.
-		 * @param[in]	paramDesc	Description of all parameters in the buffer. Required mostly for backwards compatibility.
-		 */
-		virtual void setParamBuffer(GpuProgramType gptype, UINT32 slot, const SPtr<GpuParamBlockBufferCore>& buffer, 
-			const GpuParamDesc& paramDesc) = 0;
+		virtual void bindGpuProgram(const SPtr<GpuProgramCore>& prg, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**	
 		 * Unbinds a program of a given type. 
 		 *
-		 * @param[in]	gptype	GPU program slot to unbind the program from.
+		 * @param[in]	gptype			GPU program slot to unbind the program from.
+		 * @param[in]	commandBuffer	Buffer whose subsequent commands will be affected by the state change. Buffer must 
+		 *								support graphics or compute operations (depending on program type).
 		 */
-		virtual void unbindGpuProgram(GpuProgramType gptype);
-
-		/**	Query if a GPU program of a given type is currently bound. */
-		virtual bool isGpuProgramBound(GpuProgramType gptype);
-
-		/**	
-		 * Sets up clip planes that will clip drawn geometry on the negative side of the planes. 
-		 *
-		 * @param[in]	clipPlanes	A list of planes to set, replacing the old ones.
-		 */
-		virtual void setClipPlanes(const PlaneList& clipPlanes);
-
-		/**	
-		 * Adds a new clip plane. All drawn geometry will be clipped to this plane. 
-		 *
-		 * @param[in]	p	Clip plane to add.
-		 */
-		virtual void addClipPlane(const Plane& p);
-
-		/**	Clears all clip planes. */
-		virtual void resetClipPlanes();
+		virtual void unbindGpuProgram(GpuProgramType gptype,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
-		 * Allows you to set up a region in which rendering can take place. Coordinates are in pixels. No rendering will be
-		 * done to render target pixels outside of the provided region.
+		 * Change the render target into which we want to draw.
 		 *
-		 * @param[in]	left	Left border of the scissor rectangle, in pixels.
-		 * @param[in]	top		Top border of the scissor rectangle, in pixels.
-		 * @param[in]	right	Right border of the scissor rectangle, in pixels.
-		 * @param[in]	bottom	Bottom border of the scissor rectangle, in pixels.
+		 * @param[in]	target					Render target to draw to.
+		 * @param[in]	readOnlyDepthStencil	If true the caller guarantees he won't write to the depth/stencil buffer 
+		 *										(if any was provided). This allows the depth buffer to be bound for depth 
+		 *										testing, as well as reading in a shader, at the same time.
+		 * @param[in]	commandBuffer			Buffer whose subsequent commands will be affected by the state change. 
+		 *										Buffer must support graphics operations.
 		 */
-		virtual void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom) = 0;
+        virtual void setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil = false,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Clears the currently active render target.
 		 *
-		 * @param[in]	buffers		Combination of one or more elements of FrameBufferType denoting which buffers are 
-		 *							to be cleared.
-		 * @param[in]	color		(optional) The color to clear the color buffer with, if enabled.
-		 * @param[in]	depth		(optional) The value to initialize the depth buffer with, if enabled.
-		 * @param[in]	stencil		(optional) The value to initialize the stencil buffer with, if enabled.
-		 * @param[in]	targetMask	(optional) In case multiple render targets are bound, this allows you to control
-		 *							which ones to clear (0x01 first, 0x02 second, 0x04 third, etc., and combinations).
+		 * @param[in]	buffers			Combination of one or more elements of FrameBufferType denoting which buffers are 
+		 *								to be cleared.
+		 * @param[in]	color			The color to clear the color buffer with, if enabled.
+		 * @param[in]	depth			The value to initialize the depth buffer with, if enabled.
+		 * @param[in]	stencil			The value to initialize the stencil buffer with, if enabled.
+		 * @param[in]	targetMask		In case multiple render targets are bound, this allows you to control which ones to
+		 *									clear (0x01 first, 0x02 second, 0x04 third, etc., and combinations).
+		 * @param[in]	commandBuffer	Command buffer in which to queue the clear operation on. Buffer must support
+		 *								graphics operations.
 		 */
 		virtual void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, 
-			UINT16 stencil = 0, UINT8 targetMask = 0xFF) = 0;
+			UINT16 stencil = 0, UINT8 targetMask = 0xFF, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
 
 		/**
 		 * Clears the currently active viewport (meaning it clears just a sub-area of a render-target that is covered by the 
 		 * viewport, as opposed to clearRenderTarget() which always clears the entire render target).
 		 *
-		 * @param[in]	buffers		Combination of one or more elements of FrameBufferType denoting which buffers are to be
-		 *							cleared.
-		 * @param[in]	color		(optional) The color to clear the color buffer with, if enabled.
-		 * @param[in]	depth		(optional) The value to initialize the depth buffer with, if enabled.
-		 * @param[in]	stencil		(optional) The value to initialize the stencil buffer with, if enabled.
-		 * @param[in]	targetMask	(optional) In case multiple render targets are bound, this allows you to control
-		 *							which ones to clear (0x01 first, 0x02 second, 0x04 third, etc., and combinations).
+		 * @param[in]	buffers			Combination of one or more elements of FrameBufferType denoting which buffers are to
+		 *								be cleared.
+		 * @param[in]	color			The color to clear the color buffer with, if enabled.
+		 * @param[in]	depth			The value to initialize the depth buffer with, if enabled.
+		 * @param[in]	stencil			The value to initialize the stencil buffer with, if enabled.
+		 * @param[in]	targetMask		In case multiple render targets are bound, this allows you to control which ones to
+		 *								clear (0x01 first, 0x02 second, 0x04 third, etc., and combinations).
+		 * @param[in]	commandBuffer	Command buffer in which to queue the clear operation on. Buffer must support
+		 *								graphics operations.
 		 */
 		virtual void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, 
-			UINT16 stencil = 0, UINT8 targetMask = 0xFF) = 0;
+			UINT16 stencil = 0, UINT8 targetMask = 0xFF, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) = 0;
+
+		/** Appends all commands from the provided secondary command buffer into the primary command buffer. */
+		virtual void addCommands(const SPtr<CommandBuffer>& commandBuffer, const SPtr<CommandBuffer>& secondary) = 0;
+
+		/** 
+		 * Executes all commands in the provided command buffer. Command buffer cannot be secondary.
+		 *
+		 * @note	Core thread only.
+		 */
+		virtual void executeCommands(const SPtr<CommandBuffer>& commandBuffer) = 0;
+
+		/** Returns information about the driver version. */
+		virtual const DriverVersion& getDriverVersion() const;
 
 		/**
-		 * Change the render target into which we want to draw.
+		 * Gets the capabilities of the render system.
 		 *
-		 * @param[in]	target					Render target to draw to.
-		 * @param[in]	readOnlyDepthStencil	If true the caller guarantees he won't write to the depth/stencil buffer 
-		 *										(if any was provided). This allows the depth buffer to be bound for depth 
-		 *										testing, as well as reading in a shader, at the same time.
+		 * @note	Thread safe.
 		 */
-        virtual void setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil = false) = 0;
+		const RenderAPICapabilities& getCapabilities() const { return *mCurrentCapabilities; }
 
 		/**
 		 * Returns information about available output devices and their video modes.
@@ -670,9 +721,6 @@ namespace BansheeEngine
 		/** Performs render API system shutdown on the core thread. */
 		virtual void destroyCore();
 
-		/** @copydoc setClipPlanes */
-		virtual void setClipPlanesImpl(const PlaneList& clipPlanes) = 0;
-
 		/************************************************************************/
 		/* 								INTERNAL DATA					       	*/
 		/************************************************************************/
@@ -682,18 +730,6 @@ namespace BansheeEngine
 		SPtr<RenderTargetCore> mActiveRenderTarget;
 
 		DriverVersion mDriverVersion;
-		CullingMode mCullingMode;
-		UINT16 mDisabledTexUnitsFrom;
-
-		bool mVertexProgramBound;
-		bool mGeometryProgramBound;
-		bool mFragmentProgramBound;
-		bool mDomainProgramBound;
-		bool mHullProgramBound;
-		bool mComputeProgramBound;
-
-		PlaneList mClipPlanes;
-		bool mClipPlanesDirty;
 
 		RenderAPICapabilities* mCurrentCapabilities;
 		SPtr<VideoModeInfo> mVideoModeInfo;

+ 0 - 50
Source/BansheeCore/Source/BsCommandBuffer.cpp

@@ -16,54 +16,4 @@ namespace BansheeEngine
 	{
 		return CommandBufferManager::instance().create(type, deviceIdx, syncMask, secondary);
 	}
-
-	SimpleCommandBuffer::SimpleCommandBuffer(CommandBufferType type, UINT32 deviceIdx, UINT32 syncMask, bool secondary)
-		: CommandBuffer(type, syncMask, secondary), mDeviceIdx(deviceIdx)
-	{
-
-	}
-
-	void SimpleCommandBuffer::queueCommand(const std::function<void()> command)
-	{
-		mCommands.push_back(command);
-	}
-
-	void SimpleCommandBuffer::appendSecondary(const SPtr<SimpleCommandBuffer>& secondaryBuffer)
-	{
-#if BS_DEBUG_MODE
-		if(!secondaryBuffer->mIsSecondary)
-		{
-			LOGERR("Cannot append a command buffer that is not secondary.");
-			return;
-		}
-
-		if(mIsSecondary)
-		{
-			LOGERR("Cannot append a buffer to a secondary command buffer.");
-			return;
-		}
-#endif
-
-		for (auto& entry : secondaryBuffer->mCommands)
-			mCommands.push_back(entry);
-	}
-
-	void SimpleCommandBuffer::executeCommands()
-	{
-#if BS_DEBUG_MODE
-		if (mIsSecondary)
-		{
-			LOGERR("Cannot execute commands on a secondary buffer.");
-			return;
-		}
-#endif
-
-		for (auto& entry : mCommands)
-			entry();
-	}
-
-	void SimpleCommandBuffer::clear()
-	{
-		mCommands.clear();
-	}
 }

+ 8 - 8
Source/BansheeCore/Source/BsGpuParamsSet.cpp

@@ -550,8 +550,8 @@ namespace BansheeEngine
 					}
 
 					// Create non-shareable ones (these are buffers defined by default by the RHI usually)
-					const GpuParamDesc& desc = paramPtr->getParamDesc();
-					for (auto iterBlockDesc = desc.paramBlocks.begin(); iterBlockDesc != desc.paramBlocks.end(); ++iterBlockDesc)
+					SPtr<GpuParamDesc> desc = paramPtr->getParamDesc();
+					for (auto iterBlockDesc = desc->paramBlocks.begin(); iterBlockDesc != desc->paramBlocks.end(); ++iterBlockDesc)
 					{
 						const GpuParamBlockDesc& blockDesc = iterBlockDesc->second;
 
@@ -580,7 +580,7 @@ namespace BansheeEngine
 						if (globalBlockIdx == (UINT32)-1)
 							continue;
 
-						for(auto& dataParam : desc.params)
+						for(auto& dataParam : desc->params)
 						{
 							if (dataParam.second.paramBlockSlot != blockDesc.slot)
 								continue;
@@ -675,11 +675,11 @@ namespace BansheeEngine
 						}
 					};
 
-					const GpuParamDesc& desc = paramPtr->getParamDesc();
-					processObjectParams(desc.textures, 0, MaterialParams::ParamType::Texture);
-					processObjectParams(desc.loadStoreTextures, 1, MaterialParams::ParamType::Texture);
-					processObjectParams(desc.buffers, 2, MaterialParams::ParamType::Buffer);
-					processObjectParams(desc.samplers, 3, MaterialParams::ParamType::Sampler);
+					SPtr<GpuParamDesc> desc = paramPtr->getParamDesc();
+					processObjectParams(desc->textures, 0, MaterialParams::ParamType::Texture);
+					processObjectParams(desc->loadStoreTextures, 1, MaterialParams::ParamType::Texture);
+					processObjectParams(desc->buffers, 2, MaterialParams::ParamType::Buffer);
+					processObjectParams(desc->samplers, 3, MaterialParams::ParamType::Sampler);
 
 					stageOffsets += 4;
 				}

+ 47 - 186
Source/BansheeCore/Source/BsRenderAPI.cpp

@@ -16,49 +16,57 @@
 #include "BsGpuParamDesc.h"
 #include "BsGpuBuffer.h"
 #include "BsGpuParamBlockBuffer.h"
-#include "BsShader.h"
+#include "BsCommandBuffer.h"
 
 using namespace std::placeholders;
 
 namespace BansheeEngine 
 {
+	BS_CORE_EXPORT SPtr<CommandBuffer> gMainCommandBuffer = nullptr;
+
 	void RenderAPI::setTexture(CoreAccessor& accessor, GpuProgramType gptype, UINT16 unit, const SPtr<Texture> &texPtr)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setTexture, RenderAPICore::instancePtr(), gptype, unit, texPtr->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setTexture, RenderAPICore::instancePtr(), gptype, unit, 
+			texPtr->getCore(), gMainCommandBuffer));
 	}
 
 	void RenderAPI::setLoadStoreTexture(CoreAccessor& accessor, GpuProgramType gptype, UINT16 unit, 
 		const SPtr<Texture>& texPtr, const TextureSurface& surface)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::setLoadStoreTexture, RenderAPICore::instancePtr(), gptype, unit, 
-			texPtr->getCore(), surface));
+			texPtr->getCore(), surface, gMainCommandBuffer));
 	}
 
 	void RenderAPI::setBuffer(CoreAccessor& accessor, GpuProgramType gptype, UINT16 unit, const SPtr<GpuBuffer>& buffer,
 		bool loadStore)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::setBuffer, RenderAPICore::instancePtr(), gptype, unit, 
-			buffer->getCore(), loadStore));
+			buffer->getCore(), loadStore, gMainCommandBuffer));
 	}
 
-	void RenderAPI::setSamplerState(CoreAccessor& accessor, GpuProgramType gptype, UINT16 texUnit, const SPtr<SamplerState>& samplerState)
+	void RenderAPI::setSamplerState(CoreAccessor& accessor, GpuProgramType gptype, UINT16 texUnit, 
+		const SPtr<SamplerState>& samplerState)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setSamplerState, RenderAPICore::instancePtr(), gptype, texUnit, samplerState->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setSamplerState, RenderAPICore::instancePtr(), gptype, texUnit, 
+			samplerState->getCore(), gMainCommandBuffer));
 	}
 
 	void RenderAPI::setBlendState(CoreAccessor& accessor, const SPtr<BlendState>& blendState)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setBlendState, RenderAPICore::instancePtr(), blendState->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setBlendState, RenderAPICore::instancePtr(), blendState->getCore(), 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::setRasterizerState(CoreAccessor& accessor, const SPtr<RasterizerState>& rasterizerState)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setRasterizerState, RenderAPICore::instancePtr(), rasterizerState->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setRasterizerState, RenderAPICore::instancePtr(), 
+			rasterizerState->getCore(), gMainCommandBuffer));
 	}
 
 	void RenderAPI::setDepthStencilState(CoreAccessor& accessor, const SPtr<DepthStencilState>& depthStencilState, UINT32 stencilRefValue)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setDepthStencilState, RenderAPICore::instancePtr(), depthStencilState->getCore(), stencilRefValue));
+		accessor.queueCommand(std::bind(&RenderAPICore::setDepthStencilState, RenderAPICore::instancePtr(), 
+			depthStencilState->getCore(), stencilRefValue, gMainCommandBuffer));
 	}
 
 	void RenderAPI::setVertexBuffers(CoreAccessor& accessor, UINT32 index, const Vector<SPtr<VertexBuffer>>& buffers)
@@ -78,105 +86,99 @@ namespace BansheeEngine
 
 	void RenderAPI::setIndexBuffer(CoreAccessor& accessor, const SPtr<IndexBuffer>& buffer)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setIndexBuffer, RenderAPICore::instancePtr(), buffer->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setIndexBuffer, RenderAPICore::instancePtr(), buffer->getCore(), 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::setVertexDeclaration(CoreAccessor& accessor, const SPtr<VertexDeclaration>& vertexDeclaration)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setVertexDeclaration, RenderAPICore::instancePtr(), vertexDeclaration->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setVertexDeclaration, RenderAPICore::instancePtr(), 
+			vertexDeclaration->getCore(), gMainCommandBuffer));
 	}
 
 	void RenderAPI::setViewport(CoreAccessor& accessor, const Rect2& vp)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setViewport, RenderAPICore::instancePtr(), vp));
+		accessor.queueCommand(std::bind(&RenderAPICore::setViewport, RenderAPICore::instancePtr(), vp, gMainCommandBuffer));
 	}
 
 	void RenderAPI::setDrawOperation(CoreAccessor& accessor, DrawOperationType op)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setDrawOperation, RenderAPICore::instancePtr(), op));
-	}
-
-	void RenderAPI::setClipPlanes(CoreAccessor& accessor, const PlaneList& clipPlanes)
-	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setClipPlanes, RenderAPICore::instancePtr(), clipPlanes));
-	}
-
-	void RenderAPI::addClipPlane(CoreAccessor& accessor, const Plane& p)
-	{
-		accessor.queueCommand(std::bind(&RenderAPICore::addClipPlane, RenderAPICore::instancePtr(), p));
-	}
-
-	void RenderAPI::resetClipPlanes(CoreAccessor& accessor)
-	{
-		accessor.queueCommand(std::bind(&RenderAPICore::resetClipPlanes, RenderAPICore::instancePtr()));
+		accessor.queueCommand(std::bind(&RenderAPICore::setDrawOperation, RenderAPICore::instancePtr(), op, 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::setScissorRect(CoreAccessor& accessor, UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::setScissorRect, RenderAPICore::instancePtr(), left, top, right, bottom));
+		accessor.queueCommand(std::bind(&RenderAPICore::setScissorRect, RenderAPICore::instancePtr(), left, top, right, bottom, 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::setRenderTarget(CoreAccessor& accessor, const SPtr<RenderTarget>& target, bool readOnlyDepthStencil)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::setRenderTarget, 
-			RenderAPICore::instancePtr(), target->getCore(), readOnlyDepthStencil));
+			RenderAPICore::instancePtr(), target->getCore(), readOnlyDepthStencil, gMainCommandBuffer));
 	}
 
 	void RenderAPI::bindGpuProgram(CoreAccessor& accessor, const SPtr<GpuProgram>& prg)
 	{
 		prg->syncToCore(accessor);
-		accessor.queueCommand(std::bind(&RenderAPICore::bindGpuProgram, RenderAPICore::instancePtr(), prg->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::bindGpuProgram, RenderAPICore::instancePtr(), prg->getCore(), 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::unbindGpuProgram(CoreAccessor& accessor, GpuProgramType gptype)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::unbindGpuProgram, RenderAPICore::instancePtr(), gptype));
+		accessor.queueCommand(std::bind(&RenderAPICore::unbindGpuProgram, RenderAPICore::instancePtr(), gptype, 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::beginRender(CoreAccessor& accessor)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::beginFrame, RenderAPICore::instancePtr()));
+		accessor.queueCommand(std::bind(&RenderAPICore::beginFrame, RenderAPICore::instancePtr(), gMainCommandBuffer));
 	}
 
 	void RenderAPI::endRender(CoreAccessor& accessor)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::endFrame, RenderAPICore::instancePtr()));
+		accessor.queueCommand(std::bind(&RenderAPICore::endFrame, RenderAPICore::instancePtr(), gMainCommandBuffer));
 	}
 
-	void RenderAPI::clearRenderTarget(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
+	void RenderAPI::clearRenderTarget(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, 
+		UINT16 stencil, UINT8 targetMask)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::clearRenderTarget, RenderAPICore::instancePtr(), buffers, color,
-			depth, stencil, targetMask));
+			depth, stencil, targetMask, gMainCommandBuffer));
 	}
 
-	void RenderAPI::clearViewport(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask)
+	void RenderAPI::clearViewport(CoreAccessor& accessor, UINT32 buffers, const Color& color, float depth, UINT16 stencil, 
+		UINT8 targetMask)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::clearViewport, RenderAPICore::instancePtr(), buffers, color, depth,
-			stencil, targetMask));
+			stencil, targetMask, gMainCommandBuffer));
 	}
 
 	void RenderAPI::swapBuffers(CoreAccessor& accessor, const SPtr<RenderTarget>& target)
 	{
-		accessor.queueCommand(std::bind(&RenderAPICore::swapBuffers, RenderAPICore::instancePtr(), target->getCore()));
+		accessor.queueCommand(std::bind(&RenderAPICore::swapBuffers, RenderAPICore::instancePtr(), target->getCore(), 
+			gMainCommandBuffer));
 	}
 
 	void RenderAPI::draw(CoreAccessor& accessor, UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::draw, RenderAPICore::instancePtr(), vertexOffset, 
-			vertexCount, instanceCount));
+			vertexCount, instanceCount, gMainCommandBuffer));
 	}
 
 	void RenderAPI::drawIndexed(CoreAccessor& accessor, UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, 
 		UINT32 vertexCount, UINT32 instanceCount)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::drawIndexed, RenderAPICore::instancePtr(), startIndex, indexCount, 
-			vertexOffset, vertexCount, instanceCount));
+			vertexOffset, vertexCount, instanceCount, gMainCommandBuffer));
 	}
 
 	void RenderAPI::dispatchCompute(CoreAccessor& accessor, UINT32 numGroupsX, UINT32 numGroupsY, UINT32 numGroupsZ)
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::dispatchCompute, RenderAPICore::instancePtr(), numGroupsX, 
-			numGroupsY, numGroupsZ));
+			numGroupsY, numGroupsZ, gMainCommandBuffer));
 	}
 
 	const VideoModeInfo& RenderAPI::getVideoModeInfo()
@@ -195,16 +197,7 @@ namespace BansheeEngine
 	}
 
     RenderAPICore::RenderAPICore()
-        : mCullingMode(CULL_COUNTERCLOCKWISE)
-        , mDisabledTexUnitsFrom(0)
-        , mVertexProgramBound(false)
-		, mGeometryProgramBound(false)
-        , mFragmentProgramBound(false)
-		, mDomainProgramBound(false)
-		, mHullProgramBound(false)
-		, mComputeProgramBound(false)
-		, mClipPlanesDirty(true)
-		, mCurrentCapabilities(nullptr)
+        : mCurrentCapabilities(nullptr)
     {
     }
 
@@ -214,6 +207,8 @@ namespace BansheeEngine
 
 		bs_delete(mCurrentCapabilities);
 		mCurrentCapabilities = nullptr;
+
+		gMainCommandBuffer = nullptr;
     }
 
 	SPtr<RenderWindow> RenderAPICore::initialize(const RENDER_WINDOW_DESC& primaryWindowDesc)
@@ -236,13 +231,6 @@ namespace BansheeEngine
 	void RenderAPICore::initializeFinalize(const SPtr<RenderWindowCore>& primaryWindow)
 	{
 		THROW_IF_NOT_CORE_THREAD;
-
-		mVertexProgramBound = false;
-		mGeometryProgramBound = false;
-		mFragmentProgramBound = false;
-		mDomainProgramBound = false;
-		mHullProgramBound = false;
-		mComputeProgramBound = false;
 	}
 
 	void RenderAPICore::destroy()
@@ -256,137 +244,10 @@ namespace BansheeEngine
 		mActiveRenderTarget = nullptr;
 	}
 
-	const RenderAPICapabilities& RenderAPICore::getCapabilities(void) const 
-	{ 
-		return *mCurrentCapabilities; 
-	}
-
 	const DriverVersion& RenderAPICore::getDriverVersion(void) const 
 	{ 
 		THROW_IF_NOT_CORE_THREAD;
 
 		return mDriverVersion; 
 	}
-
-	void RenderAPICore::addClipPlane(const Plane &p)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		mClipPlanes.push_back(p);
-		mClipPlanesDirty = true;
-	}
-
-	void RenderAPICore::setClipPlanes(const PlaneList& clipPlanes)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		if (clipPlanes != mClipPlanes)
-		{
-			mClipPlanes = clipPlanes;
-			mClipPlanesDirty = true;
-		}
-	}
-
-	void RenderAPICore::resetClipPlanes()
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		if (!mClipPlanes.empty())
-		{
-			mClipPlanes.clear();
-			mClipPlanesDirty = true;
-		}
-	}
-
-	void RenderAPICore::bindGpuProgram(const SPtr<GpuProgramCore>& prg)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		switch(prg->getProperties().getType())
-		{
-		case GPT_VERTEX_PROGRAM:
-			if (!mVertexProgramBound && !mClipPlanes.empty())
-				mClipPlanesDirty = true;
-
-			mVertexProgramBound = true;
-			break;
-		case GPT_GEOMETRY_PROGRAM:
-			mGeometryProgramBound = true;
-			break;
-		case GPT_FRAGMENT_PROGRAM:
-			mFragmentProgramBound = true;
-			break;
-		case GPT_DOMAIN_PROGRAM:
-			mDomainProgramBound = true;
-			break;
-		case GPT_HULL_PROGRAM:
-			mHullProgramBound = true;
-			break;
-		case GPT_COMPUTE_PROGRAM:
-			mComputeProgramBound = true;
-			break;
-		}
-	}
-
-	void RenderAPICore::unbindGpuProgram(GpuProgramType gptype)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		switch(gptype)
-		{
-		case GPT_VERTEX_PROGRAM:
-			if (mVertexProgramBound && !mClipPlanes.empty())
-				mClipPlanesDirty = true;
-
-			mVertexProgramBound = false;
-			break;
-		case GPT_GEOMETRY_PROGRAM:
-			mGeometryProgramBound = false;
-			break;
-		case GPT_FRAGMENT_PROGRAM:
-			mFragmentProgramBound = false;
-			break;
-		case GPT_DOMAIN_PROGRAM:
-			mDomainProgramBound = false;
-			break;
-		case GPT_HULL_PROGRAM:
-			mHullProgramBound = false;
-			break;
-		case GPT_COMPUTE_PROGRAM:
-			mComputeProgramBound = false;
-			break;
-		}
-	}
-
-	bool RenderAPICore::isGpuProgramBound(GpuProgramType gptype)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-	    switch(gptype)
-	    {
-        case GPT_VERTEX_PROGRAM:
-            return mVertexProgramBound;
-        case GPT_GEOMETRY_PROGRAM:
-            return mGeometryProgramBound;
-        case GPT_FRAGMENT_PROGRAM:
-            return mFragmentProgramBound;
-		case GPT_DOMAIN_PROGRAM:
-			return mDomainProgramBound;
-		case GPT_HULL_PROGRAM:
-			return mHullProgramBound;
-		case GPT_COMPUTE_PROGRAM:
-			return mComputeProgramBound;
-	    }
-
-        return false;
-	}
-	
-	void RenderAPICore::swapBuffers(const SPtr<RenderTargetCore>& target)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		target->swapBuffers();
-
-		BS_INC_RENDER_STAT(NumPresents);
-	}
 }

+ 0 - 3
Source/BansheeD3D11RenderAPI/Include/BsD3D11RenderAPI.h

@@ -101,9 +101,6 @@ namespace BansheeEngine
 		void setParamBuffer(GpuProgramType gptype, UINT32 slot, const SPtr<GpuParamBlockBufferCore>& buffer, 
 			const GpuParamDesc& paramDesc) override;
 
-		/** @copydoc RenderAPICore::setClipPlanesImpl */
-		void setClipPlanesImpl(const PlaneList& clipPlanes) override;
-
 		/** @copydoc RenderAPICore::convertProjectionMatrix */
 		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest) override;
 

+ 1 - 8
Source/BansheeD3D11RenderAPI/Source/BsD3D11RenderAPI.cpp

@@ -39,9 +39,7 @@ namespace BansheeEngine
 		, mHLSLFactory(nullptr), mIAManager(nullptr)
 		, mStencilRef(0), mActiveDrawOp(DOT_TRIANGLE_LIST)
 		, mViewportNorm(0.0f, 0.0f, 1.0f, 1.0f)
-	{
-		mClipPlanesDirty = false; // DX11 handles clip planes through shaders
-	}
+	{ }
 
 	D3D11RenderAPI::~D3D11RenderAPI()
 	{
@@ -857,11 +855,6 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumRenderTargetChanges);
 	}
 
-	void D3D11RenderAPI::setClipPlanesImpl(const PlaneList& clipPlanes)
-	{
-		LOGWRN("This call will be ignored. DX11 uses shaders for setting clip planes.");
-	}
-
 	RenderAPICapabilities* D3D11RenderAPI::createRenderSystemCapabilities() const
 	{
 		THROW_IF_NOT_CORE_THREAD;

+ 6 - 6
Source/BansheeEngine/Source/BsRendererUtility.cpp

@@ -204,16 +204,16 @@ namespace BansheeEngine
 	void RendererUtility::setGpuParams(GpuProgramType type, const SPtr<GpuParamsCore>& params)
 	{
 		RenderAPICore& rapi = RenderAPICore::instance();
-		const GpuParamDesc& paramDesc = params->getParamDesc();
+		SPtr<GpuParamDesc> paramDesc = params->getParamDesc();
 
-		for (auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
+		for (auto iter = paramDesc->textures.begin(); iter != paramDesc->textures.end(); ++iter)
 		{
 			SPtr<TextureCore> texture = params->getTexture(iter->second.slot);
 
 			rapi.setTexture(type, iter->second.slot, texture);
 		}
 
-		for (auto iter = paramDesc.loadStoreTextures.begin(); iter != paramDesc.loadStoreTextures.end(); ++iter)
+		for (auto iter = paramDesc->loadStoreTextures.begin(); iter != paramDesc->loadStoreTextures.end(); ++iter)
 		{
 			SPtr<TextureCore> texture = params->getLoadStoreTexture(iter->second.slot);
 			const TextureSurface& surface = params->getLoadStoreSurface(iter->second.slot);
@@ -224,7 +224,7 @@ namespace BansheeEngine
 				rapi.setLoadStoreTexture(type, iter->second.slot, texture, surface);
 		}
 
-		for (auto iter = paramDesc.buffers.begin(); iter != paramDesc.buffers.end(); ++iter)
+		for (auto iter = paramDesc->buffers.begin(); iter != paramDesc->buffers.end(); ++iter)
 		{
 			SPtr<GpuBufferCore> buffer = params->getBuffer(iter->second.slot);
 
@@ -234,7 +234,7 @@ namespace BansheeEngine
 			rapi.setBuffer(type, iter->second.slot, buffer, isLoadStore);
 		}
 
-		for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
+		for (auto iter = paramDesc->samplers.begin(); iter != paramDesc->samplers.end(); ++iter)
 		{
 			SPtr<SamplerStateCore> samplerState = params->getSamplerState(iter->second.slot);
 
@@ -244,7 +244,7 @@ namespace BansheeEngine
 				rapi.setSamplerState(type, iter->second.slot, samplerState);
 		}
 
-		for (auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
+		for (auto iter = paramDesc->paramBlocks.begin(); iter != paramDesc->paramBlocks.end(); ++iter)
 		{
 			SPtr<GpuParamBlockBufferCore> blockBuffer = params->getParamBlockBuffer(iter->second.slot);
 			blockBuffer->flushToGPU();

+ 4 - 0
Source/BansheeGLRenderAPI/CMakeSources.cmake

@@ -31,6 +31,8 @@ set(BS_BANSHEEGLRENDERAPI_INC_NOFILTER
 	"Include/BsGLRenderAPIFactory.h"
 	"Include/BsGLUtil.h"
 	"Include/BsGLBuffer.h"
+	"Include/BsGLCommandBuffer.h"
+	"Include/BsGLCommandBufferManager.h"
 )
 
 set(BS_BANSHEEGLRENDERAPI_SRC_WIN32
@@ -66,6 +68,8 @@ set(BS_BANSHEEGLRENDERAPI_SRC_NOFILTER
 	"Source/BsGLRenderAPIFactory.cpp"
 	"Source/BsGLPlugin.cpp"
 	"Source/BsGLBuffer.cpp"
+	"Source/BsGLCommandBuffer.cpp"
+	"Source/BsGLCommandBufferManager.cpp"
 )
 
 set(BS_BANSHEEGLRENDERAPI_INC_GLSL

+ 48 - 0
Source/BansheeGLRenderAPI/Include/BsGLCommandBuffer.h

@@ -0,0 +1,48 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsGLPrerequisites.h"
+#include "BsCommandBuffer.h"
+#include "BsDrawOps.h"
+#include "BsGLRenderAPI.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup GL
+	 *  @{
+	 */
+
+	/**
+	 * Command buffer implementation for OpenGL, which doesn't support multi-threaded command generation. Instead all
+	 * commands are stored in an internal buffer, and then sent to the actual render API when the buffer is executed.
+	 */
+	class GLCommandBuffer : public CommandBuffer
+	{
+	public:
+		/** Registers a new command in the command buffer. */
+		void queueCommand(const std::function<void()> command);
+
+		/** Appends all commands from the secondary buffer into this command buffer. */
+		void appendSecondary(const SPtr<GLCommandBuffer>& secondaryBuffer);
+
+		/** Executes all commands in the command buffer. Not supported on secondary buffer. */
+		void executeCommands();
+
+		/** Removes all commands from the command buffer. */
+		void clear();
+
+	private:
+		friend class GLCommandBufferManager;
+		friend class GLRenderAPI;
+
+		GLCommandBuffer(CommandBufferType type, UINT32 deviceIdx, UINT32 syncMask, bool secondary);
+
+		UINT32 mDeviceIdx;
+		Vector<std::function<void()>> mCommands;
+
+		DrawOperationType mCurrentDrawOperation;
+	};
+
+	/** @} */
+}

+ 28 - 0
Source/BansheeGLRenderAPI/Include/BsGLCommandBufferManager.h

@@ -0,0 +1,28 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsGLPrerequisites.h"
+#include "BsCommandBufferManager.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI-Internal
+	 *  @{
+	 */
+
+	/** 
+	 * Handles creation of OpenGL command buffers. See CommandBuffer. 
+	 *
+	 * @note Core thread only.
+	 */
+	class GLCommandBufferManager : public CommandBufferManager
+	{
+	public:
+		/** @copydoc CommandBufferManager::create() */
+		SPtr<CommandBuffer> create(CommandBufferType type, UINT32 deviceIdx = 0, UINT32 syncMask = 0xFFFFFFFF, 
+			bool secondary = false) override;
+	};
+
+	/** @} */
+}

+ 1 - 1
Source/BansheeGLRenderAPI/Include/BsGLPrerequisites.h

@@ -101,4 +101,4 @@ namespace BansheeEngine
 	};
 
 	/** @} */
-}
+}

+ 71 - 51
Source/BansheeGLRenderAPI/Include/BsGLRenderAPI.h

@@ -27,82 +27,106 @@ namespace BansheeEngine
 		/** @copydoc RenderAPICore::getShadingLanguageName() */
 		const String& getShadingLanguageName() const override;
 
-		/** @copydoc RenderAPICore::setRenderTarget() */
-		void setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil = false) override;
-
-        /** @copydoc RenderAPICore::setVertexBuffers() */
-		void setVertexBuffers(UINT32 index, SPtr<VertexBufferCore>* buffers, UINT32 numBuffers) override;
-
-		/** @copydoc RenderAPICore::setIndexBuffer() */
-		void setIndexBuffer(const SPtr<IndexBufferCore>& buffer) override;
+		/** @copydoc RenderAPICore::setSamplerState() */
+		void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SPtr<SamplerStateCore>& samplerState, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::setVertexDeclaration() */
-		void setVertexDeclaration(const SPtr<VertexDeclarationCore>& vertexDeclaration) override;
+		/** @copydoc RenderAPICore::setBlendState() */
+		void setBlendState(const SPtr<BlendStateCore>& blendState, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::setDrawOperation() */
-		void setDrawOperation(DrawOperationType op) override;
+		/** @copydoc RenderAPICore::setRasterizerState() */
+		void setRasterizerState(const SPtr<RasterizerStateCore>& rasterizerState, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-        /** @copydoc RenderAPICore::setScissorRect() */
-		void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom) override;
+		/** @copydoc RenderAPICore::setDepthStencilState() */
+		void setDepthStencilState(const SPtr<DepthStencilStateCore>& depthStencilState, UINT32 stencilRefValue,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::setTexture() */
-		void setTexture(GpuProgramType gptype, UINT16 texUnit, const SPtr<TextureCore>& texture) override;
+		void setTexture(GpuProgramType gptype, UINT16 texUnit, const SPtr<TextureCore>& texture,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::setLoadStoreTexture */
 		void setLoadStoreTexture(GpuProgramType gptype, UINT16 texUnit, const SPtr<TextureCore>& texture,
-			const TextureSurface& surface) override;
-        
-		/** @copydoc RenderAPICore::setBuffer */
-		void setBuffer(GpuProgramType gptype, UINT16 unit, const SPtr<GpuBufferCore>& buffer, bool loadStore = false) override;
-
-		/** @copydoc RenderAPICore::setSamplerState() */
-		void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SPtr<SamplerStateCore>& samplerState) override;
+			const TextureSurface& surface, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::setBlendState() */
-		void setBlendState(const SPtr<BlendStateCore>& blendState) override;
+		/** @copydoc RenderAPICore::setBuffer */
+		void setBuffer(GpuProgramType gptype, UINT16 unit, const SPtr<GpuBufferCore>& buffer, bool loadStore = false,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::setRasterizerState() */
-		void setRasterizerState(const SPtr<RasterizerStateCore>& rasterizerState) override;
+		/** @copydoc RenderAPICore::beginFrame() */
+		void beginFrame(const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::setDepthStencilState() */
-		void setDepthStencilState(const SPtr<DepthStencilStateCore>& depthStencilState, UINT32 stencilRefValue) override;
+		/** @copydoc RenderAPICore::endFrame() */
+		void endFrame(const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::setViewport() */
-		void setViewport(const Rect2& area) override;
+		void setViewport(const Rect2& area, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::bindGpuProgram() */
-		void bindGpuProgram(const SPtr<GpuProgramCore>& prg) override;
+		/** @copydoc RenderAPICore::setScissorRect() */
+		void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::unbindGpuProgram() */
-		void unbindGpuProgram(GpuProgramType gptype) override;
+		/** @copydoc RenderAPICore::setVertexBuffers() */
+		void setVertexBuffers(UINT32 index, SPtr<VertexBufferCore>* buffers, UINT32 numBuffers,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
+
+		/** @copydoc RenderAPICore::setIndexBuffer() */
+		void setIndexBuffer(const SPtr<IndexBufferCore>& buffer,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::setParamBuffer */
-		void setParamBuffer(GpuProgramType gptype, UINT32 slot, const SPtr<GpuParamBlockBufferCore>& buffer, 
-			const GpuParamDesc& paramDesc) override;
+		void setParamBuffer(GpuProgramType gptype, UINT32 slot, const SPtr<GpuParamBlockBufferCore>& buffer,
+			const SPtr<GpuParamDesc>& paramDesc, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::beginFrame() */
-		void beginFrame() override;
+		/** @copydoc RenderAPICore::setVertexDeclaration() */
+		void setVertexDeclaration(const SPtr<VertexDeclarationCore>& vertexDeclaration,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
-		/** @copydoc RenderAPICore::endFrame() */
-		void endFrame() override;
+		/** @copydoc RenderAPICore::setDrawOperation() */
+		void setDrawOperation(DrawOperationType op, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::draw() */
-		void draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount = 0) override;
+		void draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount = 0,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::drawIndexed() */
 		void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount
-			, UINT32 instanceCount = 0) override;
+			, UINT32 instanceCount = 0, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::dispatchCompute() */
-		void dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY = 1, UINT32 numGroupsZ = 1) override;
+		void dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY = 1, UINT32 numGroupsZ = 1, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
+
+		/** @copydoc RenderAPICore::swapBuffers() */
+		void swapBuffers(const SPtr<RenderTargetCore>& target,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
+
+		/** @copydoc RenderAPICore::bindGpuProgram() */
+		void bindGpuProgram(const SPtr<GpuProgramCore>& prg, 
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
+
+		/** @copydoc RenderAPICore::unbindGpuProgram() */
+		void unbindGpuProgram(GpuProgramType gptype, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
+
+		/** @copydoc RenderAPICore::setRenderTarget() */
+		void setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil = false,
+			const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::clearRenderTarget() */
 		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
-			UINT8 targetMask = 0xFF) override;
+			UINT8 targetMask = 0xFF, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
 
 		/** @copydoc RenderAPICore::clearViewport() */
 		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
-			UINT8 targetMask = 0xFF) override;
+			UINT8 targetMask = 0xFF, const SPtr<CommandBuffer>& commandBuffer = gMainCommandBuffer) override;
+
+		/** @copydoc RenderAPICore::addCommands() */
+		void addCommands(const SPtr<CommandBuffer>& commandBuffer, const SPtr<CommandBuffer>& secondary) override;
+
+		/** @copydoc RenderAPICore::executeCommands() */
+		void executeCommands(const SPtr<CommandBuffer>& commandBuffer) override;
 
 		/** @copydoc RenderAPICore::convertProjectionMatrix() */
 		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest) override;
@@ -146,9 +170,6 @@ namespace BansheeEngine
 		void clearArea(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, 
 			const Rect2I& clearArea = Rect2I::EMPTY, UINT8 targetMask = 0xFF);
 
-		/**	Set up clip planes against which all geometry will get clipped. */
-		void setClipPlanesImpl(const PlaneList& clipPlanes) override;
-
 		/** 
 		 * Changes the currently active texture unit. Any texture related operations will then be performed on this unit. 
 		 */
@@ -410,6 +431,8 @@ namespace BansheeEngine
 			UINT32 uniformIdx;
 		};
 
+		static const UINT32 MAX_VB_COUNT = 32;
+
 		Rect2 mViewportNorm;
 		UINT32 mScissorTop, mScissorBottom, mScissorLeft, mScissorRight;
 		UINT32 mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight;
@@ -420,9 +443,6 @@ namespace BansheeEngine
 		CompareFunction mStencilCompareFront;
 		CompareFunction mStencilCompareBack;
 
-		// View matrix to set world against
-		Matrix4 mViewMatrix;
-
 		// Last min & mip filtering options, so we can combine them
 		FilterOptions mMinFilter;
 		FilterOptions mMipFilter;
@@ -456,7 +476,7 @@ namespace BansheeEngine
 		UINT32 mMaxBoundImageUnits[6];
 		UINT32 mUBOffsets[6];
 
-		Vector<SPtr<VertexBufferCore>> mBoundVertexBuffers;
+		std::array<SPtr<VertexBufferCore>, MAX_VB_COUNT> mBoundVertexBuffers;
 		SPtr<VertexDeclarationCore> mBoundVertexDeclaration;
 		SPtr<IndexBufferCore> mBoundIndexBuffer;
 		DrawOperationType mCurrentDrawOperation;

+ 1 - 1
Source/BansheeGLRenderAPI/Include/BsGLVertexArrayObjectManager.h

@@ -64,7 +64,7 @@ namespace BansheeEngine
 		 * Lifetime of returned VAO is managed by the vertex buffers that it binds.
 		 */
 		const GLVertexArrayObject& getVAO(const SPtr<GLSLGpuProgramCore>& vertexProgram,
-			const SPtr<VertexDeclarationCore>& vertexDecl, const Vector<SPtr<VertexBufferCore>>& boundBuffers);
+			const SPtr<VertexDeclarationCore>& vertexDecl, const std::array<SPtr<VertexBufferCore>, 32>& boundBuffers);
 
 		/**	Called when a vertex buffer containing the provided VAO is destroyed. */
 		void notifyBufferDestroyed(GLVertexArrayObject vao);

+ 56 - 0
Source/BansheeGLRenderAPI/Source/BsGLCommandBuffer.cpp

@@ -0,0 +1,56 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsGLCommandBuffer.h"
+
+namespace BansheeEngine
+{
+	GLCommandBuffer::GLCommandBuffer(CommandBufferType type, UINT32 deviceIdx, UINT32 syncMask, bool secondary)
+		: CommandBuffer(type, syncMask, secondary), mDeviceIdx(deviceIdx), mCurrentDrawOperation(DOT_TRIANGLE_LIST)
+	{
+
+	}
+
+	void GLCommandBuffer::queueCommand(const std::function<void()> command)
+	{
+		mCommands.push_back(command);
+	}
+
+	void GLCommandBuffer::appendSecondary(const SPtr<GLCommandBuffer>& secondaryBuffer)
+	{
+#if BS_DEBUG_MODE
+		if(!secondaryBuffer->mIsSecondary)
+		{
+			LOGERR("Cannot append a command buffer that is not secondary.");
+			return;
+		}
+
+		if(mIsSecondary)
+		{
+			LOGERR("Cannot append a buffer to a secondary command buffer.");
+			return;
+		}
+#endif
+
+		for (auto& entry : secondaryBuffer->mCommands)
+			mCommands.push_back(entry);
+	}
+
+	void GLCommandBuffer::executeCommands()
+	{
+#if BS_DEBUG_MODE
+		if (mIsSecondary)
+		{
+			LOGERR("Cannot execute commands on a secondary buffer.");
+			return;
+		}
+#endif
+
+		for (auto& entry : mCommands)
+			entry();
+	}
+
+	void GLCommandBuffer::clear()
+	{
+		mCommands.clear();
+	}
+}

+ 14 - 0
Source/BansheeGLRenderAPI/Source/BsGLCommandBufferManager.cpp

@@ -0,0 +1,14 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsGLCommandBufferManager.h"
+#include "BsGLCommandBuffer.h"
+
+namespace BansheeEngine
+{
+	SPtr<CommandBuffer> GLCommandBufferManager::create(CommandBufferType type, UINT32 deviceIdx, UINT32 syncMask,
+		bool secondary)
+	{
+		CommandBuffer* buffer = new (bs_alloc<GLCommandBuffer>()) GLCommandBuffer(type, deviceIdx, syncMask, secondary);
+		return bs_shared_ptr(buffer);
+	}
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 473 - 345
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp


+ 1 - 1
Source/BansheeGLRenderAPI/Source/BsGLTextureManager.cpp

@@ -52,7 +52,7 @@ namespace BansheeEngine
 		}
         
         // Check if this is a valid rendertarget format
-		if( usage & TU_RENDERTARGET )
+		if(usage & TU_RENDERTARGET)
         {
             /// Get closest supported alternative
             /// If mFormat is supported it's returned

+ 1 - 1
Source/BansheeGLRenderAPI/Source/BsGLVertexArrayObjectManager.cpp

@@ -76,7 +76,7 @@ namespace BansheeEngine
 	}
 
 	const GLVertexArrayObject& GLVertexArrayObjectManager::getVAO(const SPtr<GLSLGpuProgramCore>& vertexProgram,
-		const SPtr<VertexDeclarationCore>& vertexDecl, const Vector<SPtr<VertexBufferCore>>& boundBuffers)
+		const SPtr<VertexDeclarationCore>& vertexDecl, const std::array<SPtr<VertexBufferCore>, 32>& boundBuffers)
 	{
 		UINT16 maxStreamIdx = 0;
 		const List<VertexElement>& decl = vertexDecl->getProperties().getElements();

+ 7 - 6
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -603,6 +603,7 @@ namespace BansheeEngine
 			}
 
 			RenderAPICore::instance().endFrame();
+			RenderAPICore::instance().executeCommands(gMainCommandBuffer);
 			RenderAPICore::instance().swapBuffers(target);
 		}
 
@@ -905,15 +906,15 @@ namespace BansheeEngine
 			if (params == nullptr)
 				continue;
 
-			const GpuParamDesc& paramDesc = params->getParamDesc();
+			SPtr<GpuParamDesc> paramDesc = params->getParamDesc();
 
-			for (auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
+			for (auto iter = paramDesc->textures.begin(); iter != paramDesc->textures.end(); ++iter)
 			{
 				SPtr<TextureCore> texture = params->getTexture(iter->second.slot);
 				rapi.setTexture(stages[i], iter->second.slot, texture);
 			}
 
-			for (auto iter = paramDesc.loadStoreTextures.begin(); iter != paramDesc.loadStoreTextures.end(); ++iter)
+			for (auto iter = paramDesc->loadStoreTextures.begin(); iter != paramDesc->loadStoreTextures.end(); ++iter)
 			{
 				SPtr<TextureCore> texture = params->getLoadStoreTexture(iter->second.slot);
 				const TextureSurface& surface = params->getLoadStoreSurface(iter->second.slot);
@@ -924,7 +925,7 @@ namespace BansheeEngine
 					rapi.setLoadStoreTexture(stages[i], iter->second.slot, texture, surface);
 			}
 
-			for (auto iter = paramDesc.buffers.begin(); iter != paramDesc.buffers.end(); ++iter)
+			for (auto iter = paramDesc->buffers.begin(); iter != paramDesc->buffers.end(); ++iter)
 			{
 				SPtr<GpuBufferCore> buffer = params->getBuffer(iter->second.slot);
 
@@ -934,7 +935,7 @@ namespace BansheeEngine
 				rapi.setBuffer(stages[i], iter->second.slot, buffer, isLoadStore);
 			}
 
-			for (auto iter = paramDesc.paramBlocks.begin(); iter != paramDesc.paramBlocks.end(); ++iter)
+			for (auto iter = paramDesc->paramBlocks.begin(); iter != paramDesc->paramBlocks.end(); ++iter)
 			{
 				SPtr<GpuParamBlockBufferCore> blockBuffer = params->getParamBlockBuffer(iter->second.slot);
 				blockBuffer->flushToGPU();
@@ -942,7 +943,7 @@ namespace BansheeEngine
 				rapi.setParamBuffer(stages[i], iter->second.slot, blockBuffer, paramDesc);
 			}
 
-			for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
+			for (auto iter = paramDesc->samplers.begin(); iter != paramDesc->samplers.end(); ++iter)
 			{
 				SPtr<SamplerStateCore> samplerState;
 

+ 4 - 4
Source/RenderBeast/Source/BsSamplerOverrides.cpp

@@ -73,9 +73,9 @@ namespace BansheeEngine
 					if (paramsPtr == nullptr)
 						continue;
 
-					const GpuParamDesc& paramDesc = paramsPtr->getParamDesc();
+					SPtr<GpuParamDesc> paramDesc = paramsPtr->getParamDesc();
 
-					for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
+					for (auto iter = paramDesc->samplers.begin(); iter != paramDesc->samplers.end(); ++iter)
 					{
 						UINT32 slot = iter->second.slot;
 						maxSamplerSlot = std::max(maxSamplerSlot, slot + 1);
@@ -116,9 +116,9 @@ namespace BansheeEngine
 					if (paramsPtr == nullptr)
 						continue;
 
-					const GpuParamDesc& paramDesc = paramsPtr->getParamDesc();
+					SPtr<GpuParamDesc> paramDesc = paramsPtr->getParamDesc();
 
-					for (auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
+					for (auto iter = paramDesc->samplers.begin(); iter != paramDesc->samplers.end(); ++iter)
 					{
 						UINT32 slot = iter->second.slot;
 						while (slot > stageOverrides.numStates)

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно