BsShader.h 13 KB

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