ソースを参照

Added a ComputePipelineState

BearishSun 9 年 前
コミット
af560f18fc

+ 5 - 1
Documentation/Manuals/Native/gpuPrograms.md

@@ -68,7 +68,11 @@ As you can see we must first retrieve a handle to the parameter, and then we can
 See the [render API manual](@ref renderAPI) for more information about how to set and bind GPU program parameters.
 See the [render API manual](@ref renderAPI) for more information about how to set and bind GPU program parameters.
 
 
 # Using GPU programs for rendering {#gpuPrograms_c}
 # Using GPU programs for rendering {#gpuPrograms_c}
-You can bind a GPU program to the pipeline by assigning it to a @ref BansheeEngine::GpuPipelineState "GpuPipelineState" and calling @ref BansheeEngine::RenderAPI::setGraphicsPipeline "RenderAPI::setGraphicsPipeline". Or alternatively if using compute programs you can bind by calling @ref BansheeEngine::RenderAPI::setComputePipeline "RenderAPI::setComputePipeline". Any subsequent draw/dispatch calls will then use the bound GPU programs. 
+You can bind a GPU program to the pipeline by assigning it to a @ref BansheeEngine::GraphicsPipelineState "GraphicsPipelineState" and calling @ref BansheeEngine::RenderAPI::setGraphicsPipeline "RenderAPI::setGraphicsPipeline". 
+
+Or alternatively if using a compute program you can bind it by assigning it to a @ref BansheeEngine::ComputePipelineState "ComputePipelineState" and calling @ref BansheeEngine::RenderAPI::setComputePipeline "RenderAPI::setComputePipeline". 
+
+Once pipeline state is bound, any subsequent draw/dispatch calls will then use the GPU programs attached to that state. 
 
 
 You can bind parameters for use in the GPU program by calling @ref BansheeEngine::RenderAPICore::setGpuParams "RenderAPICore::setGpuParams" which accepts the @ref BansheeEngine::GpuParamsCore "GpuParamsCore" object we described above.
 You can bind parameters for use in the GPU program by calling @ref BansheeEngine::RenderAPICore::setGpuParams "RenderAPICore::setGpuParams" which accepts the @ref BansheeEngine::GpuParamsCore "GpuParamsCore" object we described above.
 
 

+ 11 - 6
Documentation/Manuals/Native/renderAPI.md

@@ -51,7 +51,7 @@ rapi.swapBuffers();
 ~~~~~~~~~~~~~
 ~~~~~~~~~~~~~
  
  
 # Pipeline state {#renderAPI_b}
 # Pipeline state {#renderAPI_b}
-Before executing the drawing operation you must set up an @ref BansheeEngine::GpuPipelineStateCore "GpuPipelineStateCore" object, which contains a set of fixed and programmable states that control primitive rendering. This includes GPU programs (e.g. vertex/fragment) and fixed states (depth-stencil, blend, rasterizer).
+Before executing the drawing operation you must set up an @ref BansheeEngine::GraphicsPipelineStateCore "GraphicsPipelineStateCore" object, which contains a set of fixed and programmable states that control primitive rendering. This includes GPU programs (e.g. vertex/fragment) and fixed states (depth-stencil, blend, rasterizer).
 
 
 To create a pipeline state you must fill out @ref BansheeEngine::PIPELINE_STATE_CORE_DESC "PIPELINE_STATE_CORE_DESC" descriptor, and use it to construct the state, like so:
 To create a pipeline state you must fill out @ref BansheeEngine::PIPELINE_STATE_CORE_DESC "PIPELINE_STATE_CORE_DESC" descriptor, and use it to construct the state, like so:
 ~~~~~~~~~~~~~{.cpp}
 ~~~~~~~~~~~~~{.cpp}
@@ -68,7 +68,7 @@ desc.geometryProgram = ...;
 desc.hullProgram = ...;
 desc.hullProgram = ...;
 desc.domainProgram = ...;
 desc.domainProgram = ...;
 
 
-SPtr<GpuPipelineStateCore> state = GpuPipelineStateCore::create(desc);
+SPtr<GraphicsPipelineStateCore> state = GraphicsPipelineStateCore::create(desc);
 ~~~~~~~~~~~~~
 ~~~~~~~~~~~~~
 
 
 Once created the pipeline can be bound for rendering by calling @ref BansheeEngine::RenderAPICore::setGraphicsPipeline "RenderAPICore::setGraphicsPipeline".
 Once created the pipeline can be bound for rendering by calling @ref BansheeEngine::RenderAPICore::setGraphicsPipeline "RenderAPICore::setGraphicsPipeline".
@@ -80,7 +80,7 @@ RenderAPICore& rapi = RenderAPICore::instance();
 rapi.setGraphicsPipeline(state);
 rapi.setGraphicsPipeline(state);
 ~~~~~~~~~~~~~
 ~~~~~~~~~~~~~
 
 
-We continue below with explanation on how to create fixed and programmable states required to initialize GpuPipelineStateCore.
+We continue below with explanation on how to create fixed and programmable states required to initialize GraphicsPipelineStateCore.
 
 
 ## Fixed pipeline states {#renderAPI_b_a}
 ## Fixed pipeline states {#renderAPI_b_a}
 Fixed pipeline states allow you to control (to some extent) non-programmable parts of the pipeline. This includes anything from blend operations, rasterization mode to depth testing. Setting these states is optional and if not set, default values will be used.
 Fixed pipeline states allow you to control (to some extent) non-programmable parts of the pipeline. This includes anything from blend operations, rasterization mode to depth testing. Setting these states is optional and if not set, default values will be used.
@@ -240,15 +240,19 @@ And this wraps up the rendering pipeline. After this step your object should be
 # Compute {#renderAPI_g}
 # Compute {#renderAPI_g}
 The compute pipeline is a very simple pipeline that can be used for general purpose calculations. It is separate from the graphics pipeline we have been describing so far, but uses the same functionality, just in a more limited way. You don't have to set fixed states, render targets, vertex/index buffers and only one GPU program type is supported (compute GPU program).
 The compute pipeline is a very simple pipeline that can be used for general purpose calculations. It is separate from the graphics pipeline we have been describing so far, but uses the same functionality, just in a more limited way. You don't have to set fixed states, render targets, vertex/index buffers and only one GPU program type is supported (compute GPU program).
 
 
