BsMaterialParams.h 15 KB

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