BsGpuParams.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsGpuParams.h"
  4. #include "BsGpuParamDesc.h"
  5. #include "BsGpuParamBlockBuffer.h"
  6. #include "BsVector2.h"
  7. #include "BsTexture.h"
  8. #include "BsGpuBuffer.h"
  9. #include "BsSamplerState.h"
  10. #include "BsFrameAlloc.h"
  11. #include "BsDebug.h"
  12. #include "BsException.h"
  13. #include "BsVectorNI.h"
  14. #include "BsMatrixNxM.h"
  15. #include "BsHardwareBufferManager.h"
  16. namespace BansheeEngine
  17. {
  18. GpuParamsBase::GpuParamsBase(const GPU_PARAMS_DESC& desc)
  19. {
  20. mParamDescs[GPT_FRAGMENT_PROGRAM] = desc.fragmentParams;
  21. mParamDescs[GPT_VERTEX_PROGRAM] = desc.vertexParams;
  22. mParamDescs[GPT_GEOMETRY_PROGRAM] = desc.geometryParams;
  23. mParamDescs[GPT_HULL_PROGRAM] = desc.hullParams;
  24. mParamDescs[GPT_DOMAIN_PROGRAM] = desc.domainParams;
  25. mParamDescs[GPT_COMPUTE_PROGRAM] = desc.computeParams;
  26. }
  27. GpuParamsBase::~GpuParamsBase()
  28. { }
  29. UINT32 GpuParamsBase::getDataParamSize(GpuProgramType type, const String& name) const
  30. {
  31. GpuParamDataDesc* desc = getParamDesc(type, name);
  32. if(desc != nullptr)
  33. return desc->elementSize * 4;
  34. return 0;
  35. }
  36. bool GpuParamsBase::hasParam(GpuProgramType type, const String& name) const
  37. {
  38. return getParamDesc(type, name) != nullptr;
  39. }
  40. bool GpuParamsBase::hasTexture(GpuProgramType type, const String& name) const
  41. {
  42. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  43. if (paramDesc == nullptr)
  44. return false;
  45. auto paramIter = paramDesc->textures.find(name);
  46. if(paramIter != paramDesc->textures.end())
  47. return true;
  48. return false;
  49. }
  50. bool GpuParamsBase::hasBuffer(GpuProgramType type, const String& name) const
  51. {
  52. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  53. if (paramDesc == nullptr)
  54. return false;
  55. auto paramIter = paramDesc->buffers.find(name);
  56. if (paramIter != paramDesc->buffers.end())
  57. return true;
  58. return false;
  59. }
  60. bool GpuParamsBase::hasLoadStoreTexture(GpuProgramType type, const String& name) const
  61. {
  62. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  63. if (paramDesc == nullptr)
  64. return false;
  65. auto paramIter = paramDesc->loadStoreTextures.find(name);
  66. if (paramIter != paramDesc->loadStoreTextures.end())
  67. return true;
  68. return false;
  69. }
  70. bool GpuParamsBase::hasSamplerState(GpuProgramType type, const String& name) const
  71. {
  72. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  73. if (paramDesc == nullptr)
  74. return false;
  75. auto paramIter = paramDesc->samplers.find(name);
  76. if(paramIter != paramDesc->samplers.end())
  77. return true;
  78. return false;
  79. }
  80. bool GpuParamsBase::hasParamBlock(GpuProgramType type, const String& name) const
  81. {
  82. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  83. if (paramDesc == nullptr)
  84. return false;
  85. auto paramBlockIter = paramDesc->paramBlocks.find(name);
  86. if(paramBlockIter != paramDesc->paramBlocks.end())
  87. return true;
  88. return false;
  89. }
  90. GpuParamDataDesc* GpuParamsBase::getParamDesc(GpuProgramType type, const String& name) const
  91. {
  92. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  93. if (paramDesc == nullptr)
  94. return nullptr;
  95. auto paramIter = paramDesc->params.find(name);
  96. if (paramIter != paramDesc->params.end())
  97. return &paramIter->second;
  98. return nullptr;
  99. }
  100. GpuParamBlockDesc* GpuParamsBase::getParamBlockDesc(GpuProgramType type, const String& name) const
  101. {
  102. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[(int)type];
  103. if (paramDesc == nullptr)
  104. return nullptr;
  105. auto paramBlockIter = paramDesc->paramBlocks.find(name);
  106. if (paramBlockIter != paramDesc->paramBlocks.end())
  107. return &paramBlockIter->second;
  108. return nullptr;
  109. }
  110. template<bool Core>
  111. TGpuParams<Core>::TGpuParams(const GPU_PARAMS_DESC& desc)
  112. : GpuParamsBase(desc)
  113. {
  114. for(UINT32 i = 0; i < (UINT32)ElementType::Count; i++)
  115. {
  116. mNumSets[i] = 0;
  117. mNumElements[i] = 0;
  118. mOffsets[i] = nullptr;
  119. }
  120. UINT32 numParamDescs = sizeof(mParamDescs) / sizeof(mParamDescs[0]);
  121. for (UINT32 i = 0; i < numParamDescs; i++)
  122. {
  123. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
  124. if (paramDesc == nullptr)
  125. continue;
  126. for (auto& paramBlock : paramDesc->paramBlocks)
  127. {
  128. if ((paramBlock.second.set + 1) > mNumSets[(int)ElementType::ParamBlock])
  129. mNumSets[(int)ElementType::ParamBlock] = paramBlock.second.set + 1;
  130. }
  131. for (auto& texture : paramDesc->textures)
  132. {
  133. if ((texture.second.set + 1) > mNumSets[(int)ElementType::Texture])
  134. mNumSets[(int)ElementType::Texture] = texture.second.set + 1;
  135. }
  136. for (auto& texture : paramDesc->loadStoreTextures)
  137. {
  138. if ((texture.second.set + 1) > mNumSets[(int)ElementType::LoadStoreTexture])
  139. mNumSets[(int)ElementType::LoadStoreTexture] = texture.second.set + 1;
  140. }
  141. for (auto& buffer : paramDesc->buffers)
  142. {
  143. if ((buffer.second.set + 1) > mNumSets[(int)ElementType::Buffer])
  144. mNumSets[(int)ElementType::Buffer] = buffer.second.set + 1;
  145. }
  146. for (auto& sampler : paramDesc->samplers)
  147. {
  148. if ((sampler.second.set + 1) > mNumSets[(int)ElementType::SamplerState])
  149. mNumSets[(int)ElementType::SamplerState] = sampler.second.set + 1;
  150. }
  151. }
  152. UINT32 totalNumSets = 0;
  153. for (UINT32 i = 0; i < (UINT32)ElementType::Count; i++)
  154. totalNumSets += mNumSets[i];
  155. UINT32* slotsPerSetData = bs_stack_alloc<UINT32>(totalNumSets);
  156. memset(slotsPerSetData, 0, sizeof(UINT32) * totalNumSets);
  157. UINT32* slotsPerSet[(UINT32)ElementType::Count];
  158. for (UINT32 i = 0; i < (UINT32)ElementType::Count; i++)
  159. {
  160. if (i == 0)
  161. slotsPerSet[i] = slotsPerSetData;
  162. else
  163. slotsPerSet[i] = slotsPerSet[i - 1] + mNumSets[i - 1];
  164. }
  165. for (UINT32 i = 0; i < numParamDescs; i++)
  166. {
  167. const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
  168. if (paramDesc == nullptr)
  169. continue;
  170. for (auto& paramBlock : paramDesc->paramBlocks)
  171. {
  172. UINT32* slots = slotsPerSet[(int)ElementType::ParamBlock];
  173. slots[paramBlock.second.set] = std::max(slots[paramBlock.second.set], paramBlock.second.slot + 1);
  174. }
  175. for (auto& texture : paramDesc->textures)
  176. {
  177. UINT32* slots = slotsPerSet[(int)ElementType::Texture];
  178. slots[texture.second.set] = std::max(slots[texture.second.set], texture.second.slot + 1);
  179. }
  180. for (auto& texture : paramDesc->loadStoreTextures)
  181. {
  182. UINT32* slots = slotsPerSet[(int)ElementType::LoadStoreTexture];
  183. slots[texture.second.set] = std::max(slots[texture.second.set], texture.second.slot + 1);
  184. }
  185. for (auto& buffer : paramDesc->buffers)
  186. {
  187. UINT32* slots = slotsPerSet[(int)ElementType::Buffer];
  188. slots[buffer.second.set] = std::max(slots[buffer.second.set], buffer.second.slot + 1);
  189. }
  190. for (auto& sampler : paramDesc->samplers)
  191. {
  192. UINT32* slots = slotsPerSet[(int)ElementType::SamplerState];
  193. slots[sampler.second.set] = std::max(slots[sampler.second.set], sampler.second.slot + 1);
  194. }
  195. }
  196. for (UINT32 i = 0; i < (UINT32)ElementType::Count; i++)
  197. {
  198. for (UINT32 j = 0; j < mNumSets[i]; j++)
  199. mNumElements[i] += slotsPerSet[i][j];
  200. }
  201. UINT32 paramBlocksSize = sizeof(ParamsBufferType) * mNumElements[(int)ElementType::ParamBlock];
  202. UINT32 texturesSize = sizeof(TextureType) * mNumElements[(int)ElementType::Texture];
  203. UINT32 loadStoreTexturesSize = sizeof(TextureType) * mNumElements[(int)ElementType::LoadStoreTexture];
  204. UINT32 loadStoreSurfacesSize = sizeof(TextureSurface) * mNumElements[(int)ElementType::LoadStoreTexture];
  205. UINT32 buffersSize = sizeof(BufferType) * mNumElements[(int)ElementType::Buffer];
  206. UINT32 samplerStatesSize = sizeof(SamplerType) * mNumElements[(int)ElementType::SamplerState];
  207. UINT32 setOffsetsSize = sizeof(UINT32) * totalNumSets;
  208. UINT32 totalSize = paramBlocksSize + texturesSize + loadStoreTexturesSize + loadStoreSurfacesSize +
  209. buffersSize + samplerStatesSize + setOffsetsSize;
  210. UINT8* data = (UINT8*)bs_alloc(totalSize);
  211. mParamBlockBuffers = (ParamsBufferType*)data;
  212. for (UINT32 i = 0; i < mNumElements[(int)ElementType::ParamBlock]; i++)
  213. new (&mParamBlockBuffers[i]) ParamsBufferType();
  214. data += sizeof(ParamsBufferType) * mNumElements[(int)ElementType::ParamBlock];
  215. mTextures = (TextureType*)data;
  216. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Texture]; i++)
  217. new (&mTextures[i]) TextureType();
  218. data += sizeof(TextureType) * mNumElements[(int)ElementType::Texture];
  219. mLoadStoreTextures = (TextureType*)data;
  220. for (UINT32 i = 0; i < mNumElements[(int)ElementType::LoadStoreTexture]; i++)
  221. new (&mLoadStoreTextures[i]) TextureType();
  222. data += sizeof(TextureType) * mNumElements[(int)ElementType::LoadStoreTexture];
  223. mLoadStoreSurfaces = (TextureSurface*)data;
  224. for (UINT32 i = 0; i < mNumElements[(int)ElementType::LoadStoreTexture]; i++)
  225. new (&mLoadStoreSurfaces[i]) TextureSurface();
  226. data += sizeof(TextureSurface) * mNumElements[(int)ElementType::LoadStoreTexture];
  227. mBuffers = (BufferType*)data;
  228. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Buffer]; i++)
  229. new (&mBuffers[i]) BufferType();
  230. data += sizeof(BufferType) * mNumElements[(int)ElementType::Buffer];
  231. mSamplerStates = (SamplerType*)data;
  232. for (UINT32 i = 0; i < mNumElements[(int)ElementType::SamplerState]; i++)
  233. new (&mSamplerStates[i]) SamplerType();
  234. data += sizeof(SamplerType) * mNumElements[(int)ElementType::SamplerState];
  235. for (UINT32 i = 0; i < (UINT32)ElementType::Count; i++)
  236. {
  237. mOffsets[i] = (UINT32*)data;
  238. data += sizeof(UINT32) * mNumSets[i];
  239. if (mNumSets[i] == 0)
  240. continue;
  241. mOffsets[i][0] = 0;
  242. for (UINT32 j = 0; j < mNumSets[i] - 1; j++)
  243. mOffsets[i][j + 1] = mOffsets[i][j] + slotsPerSet[i][j];
  244. }
  245. bs_stack_free(slotsPerSetData);
  246. }
  247. template<bool Core>
  248. TGpuParams<Core>::~TGpuParams()
  249. {
  250. for (UINT32 i = 0; i < mNumElements[(int)ElementType::ParamBlock]; i++)
  251. mParamBlockBuffers[i].~ParamsBufferType();
  252. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Texture]; i++)
  253. mTextures[i].~TextureType();
  254. for (UINT32 i = 0; i < mNumElements[(int)ElementType::LoadStoreTexture]; i++)
  255. {
  256. mLoadStoreTextures[i].~TextureType();
  257. mLoadStoreSurfaces[i].~TextureSurface();
  258. }
  259. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Buffer]; i++)
  260. mBuffers[i].~BufferType();
  261. for (UINT32 i = 0; i < mNumElements[(int)ElementType::SamplerState]; i++)
  262. mSamplerStates[i].~SamplerType();
  263. // Everything is allocated in a single block, so it's enough to free the first element
  264. bs_free(mParamBlockBuffers);
  265. }
  266. template<bool Core>
  267. UINT32 TGpuParams<Core>::getGlobalSlot(ElementType type, UINT32 set, UINT32 slot) const
  268. {
  269. #if BS_DEBUG_MODE
  270. if (set >= mNumSets[(int)type])
  271. {
  272. LOGERR("Set index out of range: Valid range: 0 .. " +
  273. toString(mNumSets[(int)type] - 1) + ". Requested: " + toString(set));
  274. return (UINT32)-1;
  275. }
  276. #endif
  277. UINT32 globalSlot = mOffsets[(int)type][set] + slot;
  278. #if BS_DEBUG_MODE
  279. if (globalSlot >= mNumElements[(int)type])
  280. {
  281. UINT32 maxSlot;
  282. if (set < (mNumSets[(int)type] - 1))
  283. maxSlot = mOffsets[(int)type][set + 1];
  284. else
  285. maxSlot = mNumElements[(int)type];
  286. maxSlot -= mOffsets[(int)type][set];
  287. LOGERR("Slot index out of range: Valid range: 0 .. " +
  288. toString(maxSlot - 1) + ". Requested: " + toString(slot));
  289. return (UINT32)-1;
  290. }
  291. #endif
  292. return globalSlot;
  293. }
  294. template<bool Core>
  295. void TGpuParams<Core>::setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer)
  296. {
  297. UINT32 globalSlot = getGlobalSlot(ElementType::ParamBlock, set, slot);
  298. if (globalSlot == (UINT32)-1)
  299. return;
  300. mParamBlockBuffers[globalSlot] = paramBlockBuffer;
  301. _markCoreDirty();
  302. }
  303. template<bool Core>
  304. void TGpuParams<Core>::setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer)
  305. {
  306. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  307. if(paramDescs == nullptr)
  308. {
  309. LOGWRN("Cannot find parameter block with the name: '" + name + "'");
  310. return;
  311. }
  312. auto iterFind = paramDescs->paramBlocks.find(name);
  313. if (iterFind == paramDescs->paramBlocks.end())
  314. {
  315. LOGWRN("Cannot find parameter block with the name: '" + name + "'");
  316. return;
  317. }
  318. setParamBlockBuffer(iterFind->second.set, iterFind->second.slot, paramBlockBuffer);
  319. }
  320. template<bool Core>
  321. template<class T>
  322. void TGpuParams<Core>::getParam(GpuProgramType type, const String& name, TGpuDataParam<T, Core>& output) const
  323. {
  324. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  325. if (paramDescs == nullptr)
  326. {
  327. output = TGpuDataParam<T, Core>(nullptr, nullptr);
  328. LOGWRN("Cannot find parameter block with the name: '" + name + "'");
  329. return;
  330. }
  331. auto iterFind = paramDescs->params.find(name);
  332. if (iterFind == paramDescs->params.end())
  333. {
  334. output = TGpuDataParam<T, Core>(nullptr, nullptr);
  335. LOGWRN("Cannot find parameter with the name '" + name + "'");
  336. }
  337. else
  338. output = TGpuDataParam<T, Core>(&iterFind->second, _getThisPtr());
  339. }
  340. template<bool Core>
  341. void TGpuParams<Core>::getStructParam(GpuProgramType type, const String& name, TGpuParamStruct<Core>& output) const
  342. {
  343. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  344. if (paramDescs == nullptr)
  345. {
  346. output = TGpuParamStruct<Core>(nullptr, nullptr);
  347. LOGWRN("Cannot find struct parameter with the name: '" + name + "'");
  348. return;
  349. }
  350. auto iterFind = paramDescs->params.find(name);
  351. if (iterFind == paramDescs->params.end() || iterFind->second.type != GPDT_STRUCT)
  352. {
  353. output = TGpuParamStruct<Core>(nullptr, nullptr);
  354. LOGWRN("Cannot find struct parameter with the name '" + name + "'");
  355. }
  356. else
  357. output = TGpuParamStruct<Core>(&iterFind->second, _getThisPtr());
  358. }
  359. template<bool Core>
  360. void TGpuParams<Core>::getTextureParam(GpuProgramType type, const String& name, TGpuParamTexture<Core>& output) const
  361. {
  362. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  363. if (paramDescs == nullptr)
  364. {
  365. output = TGpuParamTexture<Core>(nullptr, nullptr);
  366. LOGWRN("Cannot find texture parameter with the name: '" + name + "'");
  367. return;
  368. }
  369. auto iterFind = paramDescs->textures.find(name);
  370. if (iterFind == paramDescs->textures.end())
  371. {
  372. output = TGpuParamTexture<Core>(nullptr, nullptr);
  373. LOGWRN("Cannot find texture parameter with the name '" + name + "'");
  374. }
  375. else
  376. output = TGpuParamTexture<Core>(&iterFind->second, _getThisPtr());
  377. }
  378. template<bool Core>
  379. void TGpuParams<Core>::getLoadStoreTextureParam(GpuProgramType type, const String& name, TGpuParamLoadStoreTexture<Core>& output) const
  380. {
  381. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  382. if (paramDescs == nullptr)
  383. {
  384. output = TGpuParamLoadStoreTexture<Core>(nullptr, nullptr);
  385. LOGWRN("Cannot find texture parameter with the name: '" + name + "'");
  386. return;
  387. }
  388. auto iterFind = paramDescs->loadStoreTextures.find(name);
  389. if (iterFind == paramDescs->loadStoreTextures.end())
  390. {
  391. output = TGpuParamLoadStoreTexture<Core>(nullptr, nullptr);
  392. LOGWRN("Cannot find texture parameter with the name '" + name + "'");
  393. }
  394. else
  395. output = TGpuParamLoadStoreTexture<Core>(&iterFind->second, _getThisPtr());
  396. }
  397. template<bool Core>
  398. void TGpuParams<Core>::getBufferParam(GpuProgramType type, const String& name, TGpuParamBuffer<Core>& output) const
  399. {
  400. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  401. if (paramDescs == nullptr)
  402. {
  403. output = TGpuParamBuffer<Core>(nullptr, nullptr);
  404. LOGWRN("Cannot find buffer parameter with the name: '" + name + "'");
  405. return;
  406. }
  407. auto iterFind = paramDescs->buffers.find(name);
  408. if (iterFind == paramDescs->buffers.end())
  409. {
  410. output = TGpuParamBuffer<Core>(nullptr, nullptr);
  411. LOGWRN("Cannot find buffer parameter with the name '" + name + "'");
  412. }
  413. else
  414. output = TGpuParamBuffer<Core>(&iterFind->second, _getThisPtr());
  415. }
  416. template<bool Core>
  417. void TGpuParams<Core>::getSamplerStateParam(GpuProgramType type, const String& name, TGpuParamSampState<Core>& output) const
  418. {
  419. const SPtr<GpuParamDesc>& paramDescs = mParamDescs[(int)type];
  420. if (paramDescs == nullptr)
  421. {
  422. output = TGpuParamSampState<Core>(nullptr, nullptr);
  423. LOGWRN("Cannot find sampler state parameter with the name: '" + name + "'");
  424. return;
  425. }
  426. auto iterFind = paramDescs->samplers.find(name);
  427. if (iterFind == paramDescs->samplers.end())
  428. {
  429. output = TGpuParamSampState<Core>(nullptr, nullptr);
  430. LOGWRN("Cannot find sampler state parameter with the name '" + name + "'");
  431. }
  432. else
  433. output = TGpuParamSampState<Core>(&iterFind->second, _getThisPtr());
  434. }
  435. template<bool Core>
  436. typename TGpuParams<Core>::ParamsBufferType TGpuParams<Core>::getParamBlockBuffer(UINT32 set, UINT32 slot) const
  437. {
  438. UINT32 globalSlot = getGlobalSlot(ElementType::ParamBlock, set, slot);
  439. if (globalSlot == (UINT32)-1)
  440. return nullptr;
  441. return mParamBlockBuffers[globalSlot];
  442. }
  443. template<bool Core>
  444. typename TGpuParams<Core>::TextureType TGpuParams<Core>::getTexture(UINT32 set, UINT32 slot) const
  445. {
  446. UINT32 globalSlot = getGlobalSlot(ElementType::Texture, set, slot);
  447. if (globalSlot == (UINT32)-1)
  448. return TGpuParams<Core>::TextureType();
  449. return mTextures[globalSlot];
  450. }
  451. template<bool Core>
  452. typename TGpuParams<Core>::TextureType TGpuParams<Core>::getLoadStoreTexture(UINT32 set, UINT32 slot) const
  453. {
  454. UINT32 globalSlot = getGlobalSlot(ElementType::LoadStoreTexture, set, slot);
  455. if (globalSlot == (UINT32)-1)
  456. return TGpuParams<Core>::TextureType();
  457. return mLoadStoreTextures[globalSlot];
  458. }
  459. template<bool Core>
  460. typename TGpuParams<Core>::BufferType TGpuParams<Core>::getBuffer(UINT32 set, UINT32 slot) const
  461. {
  462. UINT32 globalSlot = getGlobalSlot(ElementType::Buffer, set, slot);
  463. if (globalSlot == (UINT32)-1)
  464. return nullptr;
  465. return mBuffers[globalSlot];
  466. }
  467. template<bool Core>
  468. typename TGpuParams<Core>::SamplerType TGpuParams<Core>::getSamplerState(UINT32 set, UINT32 slot) const
  469. {
  470. UINT32 globalSlot = getGlobalSlot(ElementType::SamplerState, set, slot);
  471. if (globalSlot == (UINT32)-1)
  472. return nullptr;
  473. return mSamplerStates[globalSlot];
  474. }
  475. template<bool Core>
  476. const TextureSurface& TGpuParams<Core>::getLoadStoreSurface(UINT32 set, UINT32 slot) const
  477. {
  478. static TextureSurface emptySurface;
  479. UINT32 globalSlot = getGlobalSlot(ElementType::LoadStoreTexture, set, slot);
  480. if (globalSlot == (UINT32)-1)
  481. return emptySurface;
  482. return mLoadStoreSurfaces[globalSlot];
  483. }
  484. template<bool Core>
  485. void TGpuParams<Core>::setTexture(UINT32 set, UINT32 slot, const TextureType& texture)
  486. {
  487. UINT32 globalSlot = getGlobalSlot(ElementType::Texture, set, slot);
  488. if (globalSlot == (UINT32)-1)
  489. return;
  490. mTextures[globalSlot] = texture;
  491. _markResourcesDirty();
  492. _markCoreDirty();
  493. }
  494. template<bool Core>
  495. void TGpuParams<Core>::setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface)
  496. {
  497. UINT32 globalSlot = getGlobalSlot(ElementType::LoadStoreTexture, set, slot);
  498. if (globalSlot == (UINT32)-1)
  499. return;
  500. mLoadStoreTextures[globalSlot] = texture;
  501. _markResourcesDirty();
  502. _markCoreDirty();
  503. }
  504. template<bool Core>
  505. void TGpuParams<Core>::setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer)
  506. {
  507. UINT32 globalSlot = getGlobalSlot(ElementType::Buffer, set, slot);
  508. if (globalSlot == (UINT32)-1)
  509. return;
  510. mBuffers[globalSlot] = buffer;
  511. _markResourcesDirty();
  512. _markCoreDirty();
  513. }
  514. template<bool Core>
  515. void TGpuParams<Core>::setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler)
  516. {
  517. UINT32 globalSlot = getGlobalSlot(ElementType::SamplerState, set, slot);
  518. if (globalSlot == (UINT32)-1)
  519. return;
  520. mSamplerStates[globalSlot] = sampler;
  521. _markResourcesDirty();
  522. _markCoreDirty();
  523. }
  524. template<bool Core>
  525. void TGpuParams<Core>::setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface)
  526. {
  527. UINT32 globalSlot = getGlobalSlot(ElementType::LoadStoreTexture, set, slot);
  528. if (globalSlot == (UINT32)-1)
  529. return;
  530. mLoadStoreSurfaces[globalSlot] = surface;
  531. }
  532. template class TGpuParams < false > ;
  533. template class TGpuParams < true > ;
  534. template BS_CORE_EXPORT void TGpuParams<false>::getParam<float>(GpuProgramType type, const String&, TGpuDataParam<float, false>&) const;
  535. template BS_CORE_EXPORT void TGpuParams<false>::getParam<int>(GpuProgramType type, const String&, TGpuDataParam<int, false>&) const;
  536. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Color>(GpuProgramType type, const String&, TGpuDataParam<Color, false>&) const;
  537. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2>(GpuProgramType type, const String&, TGpuDataParam<Vector2, false>&) const;
  538. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3>(GpuProgramType type, const String&, TGpuDataParam<Vector3, false>&) const;
  539. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4>(GpuProgramType type, const String&, TGpuDataParam<Vector4, false>&) const;
  540. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2I>(GpuProgramType type, const String&, TGpuDataParam<Vector2I, false>&) const;
  541. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3I>(GpuProgramType type, const String&, TGpuDataParam<Vector3I, false>&) const;
  542. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4I>(GpuProgramType type, const String&, TGpuDataParam<Vector4I, false>&) const;
  543. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2>(GpuProgramType type, const String&, TGpuDataParam<Matrix2, false>&) const;
  544. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x3, false>&) const;
  545. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x4, false>&) const;
  546. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3>(GpuProgramType type, const String&, TGpuDataParam<Matrix3, false>&) const;
  547. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x2, false>&) const;
  548. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x4, false>&) const;
  549. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4>(GpuProgramType type, const String&, TGpuDataParam<Matrix4, false>&) const;
  550. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x2, false>&) const;
  551. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x3, false>&) const;
  552. template BS_CORE_EXPORT void TGpuParams<true>::getParam<float>(GpuProgramType type, const String&, TGpuDataParam<float, true>&) const;
  553. template BS_CORE_EXPORT void TGpuParams<true>::getParam<int>(GpuProgramType type, const String&, TGpuDataParam<int, true>&) const;
  554. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Color>(GpuProgramType type, const String&, TGpuDataParam<Color, true>&) const;
  555. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2>(GpuProgramType type, const String&, TGpuDataParam<Vector2, true>&) const;
  556. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3>(GpuProgramType type, const String&, TGpuDataParam<Vector3, true>&) const;
  557. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4>(GpuProgramType type, const String&, TGpuDataParam<Vector4, true>&) const;
  558. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2I>(GpuProgramType type, const String&, TGpuDataParam<Vector2I, true>&) const;
  559. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3I>(GpuProgramType type, const String&, TGpuDataParam<Vector3I, true>&) const;
  560. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4I>(GpuProgramType type, const String&, TGpuDataParam<Vector4I, true>&) const;
  561. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2>(GpuProgramType type, const String&, TGpuDataParam<Matrix2, true>&) const;
  562. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x3, true>&) const;
  563. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix2x4, true>&) const;
  564. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3>(GpuProgramType type, const String&, TGpuDataParam<Matrix3, true>&) const;
  565. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x2, true>&) const;
  566. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3x4>(GpuProgramType type, const String&, TGpuDataParam<Matrix3x4, true>&) const;
  567. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4>(GpuProgramType type, const String&, TGpuDataParam<Matrix4, true>&) const;
  568. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x2>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x2, true>&) const;
  569. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x3>(GpuProgramType type, const String&, TGpuDataParam<Matrix4x3, true>&) const;
  570. GpuParamsCore::GpuParamsCore(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask)
  571. : TGpuParams(desc)
  572. {
  573. }
  574. SPtr<GpuParamsCore> GpuParamsCore::_getThisPtr() const
  575. {
  576. return std::static_pointer_cast<GpuParamsCore>(getThisPtr());
  577. }
  578. void GpuParamsCore::syncToCore(const CoreSyncData& data)
  579. {
  580. UINT32 loadStoreSurfacesSize = mNumElements[(int)ElementType::LoadStoreTexture] * sizeof(TextureSurface);
  581. UINT32 paramBufferSize = mNumElements[(int)ElementType::ParamBlock] * sizeof(SPtr<GpuParamBlockBufferCore>);
  582. UINT32 textureArraySize = mNumElements[(int)ElementType::Texture] * sizeof(SPtr<TextureCore>);
  583. UINT32 loadStoreTextureArraySize = mNumElements[(int)ElementType::LoadStoreTexture] * sizeof(SPtr<TextureCore>);
  584. UINT32 bufferArraySize = mNumElements[(int)ElementType::Buffer] * sizeof(SPtr<GpuBufferCore>);
  585. UINT32 samplerArraySize = mNumElements[(int)ElementType::SamplerState] * sizeof(SPtr<SamplerStateCore>);
  586. UINT32 totalSize = loadStoreSurfacesSize + paramBufferSize + textureArraySize + loadStoreTextureArraySize
  587. + bufferArraySize + samplerArraySize;
  588. UINT32 textureInfoOffset = 0;
  589. UINT32 paramBufferOffset = textureInfoOffset + loadStoreSurfacesSize;
  590. UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
  591. UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
  592. UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
  593. UINT32 samplerArrayOffset = bufferArrayOffset + bufferArraySize;
  594. assert(data.getBufferSize() == totalSize);
  595. UINT8* dataPtr = data.getBuffer();
  596. TextureSurface* loadStoreSurfaces = (TextureSurface*)(dataPtr + textureInfoOffset);
  597. SPtr<GpuParamBlockBufferCore>* paramBuffers = (SPtr<GpuParamBlockBufferCore>*)(dataPtr + paramBufferOffset);
  598. SPtr<TextureCore>* textures = (SPtr<TextureCore>*)(dataPtr + textureArrayOffset);
  599. SPtr<TextureCore>* loadStoreTextures = (SPtr<TextureCore>*)(dataPtr + loadStoreTextureArrayOffset);
  600. SPtr<GpuBufferCore>* buffers = (SPtr<GpuBufferCore>*)(dataPtr + bufferArrayOffset);
  601. SPtr<SamplerStateCore>* samplers = (SPtr<SamplerStateCore>*)(dataPtr + samplerArrayOffset);
  602. // Copy & destruct
  603. for (UINT32 i = 0; i < mNumElements[(int)ElementType::ParamBlock]; i++)
  604. {
  605. mParamBlockBuffers[i] = paramBuffers[i];
  606. paramBuffers[i].~SPtr<GpuParamBlockBufferCore>();
  607. }
  608. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Texture]; i++)
  609. {
  610. mTextures[i] = textures[i];
  611. textures[i].~SPtr<TextureCore>();
  612. }
  613. for (UINT32 i = 0; i < mNumElements[(int)ElementType::LoadStoreTexture]; i++)
  614. {
  615. mLoadStoreSurfaces[i] = loadStoreSurfaces[i];
  616. loadStoreSurfaces[i].~TextureSurface();
  617. mLoadStoreTextures[i] = loadStoreTextures[i];
  618. loadStoreTextures[i].~SPtr<TextureCore>();
  619. }
  620. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Buffer]; i++)
  621. {
  622. mBuffers[i] = buffers[i];
  623. buffers[i].~SPtr<GpuBufferCore>();
  624. }
  625. for (UINT32 i = 0; i < mNumElements[(int)ElementType::SamplerState]; i++)
  626. {
  627. mSamplerStates[i] = samplers[i];
  628. samplers[i].~SPtr<SamplerStateCore>();
  629. }
  630. }
  631. SPtr<GpuParamsCore> GpuParamsCore::create(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask)
  632. {
  633. return HardwareBufferCoreManager::instance().createGpuParams(desc, deviceMask);
  634. }
  635. const GpuDataParamInfos GpuParams::PARAM_SIZES;
  636. GpuParams::GpuParams(const GPU_PARAMS_DESC& desc)
  637. : TGpuParams(desc)
  638. {
  639. }
  640. SPtr<GpuParams> GpuParams::_getThisPtr() const
  641. {
  642. return std::static_pointer_cast<GpuParams>(getThisPtr());
  643. }
  644. SPtr<GpuParamsCore> GpuParams::getCore() const
  645. {
  646. return std::static_pointer_cast<GpuParamsCore>(mCoreSpecific);
  647. }
  648. SPtr<CoreObjectCore> GpuParams::createCore() const
  649. {
  650. GPU_PARAMS_DESC desc;
  651. desc.vertexParams = mParamDescs[GPT_VERTEX_PROGRAM];
  652. desc.fragmentParams = mParamDescs[GPT_FRAGMENT_PROGRAM];
  653. desc.geometryParams = mParamDescs[GPT_GEOMETRY_PROGRAM];
  654. desc.hullParams = mParamDescs[GPT_HULL_PROGRAM];
  655. desc.domainParams = mParamDescs[GPT_DOMAIN_PROGRAM];
  656. desc.computeParams = mParamDescs[GPT_COMPUTE_PROGRAM];
  657. return HardwareBufferCoreManager::instance().createGpuParams(desc);
  658. }
  659. void GpuParams::_markCoreDirty()
  660. {
  661. markCoreDirty();
  662. }
  663. void GpuParams::_markResourcesDirty()
  664. {
  665. markListenerResourcesDirty();
  666. }
  667. SPtr<GpuParams> GpuParams::create(const GPU_PARAMS_DESC& desc)
  668. {
  669. return HardwareBufferManager::instance().createGpuParams(desc);
  670. }
  671. CoreSyncData GpuParams::syncToCore(FrameAlloc* allocator)
  672. {
  673. UINT32 loadStoreSurfacesSize = mNumElements[(int)ElementType::LoadStoreTexture] * sizeof(TextureSurface);
  674. UINT32 paramBufferSize = mNumElements[(int)ElementType::ParamBlock] * sizeof(SPtr<GpuParamBlockBufferCore>);
  675. UINT32 textureArraySize = mNumElements[(int)ElementType::Texture] * sizeof(SPtr<TextureCore>);
  676. UINT32 loadStoreTextureArraySize = mNumElements[(int)ElementType::LoadStoreTexture] * sizeof(SPtr<TextureCore>);
  677. UINT32 bufferArraySize = mNumElements[(int)ElementType::Buffer] * sizeof(SPtr<GpuBufferCore>);
  678. UINT32 samplerArraySize = mNumElements[(int)ElementType::SamplerState] * sizeof(SPtr<SamplerStateCore>);
  679. UINT32 totalSize = loadStoreSurfacesSize + paramBufferSize + textureArraySize + loadStoreTextureArraySize
  680. + bufferArraySize + samplerArraySize;
  681. UINT32 textureInfoOffset = 0;
  682. UINT32 paramBufferOffset = textureInfoOffset + loadStoreSurfacesSize;
  683. UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
  684. UINT32 loadStoreTextureArrayOffset = textureArrayOffset + textureArraySize;
  685. UINT32 bufferArrayOffset = loadStoreTextureArrayOffset + loadStoreTextureArraySize;
  686. UINT32 samplerArrayOffset = bufferArrayOffset + bufferArraySize;
  687. UINT8* data = allocator->alloc(totalSize);
  688. TextureSurface* loadStoreSurfaces = (TextureSurface*)(data + textureInfoOffset);
  689. SPtr<GpuParamBlockBufferCore>* paramBuffers = (SPtr<GpuParamBlockBufferCore>*)(data + paramBufferOffset);
  690. SPtr<TextureCore>* textures = (SPtr<TextureCore>*)(data + textureArrayOffset);
  691. SPtr<TextureCore>* loadStoreTextures = (SPtr<TextureCore>*)(data + loadStoreTextureArrayOffset);
  692. SPtr<GpuBufferCore>* buffers = (SPtr<GpuBufferCore>*)(data + bufferArrayOffset);
  693. SPtr<SamplerStateCore>* samplers = (SPtr<SamplerStateCore>*)(data + samplerArrayOffset);
  694. // Construct & copy
  695. for (UINT32 i = 0; i < mNumElements[(int)ElementType::ParamBlock]; i++)
  696. {
  697. new (&paramBuffers[i]) SPtr<GpuParamBlockBufferCore>();
  698. if (mParamBlockBuffers[i] != nullptr)
  699. paramBuffers[i] = mParamBlockBuffers[i]->getCore();
  700. }
  701. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Texture]; i++)
  702. {
  703. new (&textures[i]) SPtr<TextureCore>();
  704. if (mTextures[i].isLoaded())
  705. textures[i] = mTextures[i]->getCore();
  706. else
  707. textures[i] = nullptr;
  708. }
  709. for (UINT32 i = 0; i < mNumElements[(int)ElementType::LoadStoreTexture]; i++)
  710. {
  711. new (&loadStoreSurfaces[i]) TextureSurface();
  712. loadStoreSurfaces[i] = mLoadStoreSurfaces[i];
  713. new (&loadStoreTextures[i]) SPtr<TextureCore>();
  714. if (mLoadStoreTextures[i].isLoaded())
  715. loadStoreTextures[i] = mLoadStoreTextures[i]->getCore();
  716. else
  717. loadStoreTextures[i] = nullptr;
  718. }
  719. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Buffer]; i++)
  720. {
  721. new (&buffers[i]) SPtr<GpuBufferCore>();
  722. if (mBuffers[i] != nullptr)
  723. buffers[i] = mBuffers[i]->getCore();
  724. else
  725. buffers[i] = nullptr;
  726. }
  727. for (UINT32 i = 0; i < mNumElements[(int)ElementType::SamplerState]; i++)
  728. {
  729. new (&samplers[i]) SPtr<SamplerStateCore>();
  730. if (mSamplerStates[i] != nullptr)
  731. samplers[i] = mSamplerStates[i]->getCore();
  732. else
  733. samplers[i] = nullptr;
  734. }
  735. return CoreSyncData(data, totalSize);
  736. }
  737. void GpuParams::getListenerResources(Vector<HResource>& resources)
  738. {
  739. for (UINT32 i = 0; i < mNumElements[(int)ElementType::Texture]; i++)
  740. {
  741. if (mTextures[i] != nullptr)
  742. resources.push_back(mTextures[i]);
  743. }
  744. for (UINT32 i = 0; i < mNumElements[(int)ElementType::LoadStoreTexture]; i++)
  745. {
  746. if (mLoadStoreTextures[i] != nullptr)
  747. resources.push_back(mLoadStoreTextures[i]);
  748. }
  749. }
  750. }