-Use @ref BansheeEngine::RenderAPICore::setComputePipeline "RenderAPICore::setComputePipeline" to initialize the pipeline. When the pipeline is set up you can execute it by calling @ref BansheeEngine::RenderAPICore::dispatchCompute "RenderAPICore::dispatchCompute". You should provide it a three dimensional number that determines how many instances of the currently bound GPU program to execute. The total number of executions will be X * Y * Z.
+The pipeline is represented with the @ref BansheeEngine::ComputePipelineStateCore "ComputePipelineStateCore" object, which must be initialized with the compute GPU program to use.
+
+After creation use @ref BansheeEngine::RenderAPICore::setComputePipeline "RenderAPICore::setComputePipeline" to bind the pipeline for further operations. When the pipeline is set up you can execute it by calling @ref BansheeEngine::RenderAPICore::dispatchCompute "RenderAPICore::dispatchCompute". You should provide it a three dimensional number that determines how many instances of the currently bound GPU program to execute. The total number of executions will be X * Y * Z.
 
 
 Since compute pipeline doesn't support render targets, you will want to use load-store textures for output. An example of a simple compute pipeline:
 Since compute pipeline doesn't support render targets, you will want to use load-store textures for output. An example of a simple compute pipeline:
 ~~~~~~~~~~~~~{.cpp}
 ~~~~~~~~~~~~~{.cpp}
 SPtr<GpuProgramCore> computeProgram = ...;
 SPtr<GpuProgramCore> computeProgram = ...;
 SPtr<GpuParamsCore> computeGpuParams = ...;
 SPtr<GpuParamsCore> computeGpuParams = ...;
 
 
+SPtr<ComputePipelineStateCore> state = ComputePipelineStateCore::create(computeProgram);
+
 RenderAPICore& rapi = RenderAPICore::instance();
 RenderAPICore& rapi = RenderAPICore::instance();
-rapi.setComputePipeline(computeProgram);
+rapi.setComputePipeline(state);
 rapi.setGpuParams(computeGpuParams);
 rapi.setGpuParams(computeGpuParams);
 rapi.dispatchCompute(512, 512);
 rapi.dispatchCompute(512, 512);
 
 
@@ -277,12 +281,13 @@ Command buffer example:
 SPtr<CommandBuffer> cmdBuffer = CommandBuffer::create(CBT_COMPUTE);
 SPtr<CommandBuffer> cmdBuffer = CommandBuffer::create(CBT_COMPUTE);
 SPtr<GpuProgramCore> computeProgram = ...;
 SPtr<GpuProgramCore> computeProgram = ...;
 SPtr<GpuParamsCore> computeGpuParams = ...;
 SPtr<GpuParamsCore> computeGpuParams = ...;
+SPtr<ComputePipelineStateCore> state = ComputePipelineStateCore::create(computeProgram);
 
 
 ... queue up worker thread(s) ...
 ... queue up worker thread(s) ...
 
 
 // Worker thread
 // Worker thread
 RenderAPICore& rapi = RenderAPICore::instance();
 RenderAPICore& rapi = RenderAPICore::instance();
-rapi.setComputePipeline(computeProgram, cmdBuffer);
+rapi.setComputePipeline(state, cmdBuffer);
 rapi.setGpuParams(computeGpuParams, cmdBuffer);
 rapi.setGpuParams(computeGpuParams, cmdBuffer);
 rapi.dispatchCompute(512, 512, cmdBuffer);
 rapi.dispatchCompute(512, 512, cmdBuffer);
 
 

+ 2 - 0
Source/BansheeCore/Include/BsCorePrerequisites.h

@@ -388,6 +388,8 @@ namespace BansheeEngine
 	class CommandBuffer;
 	class CommandBuffer;
 	class GraphicsPipelineState;
 	class GraphicsPipelineState;
 	class GraphicsPipelineStateCore;
 	class GraphicsPipelineStateCore;
+	class ComputePipelineState;
+	class ComputePipelineStateCore;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
 	class Importer;
 	class Importer;

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

@@ -88,7 +88,7 @@ namespace BansheeEngine
 		/**	Gets a descriptor for a data parameter with the specified name. */
 		/**	Gets a descriptor for a data parameter with the specified name. */
 		GpuParamDataDesc* getParamDesc(GpuProgramType type, const String& name) const;
 		GpuParamDataDesc* getParamDesc(GpuProgramType type, const String& name) const;
 
 
-		const SPtr<GpuPipelineParamInfo>& mParamInfo;
+		SPtr<GpuPipelineParamInfo> mParamInfo;
 	};
 	};
 
 
 	template<bool Core> struct TGpuParamsTypes { };
 	template<bool Core> struct TGpuParamsTypes { };

+ 1 - 0
Source/BansheeCore/Include/BsGpuParamsSet.h

@@ -33,6 +33,7 @@ namespace BansheeEngine
 		typedef typename TGpuBufferType<Core>::Type BufferType;
 		typedef typename TGpuBufferType<Core>::Type BufferType;
 		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
 		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
 		typedef typename TPassTypes<Core>::GraphicsPipelineStateType GraphicsPipelineStateType;
 		typedef typename TPassTypes<Core>::GraphicsPipelineStateType GraphicsPipelineStateType;
+		typedef typename TPassTypes<Core>::ComputePipelineStateType ComputePipelineStateType;
 
 
 		/** Information about a parameter block buffer. */
 		/** Information about a parameter block buffer. */
 		struct BlockInfo
 		struct BlockInfo

+ 69 - 2
Source/BansheeCore/Include/BsGpuPipelineState.h

@@ -119,6 +119,31 @@ namespace BansheeEngine
 		SPtr<GpuPipelineParamInfo> mParamInfo;
 		SPtr<GpuPipelineParamInfo> mParamInfo;
     };
     };
 
 
+	/** 
+	 * Templated version of ComputePipelineState so it can be used for both core and non-core versions of the pipeline
+	 * state. 
+	 */
+	template<bool Core>
+	class BS_CORE_EXPORT TComputePipelineState
+    {
+    public:
+		typedef typename TGpuPipelineStateTypes<Core>::GpuProgramType GpuProgramType;
+
+		virtual ~TComputePipelineState() { }
+
+		const GpuProgramType& getProgram() const { return mProgram; }
+
+		/** Returns an object containing meta-data for parameters of the GPU program used in this pipeline state. */
+		const SPtr<GpuPipelineParamInfo>& getParamInfo() const { return mParamInfo; }
+
+	protected:
+		TComputePipelineState();
+		TComputePipelineState(const GpuProgramType& program);
+
+		GpuProgramType mProgram;
+		SPtr<GpuPipelineParamInfo> mParamInfo;
+    };
+
 	/** @} */
 	/** @} */
 
 
 	/** @addtogroup RenderAPI
 	/** @addtogroup RenderAPI
@@ -144,7 +169,7 @@ namespace BansheeEngine
 		 */
 		 */
 		SPtr<GraphicsPipelineStateCore> getCore() const;
 		SPtr<GraphicsPipelineStateCore> getCore() const;
 
 
-		/** @copydoc RenderStateManager::createPipelineState */
+		/** @copydoc RenderStateManager::createGraphicsPipelineState */
 		static SPtr<GraphicsPipelineState> create(const PIPELINE_STATE_DESC& desc);
 		static SPtr<GraphicsPipelineState> create(const PIPELINE_STATE_DESC& desc);
 	protected:
 	protected:
 		friend class RenderStateManager;
 		friend class RenderStateManager;
