| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// | 
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// | 
| 3 | #pragma once | 
| 4 |  | 
| 5 | #include "BsCorePrerequisites.h" | 
| 6 | #include "Material/BsMaterial.h" | 
| 7 | #include "Material/BsShader.h" | 
| 8 | #include "Material/BsPass.h" | 
| 9 |  | 
| 10 | namespace bs | 
| 11 | { | 
| 12 | 	/** @addtogroup Implementation | 
| 13 | 	 *  @{ | 
| 14 | 	 */ | 
| 15 |  | 
| 16 | 	/** Contains a set of GpuParams used for a single technique within a Material. */ | 
| 17 | 	template<bool Core> | 
| 18 | 	class BS_CORE_EXPORT TGpuParamsSet | 
| 19 | 	{ | 
| 20 | 		using GpuParamsType = CoreVariantType<GpuParams, Core>; | 
| 21 | 		using MaterialParamsType = CoreVariantType<MaterialParams, Core>; | 
| 22 | 		using ParamBlockPtrType = SPtr<CoreVariantType<GpuParamBlockBuffer, Core>>; | 
| 23 | 		using TechniqueType = CoreVariantType<Technique, Core>; | 
| 24 | 		using ShaderType = CoreVariantHandleType<Shader, Core>; | 
| 25 | 		using PassType = CoreVariantType<Pass, Core>; | 
| 26 | 		using GpuProgramPtrType = SPtr<CoreVariantType<GpuProgram, Core>>; | 
| 27 | 		using ParamBlockType = CoreVariantType<GpuParamBlockBuffer, Core>; | 
| 28 | 		using TextureType = CoreVariantHandleType<Texture, Core>; | 
| 29 | 		using BufferType = SPtr<CoreVariantType<GpuBuffer, Core>>; | 
| 30 | 		using SamplerStateType = SPtr<CoreVariantType<SamplerState, Core>>; | 
| 31 | 		using GraphicsPipelineStateType = CoreVariantType<GraphicsPipelineState, Core>; | 
| 32 | 		using ComputePipelineStateType = CoreVariantType<ComputePipelineState, Core>; | 
| 33 |  | 
| 34 | 		/** Binding location for a single GPU param block buffer. */ | 
| 35 | 		struct BlockBinding | 
| 36 | 		{ | 
| 37 | 			UINT32 set; | 
| 38 | 			UINT32 slot; | 
| 39 | 		}; | 
| 40 |  | 
| 41 | 		/** All bindings for GPU param block buffers, for a single pass. */ | 
| 42 | 		struct PassBlockBindings | 
| 43 | 		{ | 
| 44 | 			BlockBinding bindings[GPT_COUNT]; | 
| 45 | 		}; | 
| 46 |  | 
| 47 | 		/** Information about a parameter block buffer. */ | 
| 48 | 		struct BlockInfo | 
| 49 | 		{ | 
| 50 | 			BlockInfo(const String& name, UINT32 set, UINT32 slot, const ParamBlockPtrType& buffer, bool shareable) | 
| 51 | 				: name(name), set(set), slot(slot), buffer(buffer), shareable(shareable), allowUpdate(true), isUsed(true) | 
| 52 | 				, passData(nullptr) | 
| 53 | 			{ } | 
| 54 |  | 
| 55 | 			String name; | 
| 56 | 			UINT32 set; | 
| 57 | 			UINT32 slot; | 
| 58 | 			ParamBlockPtrType buffer; | 
| 59 | 			bool shareable; | 
| 60 | 			bool allowUpdate; | 
| 61 | 			bool isUsed; | 
| 62 |  | 
| 63 | 			PassBlockBindings* passData; | 
| 64 | 		}; | 
| 65 |  | 
| 66 | 		/** Information about how a data parameter maps from a material parameter into a parameter block buffer. */ | 
| 67 | 		struct DataParamInfo | 
| 68 | 		{ | 
| 69 | 			UINT32 paramIdx; | 
| 70 | 			UINT32 blockIdx; | 
| 71 | 			UINT32 offset; | 
| 72 | 			UINT32 arrayStride; | 
| 73 | 		}; | 
| 74 |  | 
| 75 | 		/** Information about how an object parameter maps from a material parameter to a GPU stage slot. */ | 
| 76 | 		struct ObjectParamInfo | 
| 77 | 		{ | 
| 78 | 			UINT32 paramIdx; | 
| 79 | 			UINT32 slotIdx; | 
| 80 | 			UINT32 setIdx; | 
| 81 | 		}; | 
| 82 |  | 
| 83 | 		/** Information about all object parameters for a specific GPU programmable stage. */ | 
| 84 | 		struct StageParamInfo | 
| 85 | 		{ | 
| 86 | 			ObjectParamInfo* textures; | 
| 87 | 			UINT32 numTextures; | 
| 88 | 			ObjectParamInfo* loadStoreTextures; | 
| 89 | 			UINT32 numLoadStoreTextures; | 
| 90 | 			ObjectParamInfo* buffers; | 
| 91 | 			UINT32 numBuffers; | 
| 92 | 			ObjectParamInfo* samplerStates; | 
| 93 | 			UINT32 numSamplerStates; | 
| 94 | 		}; | 
| 95 |  | 
| 96 | 		/** Information about all object parameters for a specific pass. */ | 
| 97 | 		struct PassParamInfo | 
| 98 | 		{ | 
| 99 | 			StageParamInfo stages[GPT_COUNT]; | 
| 100 | 		}; | 
| 101 |  | 
| 102 | 	public: | 
| 103 | 		TGpuParamsSet() = default; | 
| 104 | 		TGpuParamsSet(const SPtr<TechniqueType>& technique, const ShaderType& shader, | 
| 105 | 			const SPtr<MaterialParamsType>& params); | 
| 106 | 		~TGpuParamsSet(); | 
| 107 |  | 
| 108 | 		/**  | 
| 109 | 		 * Returns a set of GPU parameters for the specified pass.  | 
| 110 | 		 * | 
| 111 | 		 * @param[in]	passIdx		Pass in which to look the GPU program for in. | 
| 112 | 		 * @return					GPU parameters object that can be used for setting parameters of all GPU programs  | 
| 113 | 		 *							in a pass. Returns null if pass doesn't exist. | 
| 114 | 		 */ | 
| 115 | 		SPtr<GpuParamsType> getGpuParams(UINT32 passIdx = 0); | 
| 116 |  | 
| 117 | 		/**  | 
| 118 | 		 * Searches for a parameter block buffer with the specified name, and returns an index you can use for accessing it. | 
| 119 | 		 * Returns -1 if buffer was not found. | 
| 120 | 		 */ | 
| 121 | 		UINT32 getParamBlockBufferIndex(const String& name) const; | 
| 122 |  | 
| 123 | 		/** | 
| 124 | 		 * Assign a parameter block buffer with the specified index to all the relevant child GpuParams. | 
| 125 | 		 * | 
| 126 | 		 * @param[in]	index			Index of the buffer, as retrieved from getParamBlockBufferIndex(). | 
| 127 | 		 * @param[in]	paramBlock		Parameter block to assign. | 
| 128 | 		 * @param[in]	ignoreInUpdate	If true the buffer will not be updated during the update() call. This is useful | 
| 129 | 		 *								if the caller wishes to manually update the buffer contents externally, to prevent | 
| 130 | 		 *								overwriting manually written data during update. | 
| 131 | 		 * | 
| 132 | 		 * @note	 | 
| 133 | 		 * Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or | 
| 134 | 		 * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters | 
| 135 | 		 * in the buffers need only be set once and then reused multiple times. | 
| 136 | 		 */ | 
| 137 | 		void setParamBlockBuffer(UINT32 index, const ParamBlockPtrType& paramBlock, bool ignoreInUpdate = false); | 
| 138 |  | 
| 139 | 		/** | 
| 140 | 		 * Assign a parameter block buffer with the specified name to all the relevant child GpuParams. | 
| 141 | 		 * | 
| 142 | 		 * @param[in]	name			Name of the buffer to set. | 
| 143 | 		 * @param[in]	paramBlock		Parameter block to assign. | 
| 144 | 		 * @param[in]	ignoreInUpdate	If true the buffer will not be updated during the update() call. This is useful | 
| 145 | 		 *								if the caller wishes to manually update the buffer contents externally, to prevent | 
| 146 | 		 *								overwriting manually written data during update. | 
| 147 | 		 * | 
| 148 | 		 * @note	 | 
| 149 | 		 * Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or | 
| 150 | 		 * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters | 
| 151 | 		 * in the buffers need only be set once and then reused multiple times. | 
| 152 | 		 */ | 
| 153 | 		void setParamBlockBuffer(const String& name, const ParamBlockPtrType& paramBlock, bool ignoreInUpdate = false); | 
| 154 |  | 
| 155 | 		/** Returns the number of passes the set contains the parameters for. */ | 
| 156 | 		UINT32 getNumPasses() const { return (UINT32)mPassParams.size(); } | 
| 157 |  | 
| 158 | 		/** | 
| 159 | 		 * Updates parameter data in this object from the provided material parameters object. | 
| 160 | 		 * | 
| 161 | 		 * @param[in]	params			Object containing the parameter data to update from. Layout of the object must match | 
| 162 | 		 *								the object used for creating this object (be created for the same shader). | 
| 163 | 		 * @param[in]	t				Time to evaluate animated parameters at (if any). | 
| 164 | 		 * @param[in]	updateAll		Normally the system will track dirty parameters since the last call to this method, | 
| 165 | 		 *								and only update the dirty ones. Set this to true if you want to force all parameters | 
| 166 | 		 *								to update, regardless of their dirty state. | 
| 167 | 		 */ | 
| 168 | 		void update(const SPtr<MaterialParamsType>& params, float t = 0.0f, bool updateAll = false); | 
| 169 |  | 
| 170 | 		static const UINT32 NUM_STAGES; | 
| 171 | 	private: | 
| 172 | 		template<bool Core2> friend class TMaterial; | 
| 173 |  | 
| 174 | 		Vector<SPtr<GpuParamsType>> mPassParams; | 
| 175 | 		Vector<BlockInfo> mBlocks; | 
| 176 | 		Vector<DataParamInfo> mDataParamInfos; | 
| 177 | 		PassParamInfo* mPassParamInfos; | 
| 178 |  | 
| 179 | 		UINT64 mParamVersion; | 
| 180 | 		UINT8* mData; | 
| 181 | 	}; | 
| 182 |  | 
| 183 | 	/** Sim thread version of TGpuParamsSet<Core>. */ | 
| 184 | 	class BS_CORE_EXPORT GpuParamsSet : public TGpuParamsSet<false> | 
| 185 | 	{ | 
| 186 | 	public: | 
| 187 | 		GpuParamsSet() = default; | 
| 188 | 		GpuParamsSet(const SPtr<Technique>& technique, const HShader& shader,  | 
| 189 | 			const SPtr<MaterialParams>& params) | 
| 190 | 			:TGpuParamsSet(technique, shader, params) | 
| 191 | 		{ } | 
| 192 | 	}; | 
| 193 |  | 
| 194 | 	namespace ct | 
| 195 | 	{ | 
| 196 | 	/** Core thread version of TGpuParamsSet<Core>. */ | 
| 197 | 	class BS_CORE_EXPORT GpuParamsSet : public TGpuParamsSet<true> | 
| 198 | 	{ | 
| 199 | 	public: | 
| 200 | 		GpuParamsSet() = default; | 
| 201 | 		GpuParamsSet(const SPtr<Technique>& technique, const SPtr<Shader>& shader, | 
| 202 | 			const SPtr<MaterialParams>& params) | 
| 203 | 			:TGpuParamsSet(technique, shader, params) | 
| 204 | 		{ } | 
| 205 | 	}; | 
| 206 | 	} | 
| 207 |  | 
| 208 | 	/** @} */ | 
| 209 | } |