BsShader.h 13 KB

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