@@ -155,6 +180,36 @@ namespace BansheeEngine
 		virtual SPtr<CoreObjectCore> createCore() const;
 		virtual SPtr<CoreObjectCore> createCore() const;
     };
     };
 
 
+	class ComputePipelineStateCore;
+
+	/**
+	 * Describes the state of the GPU pipeline that determines how are compute programs executed. It consists of 
+	 * of a single programmable state (GPU program). Once created the state is immutable, and can be bound to RenderAPI for
+	 * use.
+	 */
+    class BS_CORE_EXPORT ComputePipelineState : public CoreObject, public TComputePipelineState<false>
+    {
+	public:
+		virtual ~ComputePipelineState() { }
+
+		/**
+		 * Retrieves a core implementation of the pipeline object usable only from the core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		SPtr<ComputePipelineStateCore> getCore() const;
+
+		/** @copydoc RenderStateManager::createComputePipelineState */
+		static SPtr<ComputePipelineState> create(const SPtr<GpuProgram>& program);
+	protected:
+		friend class RenderStateManager;
+
+		ComputePipelineState(const SPtr<GpuProgram>& program);
+
+		/** @copydoc CoreObject::createCore */
+		virtual SPtr<CoreObjectCore> createCore() const;
+    };
+
 	/** @} */
 	/** @} */
 
 
 	/** @addtogroup RenderAPI-Internal
 	/** @addtogroup RenderAPI-Internal
@@ -168,11 +223,23 @@ namespace BansheeEngine
 		GraphicsPipelineStateCore(const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask);
 		GraphicsPipelineStateCore(const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask);
 		virtual ~GraphicsPipelineStateCore() { }
 		virtual ~GraphicsPipelineStateCore() { }
 
 
-		/** @copydoc RenderStateManager::createPipelineState */
+		/** @copydoc RenderStateManager::createGraphicsPipelineState */
 		static SPtr<GraphicsPipelineStateCore> create(const PIPELINE_STATE_CORE_DESC& desc, 
 		static SPtr<GraphicsPipelineStateCore> create(const PIPELINE_STATE_CORE_DESC& desc, 
 			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 			GpuDeviceFlags deviceMask = GDF_DEFAULT);
 	};
 	};
 
 
+	/** Core thread version of a ComputePipelineState. */
+	class BS_CORE_EXPORT ComputePipelineStateCore : public CoreObjectCore, public TComputePipelineState<true>
+	{
+	public:
+		ComputePipelineStateCore(const SPtr<GpuProgramCore>& program, GpuDeviceFlags deviceMask);
+		virtual ~ComputePipelineStateCore() { }
+
+		/** @copydoc RenderStateManager::createComputePipelineState */
+		static SPtr<ComputePipelineStateCore> create(const SPtr<GpuProgramCore>& program,
+			GpuDeviceFlags deviceMask = GDF_DEFAULT);
+	};
+
 	/** Helper structure used for initializing GpuPipelineParamInfo. */
 	/** Helper structure used for initializing GpuPipelineParamInfo. */
 	struct GPU_PIPELINE_PARAMS_DESC
 	struct GPU_PIPELINE_PARAMS_DESC
 	{
 	{

+ 8 - 3
Source/BansheeCore/Include/BsPass.h

@@ -70,6 +70,7 @@ namespace BansheeEngine
 		typedef SPtr<DepthStencilState> DepthStencilStateType;
 		typedef SPtr<DepthStencilState> DepthStencilStateType;
 		typedef SPtr<GpuProgram> GpuProgramType;
 		typedef SPtr<GpuProgram> GpuProgramType;
 		typedef SPtr<GraphicsPipelineState> GraphicsPipelineStateType;
 		typedef SPtr<GraphicsPipelineState> GraphicsPipelineStateType;
+		typedef SPtr<ComputePipelineState> ComputePipelineStateType;
 		typedef PASS_DESC PassDescType;
 		typedef PASS_DESC PassDescType;
 	};
 	};
 
 
@@ -81,6 +82,7 @@ namespace BansheeEngine
 		typedef SPtr<DepthStencilStateCore> DepthStencilStateType;
 		typedef SPtr<DepthStencilStateCore> DepthStencilStateType;
 		typedef SPtr<GpuProgramCore> GpuProgramType;
 		typedef SPtr<GpuProgramCore> GpuProgramType;
 		typedef SPtr<GraphicsPipelineStateCore> GraphicsPipelineStateType;
 		typedef SPtr<GraphicsPipelineStateCore> GraphicsPipelineStateType;
+		typedef SPtr<ComputePipelineStateCore> ComputePipelineStateType;
 		typedef PASS_DESC_CORE PassDescType;
 		typedef PASS_DESC_CORE PassDescType;
 	};
 	};
 
 
@@ -102,6 +104,7 @@ namespace BansheeEngine
 		typedef typename TPassTypes<Core>::GpuProgramType GpuProgramType;
 		typedef typename TPassTypes<Core>::GpuProgramType GpuProgramType;
 		typedef typename TPassTypes<Core>::PassDescType PassDescType;
 		typedef typename TPassTypes<Core>::PassDescType PassDescType;
 		typedef typename TPassTypes<Core>::GraphicsPipelineStateType GraphicsPipelineStateType;
 		typedef typename TPassTypes<Core>::GraphicsPipelineStateType GraphicsPipelineStateType;
+		typedef typename TPassTypes<Core>::ComputePipelineStateType ComputePipelineStateType;
 
 
 		virtual ~TPass() { }
 		virtual ~TPass() { }
 
 
@@ -129,14 +132,15 @@ namespace BansheeEngine
 		const GpuProgramType& getDomainProgram() const { return mData.domainProgram; }
 		const GpuProgramType& getDomainProgram() const { return mData.domainProgram; }
 		const GpuProgramType& getComputeProgram() const { return mData.computeProgram; }
 		const GpuProgramType& getComputeProgram() const { return mData.computeProgram; }
 
 
-		const GraphicsPipelineStateType& getPipelineState() const { return mPipelineState; }
-
+		const GraphicsPipelineStateType& getGraphicsPipelineState() const { return mGraphicsPipelineState; }
+		const ComputePipelineStateType& getComputePipelineState() const { return mComputePipelineState; }
 	protected:
 	protected:
 		TPass();
 		TPass();
 		TPass(const PassDescType& desc);
 		TPass(const PassDescType& desc);
 
 
 		PassDescType mData;
 		PassDescType mData;
-		GraphicsPipelineStateType mPipelineState;
+		GraphicsPipelineStateType mGraphicsPipelineState;
+		ComputePipelineStateType mComputePipelineState;
     };
     };
 
 
 	/** @} */
 	/** @} */
@@ -168,6 +172,7 @@ namespace BansheeEngine
 		PassCore() { }
 		PassCore() { }
 		PassCore(const PASS_DESC_CORE& desc);
 		PassCore(const PASS_DESC_CORE& desc);
 		PassCore(const PASS_DESC_CORE& desc, const SPtr<GraphicsPipelineStateCore>& pipelineState);
 		PassCore(const PASS_DESC_CORE& desc, const SPtr<GraphicsPipelineStateCore>& pipelineState);
