BsMaterialParams.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsIReflectable.h"
  6. #include "BsStaticAlloc.h"
  7. #include "BsVector2.h"
  8. #include "BsVector3.h"
  9. #include "BsVector4.h"
  10. #include "BsVector2I.h"
  11. #include "BsVectorNI.h"
  12. #include "BsColor.h"
  13. #include "BsMatrix3.h"
  14. #include "BsMatrix4.h"
  15. #include "BsMatrixNxM.h"
  16. #include "BsGpuParams.h"
  17. namespace BansheeEngine
  18. {
  19. /** @cond INTERNAL */
  20. /** @addtogroup Material
  21. * @{
  22. */
  23. /**
  24. * Contains all parameter values set in a Material. This is similar to GpuParams which also stores parameter values,
  25. * however GpuParams are built for use on the GPU-side and don't store parameters that don't exist in a compiled GPU
  26. * program. This object on the other hand stores all parameters defined in a shader, regardless or not if they actually
  27. * exist in the GPU program. Additionally GpuParams are defined per-program (e.g. vertex, fragment) while this object
  28. * exists for the entire material.
  29. *
  30. * @note
  31. * This introduces redundancy as parameters stored by GpuParams and this object are duplicated. If this is an issue the
  32. * implementation can be modified to only store parameters not included in GpuParams.
  33. * @note
  34. * The reason why parameters in this class and GpuParams differ is most often compiler optimizations. If a compiler
  35. * optimizes out a variable in a GPU program we should still be able to store it, either for later when the variable
  36. * will be introduced, or for other techniques that might have that variable implemented.
  37. */
  38. class BS_CORE_EXPORT MaterialParams : public IReflectable
  39. {
  40. public:
  41. /** Type of material parameter. */
  42. enum class ParamType
  43. {
  44. Data, Texture, Sampler
  45. };
  46. /** Result codes for getParam method. */
  47. enum class GetParamResult
  48. {
  49. Success,
  50. NotFound,
  51. InvalidType,
  52. IndexOutOfBounds
  53. };
  54. /** Meta-data about a parameter. */
  55. struct ParamData
  56. {
  57. ParamType type;
  58. GpuParamDataType dataType;
  59. UINT32 index;
  60. UINT32 arraySize;
  61. };
  62. /** Raw data for a single structure parameter. */
  63. class BS_CORE_EXPORT StructParamData : public IReflectable
  64. {
  65. public:
  66. UINT8* data;
  67. UINT32 dataSize;
  68. friend class StructParamDataRTTI;
  69. static RTTITypeBase* getRTTIStatic();
  70. virtual RTTITypeBase* getRTTI() const override;
  71. };
  72. /** Data for a single texture parameter. */
  73. class BS_CORE_EXPORT TextureParamData : public IReflectable
  74. {
  75. public:
  76. HTexture value;
  77. bool isLoadStore;
  78. TextureSurface surface;
  79. friend class TextureParamDataRTTI;
  80. static RTTITypeBase* getRTTIStatic();
  81. virtual RTTITypeBase* getRTTI() const override;
  82. };
  83. /** Creates a new material params object and initializes enough room for parameters from the provided shader. */
  84. MaterialParams(const HShader& shader);
  85. ~MaterialParams();
  86. /**
  87. * Returns the value of a shader data parameter with the specified name at the specified array index. If the
  88. * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved.
  89. *
  90. * @param[in] name Name of the shader parameter.
  91. * @param[in] arrayIdx If the parameter is an array, index of the entry to access.
  92. * @param[out] output If successful, value of the parameter.
  93. *
  94. * @tparam T Native type of the parameter.
  95. */
  96. template <typename T>
  97. void getDataParam(const String& name, UINT32 arrayIdx, T& output) const
  98. {
  99. GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId;
  100. const ParamData* param = nullptr;
  101. auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, &param);
  102. if (result != GetParamResult::Success)
  103. return;
  104. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES[dataType];
  105. UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
  106. output = *(T*)(mDataParamsBuffer[param->index + arrayIdx * paramTypeSize]);
  107. memcpy(output, &mDataParamsBuffer[param->index + arrayIdx * paramTypeSize], sizeof(paramTypeSize));
  108. }
  109. /**
  110. * Sets the value of a shader data parameter with the specified name at the specified array index. If the
  111. * parameter name, index or type is not valid a warning will be logged and output value will not be set.
  112. *
  113. * @param[in] name Name of the shader parameter.
  114. * @param[in] arrayIdx If the parameter is an array, index of the entry to access.
  115. * @param[in] input New value of the parameter.
  116. *
  117. * @tparam T Native type of the parameter.
  118. */
  119. template <typename T>
  120. void setDataParam(const String& name, UINT32 arrayIdx, const T& input) const
  121. {
  122. GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId;
  123. const ParamData* param = nullptr;
  124. auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, &param);
  125. if (result != GetParamResult::Success)
  126. return;
  127. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES[dataType];
  128. UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
  129. memcpy(&mDataParamsBuffer[param->index + arrayIdx * paramTypeSize], input, sizeof(paramTypeSize));
  130. }
  131. /**
  132. * Returns the value of a shader structure parameter with the specified name at the specified array index. If the
  133. * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved.
  134. *
  135. * @param[in] name Name of the shader parameter.
  136. * @param[out] value Pre-allocated buffer of @p size bytes where the value will be retrieved.
  137. * @param[in] size Size of the buffer into which to write the value. Must match parameter struct's size.
  138. * @param[in] arrayIdx If the parameter is an array, index of the entry to access.
  139. */
  140. void getStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx) const;
  141. /**
  142. * Sets the value of a shader structure parameter with the specified name at the specified array index. If the
  143. * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved.
  144. *
  145. * @param[in] name Name of the shader parameter.
  146. * @param[in] value Buffer of @p size bytes containing the new value of the structure.
  147. * @param[in] size Size of the buffer from which to retrieve the value. Must match parameter struct's size.
  148. * @param[in] arrayIdx If the parameter is an array, index of the entry to access.
  149. */
  150. void setStructData(const String& name, const void* value, UINT32 size, UINT32 arrayIdx);
  151. /**
  152. * Returns the value of a shader texture parameter with the specified name. If the parameter name or type is not
  153. * valid a warning will be logged and output value will not be retrieved.
  154. *
  155. * @param[in] name Name of the shader parameter.
  156. * @param[out] value Output value of the parameter.
  157. */
  158. void getTexture(const String& name, HTexture& value) const;
  159. /**
  160. * Sets the value of a shader texture parameter with the specified name. If the parameter name or type is not
  161. * valid a warning will be logged and output value will not be set.
  162. *
  163. * @param[in] name Name of the shader parameter.
  164. * @param[in] value New value of the parameter.
  165. */
  166. void setTexture(const String& name, const HTexture& value);
  167. /**
  168. * Returns the value of a shader load/store texture parameter with the specified name. If the parameter name or
  169. * type is not valid a warning will be logged and output value will not be retrieved.
  170. *
  171. * @param[in] name Name of the shader parameter.
  172. * @param[out] value Output value of the parameter.
  173. * @param[out] surface Surface describing which part of the texture is being accessed.
  174. */
  175. void getLoadStoreTexture(const String& name, HTexture& value, TextureSurface& surface) const;
  176. /**
  177. * Sets the value of a shader load/store texture parameter with the specified name. If the parameter name or
  178. * type is not valid a warning will be logged and the value will not be set.
  179. *
  180. * @param[in] name Name of the shader parameter.
  181. * @param[in] value New value of the parameter.
  182. * @param[in] surface Surface describing which part of the texture is being accessed.
  183. */
  184. void setLoadStoreTexture(const String& name, const HTexture& value, const TextureSurface& surface);
  185. /**
  186. * Sets the value of a shader sampler state parameter with the specified name. If the parameter name or type is not
  187. * valid a warning will be logged and output value will not be set.
  188. *
  189. * @param[in] name Name of the shader parameter.
  190. * @param[out] value Output value of the parameter.
  191. */
  192. void getSamplerState(const String& name, SamplerStatePtr& value) const;
  193. /**
  194. * Sets the value of a shader sampler state parameter with the specified name. If the parameter name or type is not
  195. * valid a warning will be logged and output value will not be set.
  196. *
  197. * @param[in] name Name of the shader parameter.
  198. * @param[in] value New value of the parameter.
  199. */
  200. void setSamplerState(const String& name, const SamplerStatePtr& value);
  201. /**
  202. * Returns data about a parameter and reports an error if there is a type or size mismatch, or if the parameter
  203. * does exist.
  204. *
  205. * @param[in] name Name of the shader parameter.
  206. * @param[in] type Type of the parameter retrieve. Error will be logged if actual type of the parameter
  207. * doesn't match.
  208. * @param[in] dataType Only relevant if the parameter is a data type. Determines exact data type of the parameter
  209. * to retrieve.
  210. * @param[in] arrayIdx Array index of the entry to retrieve.
  211. * @param[out] output Object describing the parameter with an index to its data. If the parameter was not found
  212. * this value is undefined. This value will still be valid if parameter was found but
  213. * some other error was reported.
  214. *
  215. * @return Success or error state of the request.
  216. */
  217. GetParamResult getParamData(const String& name, ParamType type, GpuParamDataType dataType, UINT32 arrayIdx,
  218. const ParamData** output) const;
  219. /**
  220. * Logs an error that was reported by getParamData().
  221. *
  222. * @param[in] name Name of the shader parameter for which the error occurred.
  223. * @param[in] arrayIdx Array index for which the error occurred.
  224. */
  225. void reportGetParamError(GetParamResult errorCode, const String& name, UINT32 arrayIdx) const;
  226. /**
  227. * Equivalent to getStructData(const String&, UINT32, T&) except it uses the internal parameter index
  228. * directly, avoiding the name lookup. Caller must guarantee the index is valid.
  229. */
  230. template <typename T>
  231. void getDataParam(UINT32 index, UINT32 arrayIdx, T& output) const
  232. {
  233. GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId;
  234. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType];
  235. UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
  236. assert(sizeof(output) == paramTypeSize);
  237. memcpy(&output, &mDataParamsBuffer[index + arrayIdx * paramTypeSize], paramTypeSize);
  238. }
  239. /**
  240. * Equivalent to setDataParam(const String&, UINT32, T&) except it uses the internal parameter index
  241. * directly, avoiding the name lookup. Caller must guarantee the index is valid.
  242. */
  243. template <typename T>
  244. void setDataParam(UINT32 index, UINT32 arrayIdx, const T& input) const
  245. {
  246. GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId;
  247. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType];
  248. UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
  249. assert(sizeof(input) == paramTypeSize);
  250. memcpy(&mDataParamsBuffer[index + arrayIdx * paramTypeSize], &input, paramTypeSize);
  251. }
  252. /**
  253. * Equivalent to getStructData(const String&, UINT32, void*, UINT32) except it uses the internal parameter index
  254. * directly, avoiding the name lookup. Caller must guarantee the index is valid.
  255. */
  256. void getStructData(UINT32 index, void* value, UINT32 size) const;
  257. /**
  258. * Equivalent to setStructData(const String&, UINT32, void*, UINT32) except it uses the internal parameter index
  259. * directly, avoiding the name lookup. Caller must guarantee the index is valid.
  260. */
  261. void setStructData(UINT32 index, const void* value, UINT32 size);
  262. /**
  263. * Returns a size of a struct parameter in bytes, using the internal parameter index. Caller must guarantee the
  264. * index is valid.
  265. */
  266. UINT32 getStructSize(UINT32 index) const;
  267. /**
  268. * Equivalent to getTexture(const String&, HTexture&) except it uses the internal parameter index directly,
  269. * avoiding the name lookup. Caller must guarantee the index is valid.
  270. */
  271. void getTexture(UINT32 index, HTexture& value) const;
  272. /**
  273. * Equivalent to setTexture(const String&, HTexture&) except it uses the internal parameter index directly,
  274. * avoiding the name lookup. Caller must guarantee the index is valid.
  275. */
  276. void setTexture(UINT32 index, const HTexture& value);
  277. /**
  278. * Equivalent to getLoadStoreTexture(const String&, HTexture&, TextureSurface&) except it uses the internal
  279. * parameter index directly, avoiding the name lookup. Caller must guarantee the index is valid.
  280. */
  281. void getLoadStoreTexture(UINT32 index, HTexture& value, TextureSurface& surface) const;
  282. /**
  283. * Equivalent to setLoadStoreTexture(const String&, HTexture&, TextureSurface&) except it uses the internal
  284. * parameter index directly, avoiding the name lookup. Caller must guarantee the index is valid.
  285. */
  286. void setLoadStoreTexture(UINT32 index, const HTexture& value, const TextureSurface& surface);
  287. /**
  288. * Checks is a texture with the specified index a load/store texture or a normal one. Caller must guarantee the
  289. * index is valid.
  290. */
  291. bool getIsTextureLoadStore(UINT32 index) const;
  292. /**
  293. * Equivalent to getSamplerState(const String&, SamplerStatePtr&) except it uses the internal parameter index
  294. * directly, avoiding the name lookup. Caller must guarantee the index is valid.
  295. */
  296. void getSamplerState(UINT32 index, SamplerStatePtr& value) const;
  297. /**
  298. * Equivalent to setSamplerState(const String&, SamplerStatePtr&) except it uses the internal parameter index
  299. * directly, avoiding the name lookup. Caller must guarantee the index is valid.
  300. */
  301. void setSamplerState(UINT32 index, const SamplerStatePtr& value);
  302. /**
  303. * Returns the default texture (one assigned when no other is provided), if available for the specified index.
  304. * Index is the internal parameter index and the caller must guarantee the index is valid.
  305. */
  306. void getDefaultTexture(UINT32 index, HTexture& value) const;
  307. /**
  308. * Returns the default sampler state (one assigned when no other is provided), if available for the specified index.
  309. * Index is the internal parameter index and the caller must guarantee the index is valid.
  310. */
  311. void getDefaultSamplerState(UINT32 index, SamplerStatePtr& value) const;
  312. private:
  313. const static UINT32 STATIC_BUFFER_SIZE = 256;
  314. UnorderedMap<String, ParamData> mParams;
  315. UINT8* mDataParamsBuffer = nullptr;
  316. StructParamData* mStructParams = nullptr;
  317. TextureParamData* mTextureParams = nullptr;
  318. SamplerStatePtr* mSamplerStateParams = nullptr;
  319. HTexture* mDefaultTextureParams = nullptr;
  320. SamplerStatePtr* mDefaultSamplerStateParams = nullptr;
  321. UINT32 mDataSize = 0;
  322. UINT32 mNumStructParams = 0;
  323. UINT32 mNumTextureParams = 0;
  324. UINT32 mNumSamplerParams = 0;
  325. mutable StaticAlloc<STATIC_BUFFER_SIZE, STATIC_BUFFER_SIZE> mAlloc;
  326. /************************************************************************/
  327. /* RTTI */
  328. /************************************************************************/
  329. public:
  330. MaterialParams() { } // Only for serialization
  331. friend class MaterialParamsRTTI;
  332. static RTTITypeBase* getRTTIStatic();
  333. virtual RTTITypeBase* getRTTI() const override;
  334. };
  335. /** @cond SPECIALIZATIONS */
  336. BS_ALLOW_MEMCPY_SERIALIZATION(MaterialParams::ParamData);
  337. /** @endcond */
  338. /** @} */
  339. /** @endcond */
  340. }