BsMaterialParams.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsMaterialParams.h"
  4. #include "BsMaterialParamsRTTI.h"
  5. #include "BsShader.h"
  6. namespace BansheeEngine
  7. {
  8. MaterialParams::MaterialParams(const HShader& shader)
  9. {
  10. mDataSize = 0;
  11. auto& dataParams = shader->getDataParams();
  12. for (auto& param : dataParams)
  13. {
  14. UINT32 arraySize = param.second.arraySize > 1 ? param.second.arraySize : 1;
  15. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.second.type];
  16. UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
  17. mDataSize += arraySize * paramSize;
  18. }
  19. auto& textureParams = shader->getTextureParams();
  20. auto& bufferParams = shader->getBufferParams();
  21. auto& samplerParams = shader->getSamplerParams();
  22. mNumTextureParams = (UINT32)textureParams.size();
  23. mNumBufferParams = (UINT32)bufferParams.size();
  24. mNumSamplerParams = (UINT32)samplerParams.size();
  25. mDataParamsBuffer = mAlloc.alloc(mDataSize);
  26. memset(mDataParamsBuffer, 0, mDataSize);
  27. mStructParams = mAlloc.construct<StructParamData>(mNumStructParams);
  28. mTextureParams = mAlloc.construct<TextureParamData>(mNumTextureParams);
  29. mBufferParams = mAlloc.construct<SPtr<GpuBuffer>>(mNumBufferParams);
  30. mSamplerStateParams = mAlloc.construct<SPtr<SamplerState>>(mNumSamplerParams);
  31. mDefaultTextureParams = mAlloc.construct<HTexture>(mNumTextureParams);
  32. mDefaultSamplerStateParams = mAlloc.construct<SPtr<SamplerState>>(mNumSamplerParams);
  33. UINT32 dataBufferIdx = 0;
  34. UINT32 structIdx = 0;
  35. UINT32 textureIdx = 0;
  36. UINT32 bufferIdx = 0;
  37. UINT32 samplerIdx = 0;
  38. for (auto& entry : dataParams)
  39. {
  40. ParamData& dataParam = mParams[entry.first];
  41. UINT32 arraySize = entry.second.arraySize > 1 ? entry.second.arraySize : 1;
  42. dataParam.arraySize = arraySize;
  43. dataParam.type = ParamType::Data;
  44. dataParam.dataType = entry.second.type;
  45. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)dataParam.dataType];
  46. UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
  47. dataParam.index = dataBufferIdx;
  48. dataBufferIdx += arraySize * paramSize;
  49. if(entry.second.type == GPDT_STRUCT)
  50. {
  51. for (UINT32 i = 0; i < arraySize; i++)
  52. {
  53. StructParamData& param = mStructParams[structIdx];
  54. param.dataSize = entry.second.elementSize;
  55. param.data = mAlloc.alloc(param.dataSize);
  56. dataParam.index = structIdx;
  57. structIdx++;
  58. }
  59. }
  60. }
  61. for (auto& entry : textureParams)
  62. {
  63. ParamData& dataParam = mParams[entry.first];
  64. dataParam.arraySize = 1;
  65. dataParam.type = ParamType::Texture;
  66. dataParam.dataType = GPDT_UNKNOWN;
  67. dataParam.index = textureIdx;
  68. TextureParamData& param = mTextureParams[textureIdx];
  69. param.isLoadStore = false;
  70. if (entry.second.defaultValueIdx != (UINT32)-1)
  71. mDefaultTextureParams[textureIdx] = shader->getDefaultTexture(entry.second.defaultValueIdx);
  72. textureIdx++;
  73. }
  74. for (auto& entry : bufferParams)
  75. {
  76. ParamData& dataParam = mParams[entry.first];
  77. dataParam.arraySize = 1;
  78. dataParam.type = ParamType::Buffer;
  79. dataParam.dataType = GPDT_UNKNOWN;
  80. dataParam.index = bufferIdx;
  81. bufferIdx++;
  82. }
  83. for (auto& entry : samplerParams)
  84. {
  85. ParamData& dataParam = mParams[entry.first];
  86. dataParam.arraySize = 1;
  87. dataParam.type = ParamType::Sampler;
  88. dataParam.dataType = GPDT_UNKNOWN;
  89. dataParam.index = samplerIdx;
  90. if (entry.second.defaultValueIdx != (UINT32)-1)
  91. mDefaultSamplerStateParams[textureIdx] = shader->getDefaultSampler(entry.second.defaultValueIdx);
  92. samplerIdx++;
  93. }
  94. }
  95. MaterialParams::~MaterialParams()
  96. {
  97. if (mStructParams != nullptr)
  98. {
  99. for (UINT32 i = 0; mNumStructParams; i++)
  100. mAlloc.free(mStructParams[i].data);
  101. }
  102. mAlloc.free(mDataParamsBuffer);
  103. mAlloc.destruct(mStructParams, mNumStructParams);
  104. mAlloc.destruct(mTextureParams, mNumTextureParams);
  105. mAlloc.destruct(mBufferParams, mNumBufferParams);
  106. mAlloc.destruct(mSamplerStateParams, mNumSamplerParams);
  107. if(mDefaultTextureParams != nullptr)
  108. mAlloc.destruct(mDefaultTextureParams, mNumTextureParams);
  109. if (mDefaultSamplerStateParams != nullptr)
  110. mAlloc.destruct(mDefaultSamplerStateParams, mNumSamplerParams);
  111. mAlloc.clear();
  112. }
  113. void MaterialParams::getStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx) const
  114. {
  115. const ParamData* param = nullptr;
  116. GetParamResult result = getParamData(name, ParamType::Data, GPDT_STRUCT, arrayIdx, &param);
  117. if (result != GetParamResult::Success)
  118. {
  119. reportGetParamError(result, name, arrayIdx);
  120. return;
  121. }
  122. getStructData(param->index + arrayIdx, value, size);
  123. }
  124. void MaterialParams::setStructData(const String& name, const void* value, UINT32 size, UINT32 arrayIdx)
  125. {
  126. const ParamData* param = nullptr;
  127. GetParamResult result = getParamData(name, ParamType::Data, GPDT_STRUCT, arrayIdx, &param);
  128. if (result != GetParamResult::Success)
  129. {
  130. reportGetParamError(result, name, arrayIdx);
  131. return;
  132. }
  133. setStructData(param->index + arrayIdx, value, size);
  134. }
  135. void MaterialParams::getTexture(const String& name, HTexture& value) const
  136. {
  137. const ParamData* param = nullptr;
  138. GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
  139. if (result != GetParamResult::Success)
  140. {
  141. reportGetParamError(result, name, 0);
  142. return;
  143. }
  144. getTexture(param->index, value);
  145. }
  146. void MaterialParams::setTexture(const String& name, const HTexture& value)
  147. {
  148. const ParamData* param = nullptr;
  149. GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
  150. if (result != GetParamResult::Success)
  151. {
  152. reportGetParamError(result, name, 0);
  153. return;
  154. }
  155. setTexture(param->index, value);
  156. }
  157. void MaterialParams::getLoadStoreTexture(const String& name, HTexture& value, TextureSurface& surface) const
  158. {
  159. const ParamData* param = nullptr;
  160. GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
  161. if (result != GetParamResult::Success)
  162. {
  163. reportGetParamError(result, name, 0);
  164. return;
  165. }
  166. getLoadStoreTexture(param->index, value, surface);
  167. }
  168. void MaterialParams::setLoadStoreTexture(const String& name, const HTexture& value, const TextureSurface& surface)
  169. {
  170. const ParamData* param = nullptr;
  171. GetParamResult result = getParamData(name, ParamType::Texture, GPDT_UNKNOWN, 0, &param);
  172. if (result != GetParamResult::Success)
  173. {
  174. reportGetParamError(result, name, 0);
  175. return;
  176. }
  177. setLoadStoreTexture(param->index, value, surface);
  178. }
  179. void MaterialParams::getBuffer(const String& name, SPtr<GpuBuffer>& value) const
  180. {
  181. const ParamData* param = nullptr;
  182. GetParamResult result = getParamData(name, ParamType::Buffer, GPDT_UNKNOWN, 0, &param);
  183. if (result != GetParamResult::Success)
  184. {
  185. reportGetParamError(result, name, 0);
  186. return;
  187. }
  188. getBuffer(param->index, value);
  189. }
  190. void MaterialParams::setBuffer(const String& name, const SPtr<GpuBuffer>& value)
  191. {
  192. const ParamData* param = nullptr;
  193. GetParamResult result = getParamData(name, ParamType::Buffer, GPDT_UNKNOWN, 0, &param);
  194. if (result != GetParamResult::Success)
  195. {
  196. reportGetParamError(result, name, 0);
  197. return;
  198. }
  199. setBuffer(param->index, value);
  200. }
  201. void MaterialParams::getSamplerState(const String& name, SPtr<SamplerState>& value) const
  202. {
  203. const ParamData* param = nullptr;
  204. GetParamResult result = getParamData(name, ParamType::Sampler, GPDT_UNKNOWN, 0, &param);
  205. if (result != GetParamResult::Success)
  206. {
  207. reportGetParamError(result, name, 0);
  208. return;
  209. }
  210. getSamplerState(param->index, value);
  211. }
  212. void MaterialParams::setSamplerState(const String& name, const SPtr<SamplerState>& value)
  213. {
  214. const ParamData* param = nullptr;
  215. GetParamResult result = getParamData(name, ParamType::Sampler, GPDT_UNKNOWN, 0, &param);
  216. if(result != GetParamResult::Success)
  217. {
  218. reportGetParamError(result, name, 0);
  219. return;
  220. }
  221. setSamplerState(param->index, value);
  222. }
  223. MaterialParams::GetParamResult MaterialParams::getParamData(const String& name, ParamType type, GpuParamDataType dataType,
  224. UINT32 arrayIdx, const ParamData** output) const
  225. {
  226. auto iterFind = mParams.find(name);
  227. if (iterFind == mParams.end())
  228. return GetParamResult::NotFound;
  229. const ParamData& param = iterFind->second;
  230. *output = &param;
  231. if (param.type != type || (type == ParamType::Data && param.dataType != dataType))
  232. return GetParamResult::InvalidType;
  233. if (arrayIdx >= param.arraySize)
  234. return GetParamResult::IndexOutOfBounds;
  235. return GetParamResult::Success;
  236. }
  237. void MaterialParams::reportGetParamError(GetParamResult errorCode, const String& name, UINT32 arrayIdx) const
  238. {
  239. switch(errorCode)
  240. {
  241. case GetParamResult::NotFound:
  242. LOGWRN("Material doesn't have a parameter named " + name + ".");
  243. break;
  244. case GetParamResult::InvalidType:
  245. LOGWRN("Parameter \"" + name + "\" is not of the requested type.");
  246. break;
  247. case GetParamResult::IndexOutOfBounds:
  248. LOGWRN("Parameter \"" + name + "\" array index " + toString(arrayIdx) + " out of range.");
  249. break;
  250. default:
  251. break;
  252. }
  253. }
  254. void MaterialParams::getStructData(UINT32 index, void* value, UINT32 size) const
  255. {
  256. const StructParamData& structParam = mStructParams[index];
  257. if (structParam.dataSize != size)
  258. {
  259. LOGWRN("Size mismatch when writing to a struct. Provided size was " + toString(size) + " bytes but the "
  260. "struct size is" + toString(structParam.dataSize) + " bytes");
  261. return;
  262. }
  263. memcpy(value, structParam.data, structParam.dataSize);
  264. }
  265. void MaterialParams::setStructData(UINT32 index, const void* value, UINT32 size)
  266. {
  267. const StructParamData& structParam = mStructParams[index];
  268. if (structParam.dataSize != size)
  269. {
  270. LOGWRN("Size mismatch when writing to a struct. Provided size was " + toString(size) + " bytes but the "
  271. "struct size is" + toString(structParam.dataSize) + " bytes");
  272. return;
  273. }
  274. memcpy(structParam.data, value, structParam.dataSize);
  275. }
  276. UINT32 MaterialParams::getStructSize(UINT32 index) const
  277. {
  278. const StructParamData& structParam = mStructParams[index];
  279. return structParam.dataSize;
  280. }
  281. void MaterialParams::getTexture(UINT32 index, HTexture& value) const
  282. {
  283. TextureParamData& textureParam = mTextureParams[index];
  284. value = textureParam.value;
  285. }
  286. void MaterialParams::setTexture(UINT32 index, const HTexture& value)
  287. {
  288. TextureParamData& textureParam = mTextureParams[index];
  289. textureParam.value = value;
  290. textureParam.isLoadStore = false;
  291. }
  292. void MaterialParams::getBuffer(UINT32 index, SPtr<GpuBuffer>& value) const
  293. {
  294. value = mBufferParams[index];
  295. }
  296. void MaterialParams::setBuffer(UINT32 index, const SPtr<GpuBuffer>& value)
  297. {
  298. mBufferParams[index] = value;
  299. }
  300. void MaterialParams::getLoadStoreTexture(UINT32 index, HTexture& value, TextureSurface& surface) const
  301. {
  302. TextureParamData& textureParam = mTextureParams[index];
  303. value = textureParam.value;
  304. surface = textureParam.surface;
  305. }
  306. void MaterialParams::setLoadStoreTexture(UINT32 index, const HTexture& value, const TextureSurface& surface)
  307. {
  308. TextureParamData& textureParam = mTextureParams[index];
  309. textureParam.value = value;
  310. textureParam.isLoadStore = true;
  311. textureParam.surface = surface;
  312. }
  313. bool MaterialParams::getIsTextureLoadStore(UINT32 index) const
  314. {
  315. return mTextureParams[index].isLoadStore;
  316. }
  317. void MaterialParams::getSamplerState(UINT32 index, SPtr<SamplerState>& value) const
  318. {
  319. value = mSamplerStateParams[index];
  320. }
  321. void MaterialParams::setSamplerState(UINT32 index, const SPtr<SamplerState>& value)
  322. {
  323. mSamplerStateParams[index] = value;
  324. }
  325. void MaterialParams::getDefaultTexture(UINT32 index, HTexture& value) const
  326. {
  327. value = mDefaultTextureParams[index];
  328. }
  329. void MaterialParams::getDefaultSamplerState(UINT32 index, SPtr<SamplerState>& value) const
  330. {
  331. value = mDefaultSamplerStateParams[index];
  332. }
  333. RTTITypeBase* MaterialParams::TextureParamData::getRTTIStatic()
  334. {
  335. return TextureParamDataRTTI::instance();
  336. }
  337. RTTITypeBase* MaterialParams::TextureParamData::getRTTI() const
  338. {
  339. return getRTTIStatic();
  340. }
  341. RTTITypeBase* MaterialParams::StructParamData::getRTTIStatic()
  342. {
  343. return StructParamDataRTTI::instance();
  344. }
  345. RTTITypeBase* MaterialParams::StructParamData::getRTTI() const
  346. {
  347. return getRTTIStatic();
  348. }
  349. RTTITypeBase* MaterialParams::getRTTIStatic()
  350. {
  351. return MaterialParamsRTTI::instance();
  352. }
  353. RTTITypeBase* MaterialParams::getRTTI() const
  354. {
  355. return MaterialParams::getRTTIStatic();
  356. }
  357. }