+		PassCore(const PASS_DESC_CORE& desc, const SPtr<ComputePipelineStateCore>& pipelineState);
 
 
 		/** @copydoc CoreObjectCore::syncToCore */
 		/** @copydoc CoreObjectCore::syncToCore */
 		void syncToCore(const CoreSyncData& data) override;
 		void syncToCore(const CoreSyncData& data) override;

+ 3 - 3
Source/BansheeCore/Include/BsRenderAPI.h

@@ -40,7 +40,7 @@ namespace BansheeEngine
 		static void setGraphicsPipeline(CoreAccessor& accessor, const SPtr<GraphicsPipelineState>& pipelineState);
 		static void setGraphicsPipeline(CoreAccessor& accessor, const SPtr<GraphicsPipelineState>& pipelineState);
 
 
 		/** @see RenderAPICore::setComputePipeline() */
 		/** @see RenderAPICore::setComputePipeline() */
-		static void setComputePipeline(CoreAccessor& accessor, const SPtr<GpuProgram>& computeProgram);
+		static void setComputePipeline(CoreAccessor& accessor, const SPtr<ComputePipelineState>& pipelineState);
 
 
 		/** @see RenderAPICore::setVertexBuffers() */
 		/** @see RenderAPICore::setVertexBuffers() */
 		static void setVertexBuffers(CoreAccessor& accessor, UINT32 index, const Vector<SPtr<VertexBuffer>>& buffers);
 		static void setVertexBuffers(CoreAccessor& accessor, UINT32 index, const Vector<SPtr<VertexBuffer>>& buffers);
@@ -225,12 +225,12 @@ namespace BansheeEngine
 		/**
 		/**
 		 * Sets a pipeline state that controls how will subsequent dispatch commands execute.
 		 * Sets a pipeline state that controls how will subsequent dispatch commands execute.
 		 *
 		 *
-		 * @param[in]	computeProgram		Compute program to bind to the pipeline.
+		 * @param[in]	pipelineState		Pipeline state to bind, or null to unbind.
 		 * @param[in]	commandBuffer		Optional command buffer to queue the operation on. If not provided operation
 		 * @param[in]	commandBuffer		Optional command buffer to queue the operation on. If not provided operation
 		 *									is executed immediately. Otherwise it is executed when executeCommands() is 
 		 *									is executed immediately. Otherwise it is executed when executeCommands() is 
 		 *									called. Buffer must support graphics operations.
 		 *									called. Buffer must support graphics operations.
 		 */
 		 */
-		virtual void setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+		virtual void setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) = 0;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) = 0;
 
 
 		/**
 		/**

+ 20 - 3
Source/BansheeCore/Include/BsRenderStateManager.h

@@ -35,6 +35,9 @@ namespace BansheeEngine
 		/**	Creates and initializes a new GraphicsPipelineState. */
 		/**	Creates and initializes a new GraphicsPipelineState. */
 		SPtr<GraphicsPipelineState> createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const;
 		SPtr<GraphicsPipelineState> createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const;
 
 
+		/**	Creates and initializes a new ComputePipelineState. */
+		SPtr<ComputePipelineState> createComputePipelineState(const SPtr<GpuProgram>& program) const;
+
 		/** Creates an uninitialized sampler state. Requires manual initialization after creation. */
 		/** Creates an uninitialized sampler state. Requires manual initialization after creation. */
 		SPtr<SamplerState> _createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const;
 		SPtr<SamplerState> _createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const;
 
 
@@ -50,6 +53,9 @@ namespace BansheeEngine
 		/**	Creates an uninitialized GraphicsPipelineState. Requires manual initialization after creation. */
 		/**	Creates an uninitialized GraphicsPipelineState. Requires manual initialization after creation. */
 		virtual SPtr<GraphicsPipelineState> _createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const;
 		virtual SPtr<GraphicsPipelineState> _createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const;
 
 
+		/**	Creates an uninitialized ComputePipelineState. Requires manual initialization after creation. */
+		virtual SPtr<ComputePipelineState> _createComputePipelineState(const SPtr<GpuProgram>& program) const;
+
 		/** Gets a sampler state initialized with default options. */
 		/** Gets a sampler state initialized with default options. */
 		const SPtr<SamplerState>& getDefaultSamplerState() const;
 		const SPtr<SamplerState>& getDefaultSamplerState() const;
 
 
