BsGpuParams.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. #include "BsGpuParams.h"
  2. #include "BsGpuParamDesc.h"
  3. #include "BsGpuParamBlockBuffer.h"
  4. #include "BsVector2.h"
  5. #include "BsTexture.h"
  6. #include "BsSamplerState.h"
  7. #include "BsFrameAlloc.h"
  8. #include "BsDebug.h"
  9. #include "BsException.h"
  10. namespace BansheeEngine
  11. {
  12. GpuParamsBase::GpuParamsBase(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  13. :mParamDesc(paramDesc), mTransposeMatrices(transposeMatrices), mNumParamBlocks(0), mNumSamplerStates(0),
  14. mNumTextures(0), mTextureInfo(nullptr)
  15. {
  16. for (auto& paramBlock : mParamDesc->paramBlocks)
  17. {
  18. if ((paramBlock.second.slot + 1) > mNumParamBlocks)
  19. mNumParamBlocks = paramBlock.second.slot + 1;
  20. }
  21. for (auto& texture : mParamDesc->textures)
  22. {
  23. if ((texture.second.slot + 1) > mNumTextures)
  24. mNumTextures = texture.second.slot + 1;
  25. }
  26. for (auto& sampler : mParamDesc->samplers)
  27. {
  28. if ((sampler.second.slot + 1) > mNumSamplerStates)
  29. mNumSamplerStates = sampler.second.slot + 1;
  30. }
  31. mTextureInfo = bs_newN<BoundTextureInfo>(mNumTextures);
  32. }
  33. GpuParamsBase::~GpuParamsBase()
  34. {
  35. bs_deleteN(mTextureInfo, mNumTextures);
  36. }
  37. UINT32 GpuParamsBase::getDataParamSize(const String& name) const
  38. {
  39. GpuParamDataDesc* desc = getParamDesc(name);
  40. if(desc != nullptr)
  41. return desc->elementSize * 4;
  42. return 0;
  43. }
  44. bool GpuParamsBase::hasParam(const String& name) const
  45. {
  46. return getParamDesc(name) != nullptr;
  47. }
  48. bool GpuParamsBase::hasTexture(const String& name) const
  49. {
  50. auto paramIter = mParamDesc->textures.find(name);
  51. if(paramIter != mParamDesc->textures.end())
  52. return true;
  53. return false;
  54. }
  55. bool GpuParamsBase::hasSamplerState(const String& name) const
  56. {
  57. auto paramIter = mParamDesc->samplers.find(name);
  58. if(paramIter != mParamDesc->samplers.end())
  59. return true;
  60. return false;
  61. }
  62. bool GpuParamsBase::hasParamBlock(const String& name) const
  63. {
  64. auto paramBlockIter = mParamDesc->paramBlocks.find(name);
  65. if(paramBlockIter != mParamDesc->paramBlocks.end())
  66. return true;
  67. return false;
  68. }
  69. GpuParamDataDesc* GpuParamsBase::getParamDesc(const String& name) const
  70. {
  71. auto paramIter = mParamDesc->params.find(name);
  72. if (paramIter != mParamDesc->params.end())
  73. return &paramIter->second;
  74. return nullptr;
  75. }
  76. bool GpuParamsBase::isLoadStoreTexture(UINT32 slot) const
  77. {
  78. if (slot < 0 || slot >= mNumTextures)
  79. {
  80. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  81. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  82. }
  83. return mTextureInfo[slot].isLoadStore;
  84. }
  85. void GpuParamsBase::setIsLoadStoreTexture(UINT32 slot, bool isLoadStore)
  86. {
  87. if (slot < 0 || slot >= mNumTextures)
  88. {
  89. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  90. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  91. }
  92. mTextureInfo[slot].isLoadStore = isLoadStore;
  93. }
  94. const TextureSurface& GpuParamsBase::getLoadStoreSurface(UINT32 slot) const
  95. {
  96. if (slot < 0 || slot >= mNumTextures)
  97. {
  98. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  99. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  100. }
  101. return mTextureInfo[slot].surface;
  102. }
  103. void GpuParamsBase::setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const
  104. {
  105. if (slot < 0 || slot >= mNumTextures)
  106. {
  107. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  108. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  109. }
  110. mTextureInfo[slot].surface = surface;
  111. }
  112. template<bool Core>
  113. TGpuParams<Core>::TGpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  114. :GpuParamsBase(paramDesc, transposeMatrices), mParamBlockBuffers(nullptr), mTextures(nullptr),
  115. mSamplerStates(nullptr)
  116. {
  117. mParamBlockBuffers = bs_newN<ParamsBufferType>(mNumParamBlocks);
  118. mTextures = bs_newN<TextureType>(mNumTextures);
  119. mSamplerStates = bs_newN<SamplerType>(mNumSamplerStates);
  120. }
  121. template<bool Core>
  122. TGpuParams<Core>::~TGpuParams()
  123. {
  124. bs_deleteN(mParamBlockBuffers, mNumParamBlocks);
  125. bs_deleteN(mTextures, mNumTextures);
  126. bs_deleteN(mSamplerStates, mNumSamplerStates);
  127. }
  128. template<bool Core>
  129. void TGpuParams<Core>::setParamBlockBuffer(UINT32 slot, const ParamsBufferType& paramBlockBuffer)
  130. {
  131. if (slot < 0 || slot >= mNumParamBlocks)
  132. {
  133. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  134. toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
  135. }
  136. mParamBlockBuffers[slot] = paramBlockBuffer;
  137. _markCoreDirty();
  138. }
  139. template<bool Core>
  140. void TGpuParams<Core>::setParamBlockBuffer(const String& name, const ParamsBufferType& paramBlockBuffer)
  141. {
  142. auto iterFind = mParamDesc->paramBlocks.find(name);
  143. if (iterFind == mParamDesc->paramBlocks.end())
  144. {
  145. LOGWRN("Cannot find parameter block with the name: " + name);
  146. return;
  147. }
  148. mParamBlockBuffers[iterFind->second.slot] = paramBlockBuffer;
  149. _markCoreDirty();
  150. }
  151. template<class T> struct TDataParamInfo { };
  152. template<> struct TDataParamInfo < float > { enum { TypeId = GPDT_FLOAT1 }; };
  153. template<> struct TDataParamInfo < Color > { enum { TypeId = GPDT_FLOAT4 }; };
  154. template<> struct TDataParamInfo < Vector2 > { enum { TypeId = GPDT_FLOAT2 }; };
  155. template<> struct TDataParamInfo < Vector3 > { enum { TypeId = GPDT_FLOAT3 }; };
  156. template<> struct TDataParamInfo < Vector4 > { enum { TypeId = GPDT_FLOAT4 }; };
  157. template<> struct TDataParamInfo < Matrix3 > { enum { TypeId = GPDT_MATRIX_3X3 }; };
  158. template<> struct TDataParamInfo < Matrix4 > { enum { TypeId = GPDT_MATRIX_4X4 }; };
  159. template<bool Core>
  160. template<class T>
  161. void TGpuParams<Core>::getParam(const String& name, TGpuDataParam<T, Core>& output) const
  162. {
  163. auto iterFind = mParamDesc->params.find(name);
  164. if (iterFind == mParamDesc->params.end())
  165. {
  166. output = TGpuDataParam<T, Core>(&iterFind->second, nullptr);
  167. LOGWRN("Cannot find parameter with the name '" + name + "'");
  168. }
  169. else
  170. output = TGpuDataParam<T, Core>(&iterFind->second, _getThisPtr());
  171. }
  172. template<bool Core>
  173. void TGpuParams<Core>::getStructParam(const String& name, TGpuParamStruct<Core>& output) const
  174. {
  175. auto iterFind = mParamDesc->params.find(name);
  176. if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_STRUCT)
  177. {
  178. output = TGpuParamStruct<Core>(&iterFind->second, nullptr);
  179. LOGWRN("Cannot find struct parameter with the name '" + name + "'");
  180. }
  181. else
  182. output = TGpuParamStruct<Core>(&iterFind->second, _getThisPtr());
  183. }
  184. template<bool Core>
  185. void TGpuParams<Core>::getTextureParam(const String& name, TGpuParamTexture<Core>& output) const
  186. {
  187. auto iterFind = mParamDesc->textures.find(name);
  188. if (iterFind == mParamDesc->textures.end())
  189. {
  190. output = TGpuParamTexture<Core>(&iterFind->second, nullptr);
  191. LOGWRN("Cannot find texture parameter with the name '" + name + "'");
  192. }
  193. else
  194. output = TGpuParamTexture<Core>(&iterFind->second, _getThisPtr());
  195. }
  196. template<bool Core>
  197. void TGpuParams<Core>::getLoadStoreTextureParam(const String& name, TGpuParamLoadStoreTexture<Core>& output) const
  198. {
  199. auto iterFind = mParamDesc->textures.find(name);
  200. if (iterFind == mParamDesc->textures.end())
  201. {
  202. output = TGpuParamLoadStoreTexture<Core>(&iterFind->second, nullptr);
  203. LOGWRN("Cannot find texture parameter with the name '" + name + "'");
  204. }
  205. else
  206. output = TGpuParamLoadStoreTexture<Core>(&iterFind->second, _getThisPtr());
  207. }
  208. template<bool Core>
  209. void TGpuParams<Core>::getSamplerStateParam(const String& name, TGpuParamSampState<Core>& output) const
  210. {
  211. auto iterFind = mParamDesc->samplers.find(name);
  212. if (iterFind == mParamDesc->samplers.end())
  213. {
  214. output = TGpuParamSampState<Core>(&iterFind->second, nullptr);
  215. LOGWRN("Cannot find sampler state parameter with the name '" + name + "'");
  216. }
  217. else
  218. output = TGpuParamSampState<Core>(&iterFind->second, _getThisPtr());
  219. }
  220. template<bool Core>
  221. typename TGpuParams<Core>::ParamsBufferType TGpuParams<Core>::getParamBlockBuffer(UINT32 slot) const
  222. {
  223. if (slot < 0 || slot >= mNumParamBlocks)
  224. {
  225. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  226. toString(mNumParamBlocks - 1) + ". Requested: " + toString(slot));
  227. }
  228. return mParamBlockBuffers[slot];
  229. }
  230. template<bool Core>
  231. typename TGpuParams<Core>::TextureType TGpuParams<Core>::getTexture(UINT32 slot)
  232. {
  233. if (slot < 0 || slot >= mNumTextures)
  234. {
  235. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  236. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  237. }
  238. return mTextures[slot];
  239. }
  240. template<bool Core>
  241. typename TGpuParams<Core>::SamplerType TGpuParams<Core>::getSamplerState(UINT32 slot)
  242. {
  243. if (slot < 0 || slot >= mNumSamplerStates)
  244. {
  245. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  246. toString(mNumSamplerStates - 1) + ". Requested: " + toString(slot));
  247. }
  248. return mSamplerStates[slot];
  249. }
  250. template<bool Core>
  251. void TGpuParams<Core>::setTexture(UINT32 slot, const TextureType& texture)
  252. {
  253. if (slot < 0 || slot >= mNumTextures)
  254. {
  255. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  256. toString(mNumTextures - 1) + ". Requested: " + toString(slot));
  257. }
  258. mTextures[slot] = texture;
  259. _markResourcesDirty();
  260. _markCoreDirty();
  261. }
  262. template<bool Core>
  263. void TGpuParams<Core>::setSamplerState(UINT32 slot, const SamplerType& sampler)
  264. {
  265. if (slot < 0 || slot >= mNumSamplerStates)
  266. {
  267. BS_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  268. toString(mNumSamplerStates - 1) + ". Requested: " + toString(slot));
  269. }
  270. mSamplerStates[slot] = sampler;
  271. _markResourcesDirty();
  272. _markCoreDirty();
  273. }
  274. template class TGpuParams < false > ;
  275. template class TGpuParams < true > ;
  276. template BS_CORE_EXPORT void TGpuParams<false>::getParam<float>(const String&, TGpuDataParam<float, false>&) const;
  277. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Color>(const String&, TGpuDataParam<Color, false>&) const;
  278. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2>(const String&, TGpuDataParam<Vector2, false>&) const;
  279. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3>(const String&, TGpuDataParam<Vector3, false>&) const;
  280. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4>(const String&, TGpuDataParam<Vector4, false>&) const;
  281. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3>(const String&, TGpuDataParam<Matrix3, false>&) const;
  282. template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4>(const String&, TGpuDataParam<Matrix4, false>&) const;
  283. template BS_CORE_EXPORT void TGpuParams<true>::getParam<float>(const String&, TGpuDataParam<float, true>&) const;
  284. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Color>(const String&, TGpuDataParam<Color, true>&) const;
  285. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2>(const String&, TGpuDataParam<Vector2, true>&) const;
  286. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3>(const String&, TGpuDataParam<Vector3, true>&) const;
  287. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4>(const String&, TGpuDataParam<Vector4, true>&) const;
  288. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3>(const String&, TGpuDataParam<Matrix3, true>&) const;
  289. template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4>(const String&, TGpuDataParam<Matrix4, true>&) const;
  290. GpuParamsCore::GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  291. : TGpuParams(paramDesc, transposeMatrices)
  292. {
  293. }
  294. SPtr<GpuParamsCore> GpuParamsCore::_getThisPtr() const
  295. {
  296. return std::static_pointer_cast<GpuParamsCore>(getThisPtr());
  297. }
  298. void GpuParamsCore::updateHardwareBuffers()
  299. {
  300. for (UINT32 i = 0; i < mNumParamBlocks; i++)
  301. {
  302. if (mParamBlockBuffers[i] != nullptr)
  303. {
  304. mParamBlockBuffers[i]->flushToGPU();
  305. }
  306. }
  307. }
  308. void GpuParamsCore::syncToCore(const CoreSyncData& data)
  309. {
  310. UINT32 textureInfoSize = mNumTextures * sizeof(BoundTextureInfo);
  311. UINT32 paramBufferSize = mNumParamBlocks * sizeof(SPtr<GpuParamBlockBufferCore>);
  312. UINT32 textureArraySize = mNumTextures * sizeof(SPtr<TextureCore>);
  313. UINT32 samplerArraySize = mNumSamplerStates * sizeof(SPtr<SamplerStateCore>);
  314. UINT32 totalSize = textureInfoSize + paramBufferSize + textureArraySize + samplerArraySize;
  315. UINT32 textureInfoOffset = 0;
  316. UINT32 paramBufferOffset = textureInfoOffset + textureInfoSize;
  317. UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
  318. UINT32 samplerArrayOffset = textureArrayOffset + textureArraySize;
  319. assert(data.getBufferSize() == totalSize);
  320. UINT8* dataPtr = data.getBuffer();
  321. BoundTextureInfo* textureInfos = (BoundTextureInfo*)(dataPtr + textureInfoOffset);
  322. SPtr<GpuParamBlockBufferCore>* paramBuffers = (SPtr<GpuParamBlockBufferCore>*)(dataPtr + paramBufferOffset);
  323. SPtr<TextureCore>* textures = (SPtr<TextureCore>*)(dataPtr + textureArrayOffset);
  324. SPtr<SamplerStateCore>* samplers = (SPtr<SamplerStateCore>*)(dataPtr + samplerArrayOffset);
  325. // Copy & destruct
  326. for (UINT32 i = 0; i < mNumParamBlocks; i++)
  327. {
  328. mParamBlockBuffers[i] = paramBuffers[i];
  329. paramBuffers[i].~SPtr<GpuParamBlockBufferCore>();
  330. }
  331. for (UINT32 i = 0; i < mNumTextures; i++)
  332. {
  333. mTextureInfo[i] = textureInfos[i];
  334. textureInfos[i].~BoundTextureInfo();
  335. mTextures[i] = textures[i];
  336. textures[i].~SPtr<TextureCore>();
  337. }
  338. for (UINT32 i = 0; i < mNumSamplerStates; i++)
  339. {
  340. mSamplerStates[i] = samplers[i];
  341. samplers[i].~SPtr<SamplerStateCore>();
  342. }
  343. }
  344. SPtr<GpuParamsCore> GpuParamsCore::create(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  345. {
  346. GpuParamsCore* params = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(paramDesc, transposeMatrices);
  347. SPtr<GpuParamsCore> paramsPtr = bs_shared_ptr<GpuParamsCore, GenAlloc>(params);
  348. paramsPtr->_setThisPtr(paramsPtr);
  349. return paramsPtr;
  350. }
  351. GpuParams::GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  352. : TGpuParams(paramDesc, transposeMatrices)
  353. {
  354. }
  355. SPtr<GpuParams> GpuParams::_getThisPtr() const
  356. {
  357. return std::static_pointer_cast<GpuParams>(getThisPtr());
  358. }
  359. SPtr<GpuParamsCore> GpuParams::getCore() const
  360. {
  361. return std::static_pointer_cast<GpuParamsCore>(mCoreSpecific);
  362. }
  363. SPtr<CoreObjectCore> GpuParams::createCore() const
  364. {
  365. GpuParamsCore* obj = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(mParamDesc, mTransposeMatrices);
  366. SPtr<CoreObjectCore> coreObj = bs_shared_ptr<GpuParamsCore, GenAlloc>(obj);
  367. coreObj->_setThisPtr(coreObj);
  368. return coreObj;
  369. }
  370. void GpuParams::_markCoreDirty()
  371. {
  372. markCoreDirty();
  373. }
  374. void GpuParams::_markResourcesDirty()
  375. {
  376. markResourcesDirty();
  377. }
  378. SPtr<GpuParams> GpuParams::create(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  379. {
  380. GpuParams* params = new (bs_alloc<GpuParams>()) GpuParams(paramDesc, transposeMatrices);
  381. SPtr<GpuParams> paramsPtr = bs_core_ptr<GpuParams, GenAlloc>(params);
  382. paramsPtr->_setThisPtr(paramsPtr);
  383. paramsPtr->initialize();
  384. return paramsPtr;
  385. }
  386. CoreSyncData GpuParams::syncToCore(FrameAlloc* allocator)
  387. {
  388. UINT32 textureInfoSize = mNumTextures * sizeof(BoundTextureInfo);
  389. UINT32 paramBufferSize = mNumParamBlocks * sizeof(SPtr<GpuParamBlockBufferCore>);
  390. UINT32 textureArraySize = mNumTextures * sizeof(SPtr<TextureCore>);
  391. UINT32 samplerArraySize = mNumSamplerStates * sizeof(SPtr<SamplerStateCore>);
  392. UINT32 totalSize = textureInfoSize + paramBufferSize + textureArraySize + samplerArraySize;
  393. UINT32 textureInfoOffset = 0;
  394. UINT32 paramBufferOffset = textureInfoOffset + textureInfoSize;
  395. UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
  396. UINT32 samplerArrayOffset = textureArrayOffset + textureArraySize;
  397. UINT8* data = allocator->alloc(totalSize);
  398. BoundTextureInfo* textureInfos = (BoundTextureInfo*)(data + textureInfoOffset);
  399. SPtr<GpuParamBlockBufferCore>* paramBuffers = (SPtr<GpuParamBlockBufferCore>*)(data + paramBufferOffset);
  400. SPtr<TextureCore>* textures = (SPtr<TextureCore>*)(data + textureArrayOffset);
  401. SPtr<SamplerStateCore>* samplers = (SPtr<SamplerStateCore>*)(data + samplerArrayOffset);
  402. // Construct & copy
  403. for (UINT32 i = 0; i < mNumParamBlocks; i++)
  404. {
  405. new (&paramBuffers[i]) SPtr<GpuParamBlockBufferCore>();
  406. if (mParamBlockBuffers[i] != nullptr)
  407. paramBuffers[i] = mParamBlockBuffers[i]->getCore();
  408. }
  409. for (UINT32 i = 0; i < mNumTextures; i++)
  410. {
  411. new (&textureInfos[i]) BoundTextureInfo();
  412. textureInfos[i] = mTextureInfo[i];
  413. new (&textures[i]) SPtr<TextureCore>();
  414. if (mTextures[i].isLoaded())
  415. textures[i] = mTextures[i]->getCore();
  416. else
  417. textures[i] = nullptr;
  418. }
  419. for (UINT32 i = 0; i < mNumSamplerStates; i++)
  420. {
  421. new (&samplers[i]) SPtr<SamplerStateCore>();
  422. if (mSamplerStates[i].isLoaded())
  423. samplers[i] = mSamplerStates[i]->getCore();
  424. else
  425. samplers[i] = nullptr;
  426. }
  427. return CoreSyncData(data, totalSize);
  428. }
  429. void GpuParams::getResourceDependencies(Vector<HResource>& resources)
  430. {
  431. for (UINT32 i = 0; i < mNumTextures; i++)
  432. {
  433. if (mTextures[i] != nullptr)
  434. resources.push_back(mTextures[i]);
  435. }
  436. for (UINT32 i = 0; i < mNumSamplerStates; i++)
  437. {
  438. if (mSamplerStates[i] != nullptr)
  439. resources.push_back(mSamplerStates[i]);
  440. }
  441. }
  442. }