BsGpuParams.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. GpuParamsCore::GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  113. : TGpuParams(paramDesc, transposeMatrices)
  114. {
  115. }
  116. void GpuParamsCore::updateHardwareBuffers()
  117. {
  118. for (UINT32 i = 0; i < mNumParamBlocks; i++)
  119. {
  120. if (mParamBlockBuffers[i] != nullptr)
  121. {
  122. mParamBlockBuffers[i]->flushToGPU();
  123. }
  124. }
  125. }
  126. void GpuParamsCore::syncToCore(const CoreSyncData& data)
  127. {
  128. UINT32 textureInfoSize = mNumTextures * sizeof(BoundTextureInfo);
  129. UINT32 paramBufferSize = mNumParamBlocks * sizeof(SPtr<GpuParamBlockBufferCore>);
  130. UINT32 textureArraySize = mNumTextures * sizeof(SPtr<TextureCore>);
  131. UINT32 samplerArraySize = mNumSamplerStates * sizeof(SPtr<SamplerStateCore>);
  132. UINT32 totalSize = textureInfoSize + paramBufferSize + textureArraySize + samplerArraySize;
  133. UINT32 textureInfoOffset = 0;
  134. UINT32 paramBufferOffset = textureInfoOffset + textureInfoSize;
  135. UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
  136. UINT32 samplerArrayOffset = textureArrayOffset + textureArraySize;
  137. assert(data.getBufferSize() == totalSize);
  138. UINT8* dataPtr = data.getBuffer();
  139. BoundTextureInfo* textureInfos = (BoundTextureInfo*)(dataPtr + textureInfoOffset);
  140. SPtr<GpuParamBlockBufferCore>* paramBuffers = (SPtr<GpuParamBlockBufferCore>*)(dataPtr + paramBufferOffset);
  141. SPtr<TextureCore>* textures = (SPtr<TextureCore>*)(dataPtr + textureArrayOffset);
  142. SPtr<SamplerStateCore>* samplers = (SPtr<SamplerStateCore>*)(dataPtr + samplerArrayOffset);
  143. // Copy & destruct
  144. for (UINT32 i = 0; i < mNumParamBlocks; i++)
  145. {
  146. mParamBlockBuffers[i] = paramBuffers[i];
  147. paramBuffers[i].~SPtr<GpuParamBlockBufferCore>();
  148. }
  149. for (UINT32 i = 0; i < mNumTextures; i++)
  150. {
  151. mTextureInfo[i] = textureInfos[i];
  152. textureInfos[i].~BoundTextureInfo();
  153. mTextures[i] = textures[i];
  154. textures[i].~SPtr<TextureCore>();
  155. }
  156. for (UINT32 i = 0; i < mNumSamplerStates; i++)
  157. {
  158. mSamplerStates[i] = samplers[i];
  159. samplers[i].~SPtr<SamplerStateCore>();
  160. }
  161. }
  162. SPtr<GpuParamsCore> GpuParamsCore::create(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  163. {
  164. GpuParamsCore* params = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(paramDesc, transposeMatrices);
  165. SPtr<GpuParamsCore> paramsPtr = bs_shared_ptr<GpuParamsCore, GenAlloc>(params);
  166. paramsPtr->_setThisPtr(paramsPtr);
  167. return paramsPtr;
  168. }
  169. GpuParams::GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  170. : TGpuParams(paramDesc, transposeMatrices)
  171. {
  172. }
  173. SPtr<GpuParamsCore> GpuParams::getCore() const
  174. {
  175. return std::static_pointer_cast<GpuParamsCore>(mCoreSpecific);
  176. }
  177. SPtr<CoreObjectCore> GpuParams::createCore() const
  178. {
  179. GpuParamsCore* obj = new (bs_alloc<GpuParamsCore>()) GpuParamsCore(mParamDesc, mTransposeMatrices);
  180. SPtr<CoreObjectCore> coreObj = bs_shared_ptr<GpuParamsCore, GenAlloc>(obj);
  181. coreObj->_setThisPtr(coreObj);
  182. return coreObj;
  183. }
  184. void GpuParams::_markCoreDirty()
  185. {
  186. markCoreDirty();
  187. }
  188. SPtr<GpuParams> GpuParams::create(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
  189. {
  190. GpuParams* params = new (bs_alloc<GpuParams>()) GpuParams(paramDesc, transposeMatrices);
  191. SPtr<GpuParams> paramsPtr = bs_core_ptr<GpuParams, GenAlloc>(params);
  192. paramsPtr->_setThisPtr(paramsPtr);
  193. paramsPtr->initialize();
  194. return paramsPtr;
  195. }
  196. CoreSyncData GpuParams::syncToCore(FrameAlloc* allocator)
  197. {
  198. UINT32 textureInfoSize = mNumTextures * sizeof(BoundTextureInfo);
  199. UINT32 paramBufferSize = mNumParamBlocks * sizeof(SPtr<GpuParamBlockBufferCore>);
  200. UINT32 textureArraySize = mNumTextures * sizeof(SPtr<TextureCore>);
  201. UINT32 samplerArraySize = mNumSamplerStates * sizeof(SPtr<SamplerStateCore>);
  202. UINT32 totalSize = textureInfoSize + paramBufferSize + textureArraySize + samplerArraySize;
  203. UINT32 textureInfoOffset = 0;
  204. UINT32 paramBufferOffset = textureInfoOffset + textureInfoSize;
  205. UINT32 textureArrayOffset = paramBufferOffset + paramBufferSize;
  206. UINT32 samplerArrayOffset = textureArrayOffset + textureArraySize;
  207. UINT8* data = allocator->alloc(totalSize);
  208. BoundTextureInfo* textureInfos = (BoundTextureInfo*)(data + textureInfoOffset);
  209. SPtr<GpuParamBlockBufferCore>* paramBuffers = (SPtr<GpuParamBlockBufferCore>*)(data + paramBufferOffset);
  210. SPtr<TextureCore>* textures = (SPtr<TextureCore>*)(data + textureArrayOffset);
  211. SPtr<SamplerStateCore>* samplers = (SPtr<SamplerStateCore>*)(data + samplerArrayOffset);
  212. // Construct & copy
  213. for (UINT32 i = 0; i < mNumParamBlocks; i++)
  214. {
  215. new (&paramBuffers[i]) SPtr<GpuParamBlockBufferCore>();
  216. if (mParamBlockBuffers[i] != nullptr)
  217. paramBuffers[i] = mParamBlockBuffers[i]->getCore();
  218. }
  219. for (UINT32 i = 0; i < mNumTextures; i++)
  220. {
  221. new (&textureInfos[i]) BoundTextureInfo();
  222. textureInfos[i] = mTextureInfo[i];
  223. new (&textures[i]) SPtr<TextureCore>();
  224. if (mTextures[i].isLoaded())
  225. textures[i] = mTextures[i]->getCore();
  226. else
  227. textures[i] = nullptr;
  228. }
  229. for (UINT32 i = 0; i < mNumSamplerStates; i++)
  230. {
  231. new (&samplers[i]) SPtr<SamplerStateCore>();
  232. if (mSamplerStates[i].isLoaded())
  233. samplers[i] = mSamplerStates[i]->getCore();
  234. else
  235. samplers[i] = nullptr;
  236. }
  237. return CoreSyncData(data, totalSize);
  238. }
  239. }