@@ -143,10 +149,17 @@ namespace BansheeEngine
 		SPtr<BlendStateCore> createBlendState(const BLEND_STATE_DESC& desc) const;
 		SPtr<BlendStateCore> createBlendState(const BLEND_STATE_DESC& desc) const;
 
 
 		/** 
 		/** 
-		 * @copydoc RenderStateManager::createPipelineState 
+		 * @copydoc RenderStateManager::createGraphicsPipelineState 
+		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
+		 */
+		SPtr<GraphicsPipelineStateCore> createGraphicsPipelineState(const PIPELINE_STATE_CORE_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
+
+		/** 
+		 * @copydoc RenderStateManager::createComputePipelineState 
 		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
 		 * @param[in]	deviceMask		Mask that determines on which GPU devices should the object be created on.
 		 */
 		 */
-		SPtr<GraphicsPipelineStateCore> createPipelineState(const PIPELINE_STATE_CORE_DESC& desc, 
+		SPtr<ComputePipelineStateCore> createComputePipelineState(const SPtr<GpuProgramCore>& program,
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
 
 
 		/** Creates an uninitialized sampler state. Requires manual initialization after creation. */
 		/** Creates an uninitialized sampler state. Requires manual initialization after creation. */
@@ -163,9 +176,13 @@ namespace BansheeEngine
 		SPtr<BlendStateCore> _createBlendState(const BLEND_STATE_DESC& desc) const;
 		SPtr<BlendStateCore> _createBlendState(const BLEND_STATE_DESC& desc) const;
 
 
 		/**	Creates an uninitialized GraphicsPipelineState. Requires manual initialization after creation. */
 		/**	Creates an uninitialized GraphicsPipelineState. Requires manual initialization after creation. */
-		virtual SPtr<GraphicsPipelineStateCore> _createPipelineState(const PIPELINE_STATE_CORE_DESC& desc, 
+		virtual SPtr<GraphicsPipelineStateCore> _createGraphicsPipelineState(const PIPELINE_STATE_CORE_DESC& desc, 
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
 
 
+		/**	Creates an uninitialized ComputePipelineState. Requires manual initialization after creation. */
+		virtual SPtr<ComputePipelineStateCore> _createComputePipelineState(const SPtr<GpuProgramCore>& program,
+																		   GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
+
 		/** Gets a sampler state initialized with default options. */
 		/** Gets a sampler state initialized with default options. */
 		const SPtr<SamplerStateCore>& getDefaultSamplerState() const;
 		const SPtr<SamplerStateCore>& getDefaultSamplerState() const;
 
 

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

@@ -474,9 +474,15 @@ namespace BansheeEngine
 		for (UINT32 i = 0; i < numPasses; i++)
 		for (UINT32 i = 0; i < numPasses; i++)
 		{
 		{
 			SPtr<PassType> curPass = technique->getPass(i);
 			SPtr<PassType> curPass = technique->getPass(i);
-			GraphicsPipelineStateType pipeline = curPass->getPipelineState();
 
 
-			mPassParams[i] = GpuParamsType::create(pipeline->getParamInfo());
+			GraphicsPipelineStateType gfxPipeline = curPass->getGraphicsPipelineState();
+			if(gfxPipeline != nullptr)
+				mPassParams[i] = GpuParamsType::create(gfxPipeline->getParamInfo());
+			else
+			{
+				ComputePipelineStateType computePipeline = curPass->getComputePipelineState();
+				mPassParams[i] = GpuParamsType::create(computePipeline->getParamInfo());
+			}
 		}
 		}
 
 
 		// Create and assign parameter block buffers
 		// Create and assign parameter block buffers

+ 64 - 7
Source/BansheeCore/Source/BsGpuPipelineState.cpp

@@ -23,6 +23,17 @@ namespace BansheeEngine
 		output.domainProgram = input.domainProgram != nullptr ? input.domainProgram->getCore() : nullptr;
 		output.domainProgram = input.domainProgram != nullptr ? input.domainProgram->getCore() : nullptr;
 	}
 	}
 
 
+	SPtr<GpuParamDesc> getParamDesc(const SPtr<GpuProgram>& program)
+	{
+		program->blockUntilCoreInitialized();
+		return program->getParamDesc();
+	}
+
+	SPtr<GpuParamDesc> getParamDesc(const SPtr<GpuProgramCore>& program)
+	{
+		return program->getParamDesc();
+	}
+
 	template<bool Core>
 	template<bool Core>
 	TGraphicsPipelineState<Core>::TGraphicsPipelineState()
 	TGraphicsPipelineState<Core>::TGraphicsPipelineState()
 	{ }
 	{ }
@@ -33,19 +44,19 @@ namespace BansheeEngine
 	{
 	{
 		GPU_PIPELINE_PARAMS_DESC paramsDesc;
 		GPU_PIPELINE_PARAMS_DESC paramsDesc;
 		if (data.vertexProgram != nullptr)
 		if (data.vertexProgram != nullptr)
-			paramsDesc.vertexParams = data.vertexProgram->getParamDesc();
+			paramsDesc.vertexParams = getParamDesc(data.vertexProgram);
 
 
 		if (data.fragmentProgram != nullptr)
 		if (data.fragmentProgram != nullptr)
-			paramsDesc.fragmentParams = data.fragmentProgram->getParamDesc();
+			paramsDesc.fragmentParams = getParamDesc(data.fragmentProgram);
 
 
 		if (data.geometryProgram != nullptr)
 		if (data.geometryProgram != nullptr)
-			paramsDesc.geometryParams = data.geometryProgram->getParamDesc();
+			paramsDesc.geometryParams = getParamDesc(data.geometryProgram);
 
 
 		if (data.hullProgram != nullptr)
 		if (data.hullProgram != nullptr)
-			paramsDesc.hullParams = data.hullProgram->getParamDesc();
+			paramsDesc.hullParams = getParamDesc(data.hullProgram);
 
 
 		if (data.domainProgram != nullptr)
 		if (data.domainProgram != nullptr)
-			paramsDesc.domainParams = data.domainProgram->getParamDesc();
+			paramsDesc.domainParams = getParamDesc(data.domainProgram);
 
 
 		mParamInfo = GpuPipelineParamInfo::create(paramsDesc);
 		mParamInfo = GpuPipelineParamInfo::create(paramsDesc);
 	}
 	}
@@ -59,7 +70,7 @@ namespace BansheeEngine
 
 
 	SPtr<GraphicsPipelineStateCore> GraphicsPipelineStateCore::create(const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask)
 	SPtr<GraphicsPipelineStateCore> GraphicsPipelineStateCore::create(const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask)
 	{
 	{
-		return RenderStateCoreManager::instance().createPipelineState(desc, deviceMask);
+		return RenderStateCoreManager::instance().createGraphicsPipelineState(desc, deviceMask);
 	}
 	}
 
 
 	GraphicsPipelineState::GraphicsPipelineState(const PIPELINE_STATE_DESC& desc)
 	GraphicsPipelineState::GraphicsPipelineState(const PIPELINE_STATE_DESC& desc)
@@ -76,7 +87,7 @@ namespace BansheeEngine
 		PIPELINE_STATE_CORE_DESC desc;
 		PIPELINE_STATE_CORE_DESC desc;
 		convertPassDesc(mData, desc);
 		convertPassDesc(mData, desc);
 
 
-		return RenderStateCoreManager::instance()._createPipelineState(desc);
+		return RenderStateCoreManager::instance()._createGraphicsPipelineState(desc);
 	}
 	}
 
 
 	SPtr<GraphicsPipelineState> GraphicsPipelineState::create(const PIPELINE_STATE_DESC& desc)
 	SPtr<GraphicsPipelineState> GraphicsPipelineState::create(const PIPELINE_STATE_DESC& desc)
@@ -84,6 +95,52 @@ namespace BansheeEngine
 		return RenderStateManager::instance().createGraphicsPipelineState(desc);
 		return RenderStateManager::instance().createGraphicsPipelineState(desc);
 	}
 	}
 
 
