BsShader.h 13 KB

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