BsShader.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsResource.h"
  4. #include "BsStringID.h"
  5. namespace BansheeEngine
  6. {
  7. /**
  8. * @brief Describes a single data (int, Vector2, etc.) shader parameter.
  9. *
  10. * @see Shader::addParameter.
  11. */
  12. struct SHADER_DATA_PARAM_DESC
  13. {
  14. String name;
  15. String gpuVariableName;
  16. GpuParamDataType type;
  17. StringID rendererSemantic;
  18. UINT32 arraySize;
  19. UINT32 elementSize;
  20. };
  21. /**
  22. * @brief Describes a single object (texture, sampler state, etc.) shader parameter.
  23. *
  24. * @see Shader::addParameter.
  25. */
  26. struct SHADER_OBJECT_PARAM_DESC
  27. {
  28. String name;
  29. Vector<String> gpuVariableNames;
  30. StringID rendererSemantic;
  31. GpuParamObjectType type;
  32. };
  33. /**
  34. * @brief Describes a shader parameter block.
  35. */
  36. struct SHADER_PARAM_BLOCK_DESC
  37. {
  38. String name;
  39. bool shared;
  40. StringID rendererSemantic;
  41. GpuParamBlockUsage usage;
  42. };
  43. /**
  44. * @brief Structure used for initializing a shader.
  45. */
  46. struct BS_CORE_EXPORT SHADER_DESC
  47. {
  48. SHADER_DESC();
  49. /**
  50. * @brief Registers a new data (int, Vector2, etc.) parameter you that you may then use
  51. * via Material by providing the parameter name. All parameters internally map to
  52. * variables defined in GPU programs.
  53. *
  54. * @param name The name of the parameter. Name must be unique between all data and object parameters.
  55. * @param gpuVariableName Name of the GPU variable in the GpuProgram that the parameter corresponds with.
  56. * @param type The type of the parameter, must be the same as the type in GpuProgram.
  57. * @param rendererSemantic (optional) Semantic that allows you to specify the use of this parameter in the renderer. The actual value of the semantic
  58. * depends on the current Renderer and its supported list of semantics. Elements with renderer semantics should not be updated
  59. * by the user, and will be updated by the renderer. These semantics will also be used to determine if a shader is compatible
  60. * with a specific renderer or not. Value of 0 signifies the parameter is not used by the renderer.
  61. * @param arraySize (optional) If the parameter is an array, the number of elements in the array. Size of 1 means its not an array.
  62. * @param elementSize (optional) Size of an individual element in the array, in bytes. You only need to set this if you are setting variable
  63. * length parameters, like structs.
  64. */
  65. void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, StringID rendererSemantic = StringID::NONE,
  66. UINT32 arraySize = 1, UINT32 elementSize = 0);
  67. /**
  68. * @brief Registers a new object (texture, sampler state, etc.) parameter you that you may then use
  69. * via Material by providing the parameter name. All parameters internally map to variables defined in GPU programs.
  70. * Multiple GPU variables may be mapped to a single parameter in which case the first variable actually found in the program
  71. * will be used while others will be ignored.
  72. *
  73. * @param name The name of the parameter. Name must be unique between all data and object parameters.
  74. * @param gpuVariableName Name of the GPU variable in the GpuProgram that the parameter corresponds with.
  75. * @param type The type of the parameter, must be the same as the type in GpuProgram.
  76. * @param rendererSemantic (optional) Semantic that allows you to specify the use of this parameter in the renderer. The actual value of the semantic
  77. * depends on the current Renderer and its supported list of semantics. Elements with renderer semantics should not be updated
  78. * by the user, and will be updated by the renderer. These semantics will also be used to determine if a shader is compatible
  79. * with a specific renderer or not. Value of 0 signifies the parameter is not used by the renderer.
  80. *
  81. * @note Mapping multiple GPU variables to a single parameter is useful when you are defining a shader that supports techniques across different render
  82. * systems where GPU variable names for the same parameters might differ.
  83. */
  84. void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic = StringID::NONE);
  85. /**
  86. * @brief Changes parameters of a parameter block with the specified name.
  87. *
  88. * @param name Name of the parameter block. This should correspond with the name specified in the GPU program code.
  89. * @param shared If parameter block is marked as shared it will not be automatically created by the Material. You will need
  90. * to create it elsewhere and then assign it manually.
  91. * @param usage Specified how often do we plan on modifying the buffer, which determines how is the buffer internally stored
  92. * for best performance.
  93. * @param rendererSemantic (optional) Semantic that allows you to specify the use of this parameter block in the renderer. The actual value of the
  94. * semantic depends on the current Renderer and its supported list of semantics. Elements with a renderer semantic
  95. * will not have their parameter block automatically created (similar to "shared" argument), but instead a Renderer will
  96. * create an assign it instead. Be aware that renderers have strict policies on what and how are parameters stored in the
  97. * buffer and you will need to respect them. If you don't respect them your shader will be deemed incompatible and won't be used.
  98. * Value of 0 signifies the parameter block is not used by the renderer.
  99. */
  100. void setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic = StringID::NONE);
  101. /**
  102. * @brief sorting type to use when performing sort in the render queue. Default value is sort front to back
  103. * which causes least overdraw and is preferable. Transparent objects need to be sorted back to front.
  104. * You may also specify no sorting and the elements will be rendered in the order they were added to the
  105. * render queue.
  106. */
  107. QueueSortType queueSortType;
  108. /**
  109. * @brief Priority that allows you to control in what order are your shaders rendered.
  110. * See "QueuePriority" for a list of initial values. Shaders with higher priority will be
  111. * rendered before shaders with lower priority, and additionally render queue will only sort
  112. * elements within the same priority group.
  113. *
  114. * @note This is useful when you want all your opaque objects to be rendered before you start
  115. * drawing your transparent ones. Or to render your overlays after everything else. Values
  116. * provided in "QueuePriority" are just for general guidance and feel free to increase them
  117. * or decrease them for finer tuning. (e.g. "QueuePriority::Opaque + 1").
  118. */
  119. INT32 queuePriority;
  120. /**
  121. * @brief Enables or disables separable passes. When separable passes are disabled
  122. * all shader passes will be executed in a sequence one after another. If it is disabled
  123. * the renderer is free to mix and match passes from different objects to achieve best
  124. * performance. (They will still be executed in sequence, but some other object may
  125. * be rendered in-between passes)
  126. *
  127. * @note Shaders with transparency generally can't be separable, while opaque can.
  128. */
  129. bool separablePasses;
  130. Map<String, SHADER_DATA_PARAM_DESC> dataParams;
  131. Map<String, SHADER_OBJECT_PARAM_DESC> objectParams;
  132. Map<String, SHADER_PARAM_BLOCK_DESC> paramBlocks;
  133. };
  134. /**
  135. * @brief Shader represents a collection of techniques. They are used in Materials,
  136. * which can be considered as instances of a Shader. Multiple materials
  137. * may share the same shader but provide different parameters to it.
  138. *
  139. * Shader will always choose the first supported technique based on the current render
  140. * system, render manager and other properties. So make sure to add most important techniques
  141. * first so you make sure they are used if they are supported.
  142. */
  143. class BS_CORE_EXPORT ShaderBase
  144. {
  145. public:
  146. virtual ~ShaderBase() { }
  147. /**
  148. * @brief Returns currently active queue sort type.
  149. *
  150. * @see SHADER_DESC::queueSortType
  151. */
  152. QueueSortType getQueueSortType() const { return mDesc.queueSortType; }
  153. /**
  154. * @brief Returns currently active queue priority.
  155. *
  156. * @see SHADER_DESC::queuePriority
  157. */
  158. INT32 getQueuePriority() const { return mDesc.queuePriority; }
  159. /**
  160. * @brief Returns if separable passes are allowed.
  161. *
  162. * @see SHADER_DESC::separablePasses
  163. */
  164. bool getAllowSeparablePasses() const { return mDesc.separablePasses; }
  165. /**
  166. * @brief Returns type of the parameter with the specified name. Throws exception if
  167. * the parameter doesn't exist.
  168. */
  169. GpuParamType getParamType(const String& name) const;
  170. /**
  171. * @brief Returns description for a data parameter with the specified name. Throws exception if
  172. * the parameter doesn't exist.
  173. */
  174. const SHADER_DATA_PARAM_DESC& getDataParamDesc(const String& name) const;
  175. /**
  176. * @brief Returns description for an object parameter with the specified name. Throws exception if
  177. * the parameter doesn't exist.
  178. */
  179. const SHADER_OBJECT_PARAM_DESC& getObjectParamDesc(const String& name) const;
  180. /**
  181. * @brief Checks if the parameter with the specified name exists, and is a data parameter.
  182. */
  183. bool hasDataParam(const String& name) const;
  184. /**
  185. * @brief Checks if the parameter with the specified name exists, and is an object parameter.
  186. */
  187. bool hasObjectParam(const String& name) const;
  188. /**
  189. * @brief Returns a map of all data parameters in the shader.
  190. */
  191. const Map<String, SHADER_DATA_PARAM_DESC>& getDataParams() const { return mDesc.dataParams; }
  192. /**
  193. * @brief Returns a map of all object parameters in the shader.
  194. */
  195. const Map<String, SHADER_OBJECT_PARAM_DESC>& getObjectParams() const { return mDesc.objectParams; }
  196. /**
  197. * @brief Returns a map of all parameter blocks.
  198. */
  199. const Map<String, SHADER_PARAM_BLOCK_DESC>& getParamBlocks() const { return mDesc.paramBlocks; }
  200. protected:
  201. ShaderBase() { }
  202. ShaderBase(const String& name, const SHADER_DESC& desc);
  203. String mName;
  204. SHADER_DESC mDesc;
  205. };
  206. /**
  207. * @copydoc ShaderBase
  208. *
  209. * @note Templated version of Shader used for implementing both
  210. * sim and core thread variants.
  211. */
  212. template<bool Core>
  213. class BS_CORE_EXPORT TShader : public ShaderBase
  214. {
  215. public:
  216. template<bool Core> struct TTechniqueType {};
  217. template<> struct TTechniqueType < false > { typedef Technique Type; };
  218. template<> struct TTechniqueType < true > { typedef TechniqueCore Type; };
  219. typedef typename TTechniqueType<Core>::Type TechniqueType;
  220. TShader() { }
  221. TShader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueType>>& techniques);
  222. virtual ~TShader();
  223. /**
  224. * @brief Returns the total number of techniques in this shader.
  225. */
  226. UINT32 getNumTechniques() const { return (UINT32)mTechniques.size(); }
  227. /**
  228. * @brief Gets the best supported technique based on current render and other systems.
  229. * Returns null if not a single technique is supported.
  230. */
  231. SPtr<TechniqueType> getBestTechnique() const;
  232. protected:
  233. Vector<SPtr<TechniqueType>> mTechniques;
  234. };
  235. /**
  236. * @copydoc ShaderBase
  237. */
  238. class BS_CORE_EXPORT ShaderCore : public CoreObjectCore, public TShader<true>
  239. {
  240. public:
  241. /**
  242. * @copydoc Shader::create
  243. */
  244. static SPtr<ShaderCore> create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueCore>>& techniques);
  245. protected:
  246. friend class Shader;
  247. ShaderCore(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueCore>>& techniques);
  248. };
  249. /**
  250. * @copydoc ShaderBase
  251. */
  252. class BS_CORE_EXPORT Shader : public Resource, public TShader<false>
  253. {
  254. public:
  255. /**
  256. * @brief Retrieves an implementation of a shader usable only from the
  257. * core thread.
  258. */
  259. SPtr<ShaderCore> getCore() const;
  260. static bool isSampler(GpuParamObjectType type);
  261. static bool isTexture(GpuParamObjectType type);
  262. static bool isBuffer(GpuParamObjectType type);
  263. /**
  264. * @brief Creates a new shader resource using the provided descriptor and techniques.
  265. */
  266. static HShader create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
  267. /**
  268. * @brief Creates a new shader object using the provided descriptor and techniques.
  269. *
  270. * @note Internal method.
  271. */
  272. static ShaderPtr _createPtr(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
  273. /**
  274. * @brief Returns a shader object but doesn't initialize it.
  275. */
  276. static ShaderPtr createEmpty();
  277. private:
  278. Shader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
  279. /**
  280. * @copydoc CoreObject::getCoreDependencies
  281. */
  282. void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
  283. /**
  284. * @copydoc CoreObject::createCore
  285. */
  286. SPtr<CoreObjectCore> createCore() const;
  287. private:
  288. /************************************************************************/
  289. /* RTTI */
  290. /************************************************************************/
  291. Shader() { }
  292. public:
  293. friend class ShaderRTTI;
  294. static RTTITypeBase* getRTTIStatic();
  295. virtual RTTITypeBase* getRTTI() const;
  296. };
  297. }