+	template<bool Core>
+	TComputePipelineState<Core>::TComputePipelineState()
+	{ }
+
+	template<bool Core>
+	TComputePipelineState<Core>::TComputePipelineState(const GpuProgramType& program)
+		:mProgram(program)
+	{
+		GPU_PIPELINE_PARAMS_DESC paramsDesc;
+		paramsDesc.computeParams = getParamDesc(program);
+
+		mParamInfo = GpuPipelineParamInfo::create(paramsDesc);
+	}
+
+	template class TComputePipelineState < false >;
+	template class TComputePipelineState < true >;
+
+	ComputePipelineStateCore::ComputePipelineStateCore(const SPtr<GpuProgramCore>& program, GpuDeviceFlags deviceMask)
+		:TComputePipelineState(program)
+	{ }
+
+	SPtr<ComputePipelineStateCore> ComputePipelineStateCore::create(const SPtr<GpuProgramCore>& program, 
+		GpuDeviceFlags deviceMask)
+	{
+		return RenderStateCoreManager::instance().createComputePipelineState(program, deviceMask);
+	}
+
+	ComputePipelineState::ComputePipelineState(const SPtr<GpuProgram>& program)
+		:TComputePipelineState(program)
+	{ }
+
+	SPtr<ComputePipelineStateCore> ComputePipelineState::getCore() const
+	{
+		return std::static_pointer_cast<ComputePipelineStateCore>(mCoreSpecific);
+	}
+
+	SPtr<CoreObjectCore> ComputePipelineState::createCore() const
+	{
+		return RenderStateCoreManager::instance()._createComputePipelineState(mProgram->getCore());
+	}
+
+	SPtr<ComputePipelineState> ComputePipelineState::create(const SPtr<GpuProgram>& program)
+	{
+		return RenderStateManager::instance().createComputePipelineState(program);
+	}
+
 	GpuPipelineParamInfo::GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc)
 	GpuPipelineParamInfo::GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc)
 		:mTotalNumSets(0)
 		:mTotalNumSets(0)
 	{
 	{

+ 41 - 13
Source/BansheeCore/Source/BsPass.cpp

@@ -102,18 +102,32 @@ namespace BansheeEngine
 	PassCore::PassCore(const PASS_DESC_CORE& desc, const SPtr<GraphicsPipelineStateCore>& pipelineState)
 	PassCore::PassCore(const PASS_DESC_CORE& desc, const SPtr<GraphicsPipelineStateCore>& pipelineState)
 		:TPass(desc)
 		:TPass(desc)
 	{
 	{
-		mPipelineState = pipelineState;
+		mGraphicsPipelineState = pipelineState;
+	}
+
+
+	PassCore::PassCore(const PASS_DESC_CORE& desc, const SPtr<ComputePipelineStateCore>& pipelineState)
+		:TPass(desc)
+	{
+		mComputePipelineState = pipelineState;
 	}
 	}
 
 
 	void PassCore::initialize()
 	void PassCore::initialize()
 	{
 	{
-		// Create pipeline state unless it's already provided, or unless it's a compute pass
-		if (mPipelineState == nullptr && !hasComputeProgram())
+		if(hasComputeProgram())
 		{
 		{
-			PIPELINE_STATE_CORE_DESC desc;
-			convertPassDesc(mData, desc);
+			if(mComputePipelineState == nullptr)
+				mComputePipelineState = ComputePipelineStateCore::create(getComputeProgram());
+		}
+		else
+		{
+			if (mGraphicsPipelineState == nullptr)
+			{
+				PIPELINE_STATE_CORE_DESC desc;
+				convertPassDesc(mData, desc);
 
 
-			mPipelineState = GraphicsPipelineStateCore::create(desc);
+				mGraphicsPipelineState = GraphicsPipelineStateCore::create(desc);
+			}
 		}
 		}
 
 
 		CoreObjectCore::initialize();
 		CoreObjectCore::initialize();
@@ -152,11 +166,21 @@ namespace BansheeEngine
 		PASS_DESC_CORE desc;
 		PASS_DESC_CORE desc;
 		convertPassDesc(mData, desc);
 		convertPassDesc(mData, desc);
 
 
-		SPtr<GraphicsPipelineStateCore> corePipeline;
-		if (mPipelineState != nullptr)
-			corePipeline = mPipelineState->getCore();
+		PassCore* pass;
+		if(mComputePipelineState != nullptr)
+		{
+			SPtr<ComputePipelineStateCore> corePipeline = mComputePipelineState->getCore();
+			pass = new (bs_alloc<PassCore>()) PassCore(desc, corePipeline);
+		}
+		else
+		{
+			SPtr<GraphicsPipelineStateCore> corePipeline;
+			if (mGraphicsPipelineState != nullptr)
+				corePipeline = mGraphicsPipelineState->getCore();
+
+			pass = new (bs_alloc<PassCore>()) PassCore(desc, corePipeline);
+		}
 
 
-		PassCore* pass = new (bs_alloc<PassCore>()) PassCore(desc, corePipeline);
 		SPtr<PassCore> passPtr = bs_shared_ptr<PassCore>(pass);
 		SPtr<PassCore> passPtr = bs_shared_ptr<PassCore>(pass);
 		passPtr->_setThisPtr(passPtr);
 		passPtr->_setThisPtr(passPtr);
 
 
@@ -165,13 +189,17 @@ namespace BansheeEngine
 
 
 	void Pass::initialize()
 	void Pass::initialize()
 	{
 	{
-		// Create pipeline state unless it's a compute pass
-		if (!hasComputeProgram())
+		// Create pipeline state
+		if (hasComputeProgram())
+		{
+			mComputePipelineState = ComputePipelineState::create(getComputeProgram());
+		}
+		else
 		{
 		{
 			PIPELINE_STATE_DESC desc;
 			PIPELINE_STATE_DESC desc;
 			convertPassDesc(mData, desc);
 			convertPassDesc(mData, desc);
 
 
-			mPipelineState = GraphicsPipelineState::create(desc);
+			mGraphicsPipelineState = GraphicsPipelineState::create(desc);
 		}
 		}
 
 
 		CoreObject::initialize();
 		CoreObject::initialize();

+ 2 - 2
Source/BansheeCore/Source/BsRenderAPI.cpp

@@ -29,10 +29,10 @@ namespace BansheeEngine
 			pipelineState->getCore(), nullptr));
 			pipelineState->getCore(), nullptr));
 	}
 	}
 
 
-	void RenderAPI::setComputePipeline(CoreAccessor& accessor, const SPtr<GpuProgram>& computeProgram)
+	void RenderAPI::setComputePipeline(CoreAccessor& accessor, const SPtr<ComputePipelineState>& pipelineState)
 	{
 	{
 		accessor.queueCommand(std::bind(&RenderAPICore::setComputePipeline, RenderAPICore::instancePtr(),
 		accessor.queueCommand(std::bind(&RenderAPICore::setComputePipeline, RenderAPICore::instancePtr(),
-			computeProgram->getCore(), nullptr));
+							  pipelineState->getCore(), nullptr));
 	}
 	}
 
 
 	void RenderAPI::setVertexBuffers(CoreAccessor& accessor, UINT32 index, const Vector<SPtr<VertexBuffer>>& buffers)
 	void RenderAPI::setVertexBuffers(CoreAccessor& accessor, UINT32 index, const Vector<SPtr<VertexBuffer>>& buffers)

+ 44 - 4
Source/BansheeCore/Source/BsRenderStateManager.cpp

@@ -48,6 +48,14 @@ namespace BansheeEngine
 		return state;
 		return state;
 	}
 	}
 
 
+	SPtr<ComputePipelineState> RenderStateManager::createComputePipelineState(const SPtr<GpuProgram>& program) const
+	{
+		SPtr<ComputePipelineState> state = _createComputePipelineState(program);
+		state->initialize();
+
+		return state;
+	}
+
 	SPtr<SamplerState> RenderStateManager::_createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const
 	SPtr<SamplerState> RenderStateManager::_createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const
 	{
 	{
 		SPtr<SamplerState> samplerState = bs_core_ptr<SamplerState>(new (bs_alloc<SamplerState>()) SamplerState(desc));
 		SPtr<SamplerState> samplerState = bs_core_ptr<SamplerState>(new (bs_alloc<SamplerState>()) SamplerState(desc));
@@ -89,6 +97,15 @@ namespace BansheeEngine
 		return pipelineState;
 		return pipelineState;
 	}
 	}
 
 
+	SPtr<ComputePipelineState> RenderStateManager::_createComputePipelineState(const SPtr<GpuProgram>& program) const
+	{
+		SPtr<ComputePipelineState> pipelineState =
+			bs_core_ptr<ComputePipelineState>(new (bs_alloc<ComputePipelineState>()) ComputePipelineState(program));
+		pipelineState->_setThisPtr(pipelineState);
+
+		return pipelineState;
+	}
+
 	const SPtr<SamplerState>& RenderStateManager::getDefaultSamplerState() const 
 	const SPtr<SamplerState>& RenderStateManager::getDefaultSamplerState() const 
 	{ 
 	{ 
 		if(mDefaultSamplerState == nullptr)
 		if(mDefaultSamplerState == nullptr)
@@ -196,10 +213,19 @@ namespace BansheeEngine
 		return state;
 		return state;
 	}
 	}
 
 
-	SPtr<GraphicsPipelineStateCore> RenderStateCoreManager::createPipelineState(const PIPELINE_STATE_CORE_DESC& desc, 
+	SPtr<GraphicsPipelineStateCore> RenderStateCoreManager::createGraphicsPipelineState(const PIPELINE_STATE_CORE_DESC& desc, 
 		GpuDeviceFlags deviceMask) const
 		GpuDeviceFlags deviceMask) const
 	{
 	{
-		SPtr<GraphicsPipelineStateCore> state = _createPipelineState(desc, deviceMask);
+		SPtr<GraphicsPipelineStateCore> state = _createGraphicsPipelineState(desc, deviceMask);
+		state->initialize();
+
+		return state;
+	}
+
+	SPtr<ComputePipelineStateCore> RenderStateCoreManager::createComputePipelineState(const SPtr<GpuProgramCore>& program,
+																					  GpuDeviceFlags deviceMask) const
+	{
+		SPtr<ComputePipelineStateCore> state = _createComputePipelineState(program, deviceMask);
 		state->initialize();
 		state->initialize();
 
 
 		return state;
 		return state;
@@ -270,11 +296,25 @@ namespace BansheeEngine
 		return state;
 		return state;
 	}
 	}
 
 
-	SPtr<GraphicsPipelineStateCore> RenderStateCoreManager::_createPipelineState(const PIPELINE_STATE_CORE_DESC& desc,
+	SPtr<GraphicsPipelineStateCore> RenderStateCoreManager::_createGraphicsPipelineState(const PIPELINE_STATE_CORE_DESC& desc,
 		GpuDeviceFlags deviceMask) const
 		GpuDeviceFlags deviceMask) const
 	{
 	{
 		SPtr<GraphicsPipelineStateCore> pipelineState =
 		SPtr<GraphicsPipelineStateCore> pipelineState =
-			bs_shared_ptr<GraphicsPipelineStateCore>(new (bs_alloc<GraphicsPipelineStateCore>()) GraphicsPipelineStateCore(desc, deviceMask));
+			bs_shared_ptr<GraphicsPipelineStateCore>(new (bs_alloc<GraphicsPipelineStateCore>()) 
+			GraphicsPipelineStateCore(desc, deviceMask));
+
+		pipelineState->_setThisPtr(pipelineState);
+
+		return pipelineState;
+	}
+
+	SPtr<ComputePipelineStateCore> RenderStateCoreManager::_createComputePipelineState(const SPtr<GpuProgramCore>& program,
+																					   GpuDeviceFlags deviceMask) const
+	{
+		SPtr<ComputePipelineStateCore> pipelineState =
+			bs_shared_ptr<ComputePipelineStateCore>(new (bs_alloc<ComputePipelineStateCore>()) 
+			ComputePipelineStateCore(program, deviceMask));
+
 		pipelineState->_setThisPtr(pipelineState);
 		pipelineState->_setThisPtr(pipelineState);
 
 
 		return pipelineState;
 		return pipelineState;

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

@@ -29,7 +29,7 @@ namespace BansheeEngine
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 
 		/** @copydoc RenderAPICore::setComputePipeline */
 		/** @copydoc RenderAPICore::setComputePipeline */
-		void setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+		void setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 
 		/** @copydoc RenderAPICore::setGpuParams */
 		/** @copydoc RenderAPICore::setGpuParams */

+ 10 - 6
Source/BansheeD3D11RenderAPI/Source/BsD3D11RenderAPI.cpp

@@ -303,16 +303,20 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 	}
 	}
 
 
-	void D3D11RenderAPI::setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+	void D3D11RenderAPI::setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 		const SPtr<CommandBuffer>& commandBuffer)
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
 	{
-		auto executeRef = [&](const SPtr<GpuProgramCore>& computeProgram)
+		auto executeRef = [&](const SPtr<ComputePipelineStateCore>& pipelineState)
 		{
 		{
 			THROW_IF_NOT_CORE_THREAD;
 			THROW_IF_NOT_CORE_THREAD;
 
 
-			if (computeProgram != nullptr && computeProgram->getProperties().getType() == GPT_COMPUTE_PROGRAM)
+			SPtr<GpuProgramCore> program;
+			if (pipelineState != nullptr)
+				program = pipelineState->getProgram();
+
+			if (program != nullptr && program->getProperties().getType() == GPT_COMPUTE_PROGRAM)
 			{
 			{
-				D3D11GpuComputeProgramCore *d3d11ComputeProgram = static_cast<D3D11GpuComputeProgramCore*>(computeProgram.get());
+				D3D11GpuComputeProgramCore *d3d11ComputeProgram = static_cast<D3D11GpuComputeProgramCore*>(program.get());
 				mDevice->getImmediateContext()->CSSetShader(d3d11ComputeProgram->getComputeShader(), nullptr, 0);
 				mDevice->getImmediateContext()->CSSetShader(d3d11ComputeProgram->getComputeShader(), nullptr, 0);
 			}
 			}
 			else
 			else
@@ -320,10 +324,10 @@ namespace BansheeEngine
 		};
 		};
 
 
 		if (commandBuffer == nullptr)
 		if (commandBuffer == nullptr)
-			executeRef(computeProgram);
+			executeRef(pipelineState);
 		else
 		else
 		{
 		{
-			auto execute = [=]() { executeRef(computeProgram); };
+			auto execute = [=]() { executeRef(pipelineState); };
 
 
 			SPtr<D3D11CommandBuffer> cb = std::static_pointer_cast<D3D11CommandBuffer>(commandBuffer);
 			SPtr<D3D11CommandBuffer> cb = std::static_pointer_cast<D3D11CommandBuffer>(commandBuffer);
 			cb->queueCommand(execute);
 			cb->queueCommand(execute);

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

@@ -122,7 +122,7 @@ namespace BansheeEngine
 		RenderAPICore& rapi = RenderAPICore::instance();
 		RenderAPICore& rapi = RenderAPICore::instance();
 
 
 		SPtr<PassCore> pass = material->getPass(passIdx, techniqueIdx);
 		SPtr<PassCore> pass = material->getPass(passIdx, techniqueIdx);
-		rapi.setGraphicsPipeline(pass->getPipelineState());
+		rapi.setGraphicsPipeline(pass->getGraphicsPipelineState());
 		rapi.setStencilRef(pass->getStencilRefValue());
 		rapi.setStencilRef(pass->getStencilRefValue());
 	}
 	}
 
 
@@ -131,7 +131,7 @@ namespace BansheeEngine
 		RenderAPICore& rapi = RenderAPICore::instance();
 		RenderAPICore& rapi = RenderAPICore::instance();
 
 
 		SPtr<PassCore> pass = material->getPass(passIdx);
 		SPtr<PassCore> pass = material->getPass(passIdx);
-		rapi.setComputePipeline(pass->getComputeProgram());
+		rapi.setComputePipeline(pass->getComputePipelineState());
 	}
 	}
 
 
 	void RendererUtility::setPassParams(const SPtr<GpuParamsSetCore>& params, UINT32 passIdx)
 	void RendererUtility::setPassParams(const SPtr<GpuParamsSetCore>& params, UINT32 passIdx)

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

@@ -32,7 +32,7 @@ namespace BansheeEngine
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 
 		/** @copydoc RenderAPICore::setComputePipeline */
 		/** @copydoc RenderAPICore::setComputePipeline */
-		void setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+		void setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 
 		/** @copydoc RenderAPICore::setGpuParams() */
 		/** @copydoc RenderAPICore::setGpuParams() */

+ 10 - 6
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -311,24 +311,28 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 	}
 	}
 
 
-	void GLRenderAPI::setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+	void GLRenderAPI::setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 		const SPtr<CommandBuffer>& commandBuffer)
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
 	{
-		auto executeRef = [&](const SPtr<GpuProgramCore>& computeProgram)
+		auto executeRef = [&](const SPtr<ComputePipelineStateCore>& pipelineState)
 		{
 		{
 			THROW_IF_NOT_CORE_THREAD;
 			THROW_IF_NOT_CORE_THREAD;
 
 
-			if (computeProgram != nullptr && computeProgram->getProperties().getType() == GPT_COMPUTE_PROGRAM)
-				mCurrentComputeProgram = std::static_pointer_cast<GLSLGpuProgramCore>(computeProgram);
+			SPtr<GpuProgramCore> program;
+			if (pipelineState != nullptr)
+				program = pipelineState->getProgram();
+
+			if (program != nullptr && program->getProperties().getType() == GPT_COMPUTE_PROGRAM)
+				mCurrentComputeProgram = std::static_pointer_cast<GLSLGpuProgramCore>(program);
 			else
 			else
 				mCurrentComputeProgram = nullptr;
 				mCurrentComputeProgram = nullptr;
 		};
 		};
 
 
 		if (commandBuffer == nullptr)
 		if (commandBuffer == nullptr)
-			executeRef(computeProgram);
+			executeRef(pipelineState);
 		else
 		else
 		{
 		{
-			auto execute = [=]() { executeRef(computeProgram); };
+			auto execute = [=]() { executeRef(pipelineState); };
 
 
 			SPtr<GLCommandBuffer> cb = std::static_pointer_cast<GLCommandBuffer>(commandBuffer);
 			SPtr<GLCommandBuffer> cb = std::static_pointer_cast<GLCommandBuffer>(commandBuffer);
 			cb->queueCommand(execute);
 			cb->queueCommand(execute);

+ 1 - 1
Source/BansheeVulkanRenderAPI/Include/BsVulkanRenderAPI.h

@@ -29,7 +29,7 @@ namespace BansheeEngine
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 
 		/** @copydoc RenderAPICore::setComputePipeline */
 		/** @copydoc RenderAPICore::setComputePipeline */
-		void setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+		void setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 
 		/** @copydoc RenderAPICore::setGpuParams */
 		/** @copydoc RenderAPICore::setGpuParams */

+ 2 - 2
Source/BansheeVulkanRenderAPI/Include/BsVulkanRenderStateManager.h

@@ -19,8 +19,8 @@ namespace BansheeEngine
 		SPtr<SamplerStateCore> createSamplerStateInternal(const SAMPLER_STATE_DESC& desc,
 		SPtr<SamplerStateCore> createSamplerStateInternal(const SAMPLER_STATE_DESC& desc,
 			GpuDeviceFlags deviceMask) const override;
 			GpuDeviceFlags deviceMask) const override;
 
 
-		/** @copydoc RenderStateCoreManager::_createPipelineState */
-		SPtr<GraphicsPipelineStateCore> _createPipelineState(const PIPELINE_STATE_CORE_DESC& desc,
+		/** @copydoc RenderStateCoreManager::_createGraphicsPipelineState */
+		SPtr<GraphicsPipelineStateCore> _createGraphicsPipelineState(const PIPELINE_STATE_CORE_DESC& desc,
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) const override;
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) const override;
 	};
 	};
 
 

+ 1 - 1
Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderAPI.cpp

@@ -312,7 +312,7 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 	}
 	}
 
 
-	void VulkanRenderAPI::setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
+	void VulkanRenderAPI::setComputePipeline(const SPtr<ComputePipelineStateCore>& pipelineState,
 		const SPtr<CommandBuffer>& commandBuffer)
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
 	{
 		// TODO
 		// TODO

+ 4 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderStateManager.cpp

@@ -16,11 +16,12 @@ namespace BansheeEngine
 		return samplerState;
 		return samplerState;
 	}
 	}
 
 
-	SPtr<GraphicsPipelineStateCore> VulkanRenderStateCoreManager::_createPipelineState(const PIPELINE_STATE_CORE_DESC& desc,
-		GpuDeviceFlags deviceMask) const
+	SPtr<GraphicsPipelineStateCore> VulkanRenderStateCoreManager::_createGraphicsPipelineState(
+		const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask) const
 	{
 	{
 		SPtr<VulkanGraphicsPipelineStateCore> pipelineState =
 		SPtr<VulkanGraphicsPipelineStateCore> pipelineState =
-			bs_shared_ptr<VulkanGraphicsPipelineStateCore>(new (bs_alloc<VulkanGraphicsPipelineStateCore>()) VulkanGraphicsPipelineStateCore(desc, deviceMask));
+			bs_shared_ptr<VulkanGraphicsPipelineStateCore>(new (bs_alloc<VulkanGraphicsPipelineStateCore>()) 
+			VulkanGraphicsPipelineStateCore(desc, deviceMask));
 		pipelineState->_setThisPtr(pipelineState);
 		pipelineState->_setThisPtr(pipelineState);
 
 
 		return pipelineState;
 		return pipelineState;