CmGpuParams.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #include "CmGpuParams.h"
  2. #include "CmGpuParamDesc.h"
  3. #include "CmGpuParamBlock.h"
  4. #include "CmVector2.h"
  5. #include "CmDebug.h"
  6. #include "CmException.h"
  7. namespace CamelotEngine
  8. {
  9. GpuParams::GpuParams(GpuParamDesc& paramDesc)
  10. :mParamDesc(paramDesc), mTransposeMatrices(false)
  11. {
  12. UINT32 numParamBlockSlots = 0;
  13. for(auto iter = mParamDesc.paramBlocks.begin(); iter != mParamDesc.paramBlocks.end(); ++iter)
  14. {
  15. if((iter->second.slot + 1) > numParamBlockSlots)
  16. numParamBlockSlots = iter->second.slot + 1;
  17. }
  18. mParamBlocks.resize(numParamBlockSlots);
  19. UINT32 numTextureSlots = 0;
  20. for(auto iter = mParamDesc.textures.begin(); iter != mParamDesc.textures.end(); ++iter)
  21. {
  22. if((iter->second.slot + 1) > numTextureSlots)
  23. numTextureSlots = iter->second.slot + 1;
  24. }
  25. mTextures.resize(numTextureSlots);
  26. UINT32 numSamplerSlots = 0;
  27. for(auto iter = mParamDesc.samplers.begin(); iter != mParamDesc.samplers.end(); ++iter)
  28. {
  29. if((iter->second.slot + 1) > numSamplerSlots)
  30. numSamplerSlots = iter->second.slot + 1;
  31. }
  32. mSamplerStates.resize(numSamplerSlots);
  33. }
  34. GpuParamBlockPtr GpuParams::getParamBlock(UINT32 slot) const
  35. {
  36. if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
  37. {
  38. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  39. toString(mParamBlocks.size() - 1) + ". Requested: " + toString(slot));
  40. }
  41. return mParamBlocks[slot];
  42. }
  43. GpuParamBlockPtr GpuParams::getParamBlock(const String& name) const
  44. {
  45. auto iterFind = mParamDesc.paramBlocks.find(name);
  46. if(iterFind == mParamDesc.paramBlocks.end())
  47. {
  48. LOGWRN("Cannot find parameter block with the name: " + name);
  49. return nullptr;
  50. }
  51. return mParamBlocks[iterFind->second.slot];
  52. }
  53. void GpuParams::setParamBlock(UINT32 slot, GpuParamBlockPtr paramBlock)
  54. {
  55. if(slot < 0 || slot >= (UINT32)mParamBlocks.size())
  56. {
  57. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  58. toString(mParamBlocks.size() - 1) + ". Requested: " + toString(slot));
  59. }
  60. mParamBlocks[slot] = paramBlock;
  61. }
  62. void GpuParams::setParamBlock(const String& name, GpuParamBlockPtr paramBlock)
  63. {
  64. auto iterFind = mParamDesc.paramBlocks.find(name);
  65. if(iterFind == mParamDesc.paramBlocks.end())
  66. {
  67. LOGWRN("Cannot find parameter block with the name: " + name);
  68. return;
  69. }
  70. mParamBlocks[iterFind->second.slot] = paramBlock;
  71. }
  72. UINT32 GpuParams::getDataParamSize(const String& name) const
  73. {
  74. GpuParamDataDesc* desc = getParamDesc(name);
  75. if(desc != nullptr)
  76. return desc->elementSize * 4;
  77. return 0;
  78. }
  79. bool GpuParams::hasParam(const String& name) const
  80. {
  81. return getParamDesc(name) != nullptr;
  82. }
  83. bool GpuParams::hasTexture(const String& name) const
  84. {
  85. auto paramIter = mParamDesc.textures.find(name);
  86. if(paramIter != mParamDesc.textures.end())
  87. return true;
  88. return false;
  89. }
  90. bool GpuParams::hasSamplerState(const String& name) const
  91. {
  92. auto paramIter = mParamDesc.samplers.find(name);
  93. if(paramIter != mParamDesc.samplers.end())
  94. return true;
  95. return false;
  96. }
  97. bool GpuParams::hasParamBlock(const String& name) const
  98. {
  99. auto paramBlockIter = mParamDesc.paramBlocks.find(name);
  100. if(paramBlockIter != mParamDesc.paramBlocks.end())
  101. return true;
  102. return false;
  103. }
  104. void GpuParams::setParam(const String& name, float value, UINT32 arrayIndex)
  105. {
  106. setParam(name, (void*)&value, 1 * sizeof(float), arrayIndex);
  107. }
  108. void GpuParams::setParam(const String& name, int value, UINT32 arrayIndex)
  109. {
  110. setParam(name, (void*)&value, 1 * sizeof(int), arrayIndex);
  111. }
  112. void GpuParams::setParam(const String& name, bool value, UINT32 arrayIndex)
  113. {
  114. setParam(name, (void*)&value, 1 * sizeof(bool), arrayIndex);
  115. }
  116. void GpuParams::setParam(const String& name, const Vector4& vec, UINT32 arrayIndex)
  117. {
  118. setParam(name, (void*)&vec, 4 * sizeof(float), arrayIndex);
  119. }
  120. void GpuParams::setParam(const String& name, const Vector3& vec, UINT32 arrayIndex)
  121. {
  122. setParam(name, (void*)&vec, 3 * sizeof(float), arrayIndex);
  123. }
  124. void GpuParams::setParam(const String& name, const Vector2& vec, UINT32 arrayIndex)
  125. {
  126. setParam(name, (void*)&vec, 2 * sizeof(float), arrayIndex);
  127. }
  128. void GpuParams::setParam(const String& name, const Matrix4& mat, UINT32 arrayIndex)
  129. {
  130. if (mTransposeMatrices)
  131. {
  132. Matrix4 transMat = mat.transpose();
  133. setParam(name, (void*)&transMat, 16 * sizeof(float), arrayIndex);
  134. }
  135. else
  136. {
  137. setParam(name, (void*)&mat, 16 * sizeof(float), arrayIndex);
  138. }
  139. }
  140. void GpuParams::setParam(const String& name, const Matrix3& mat, UINT32 arrayIndex)
  141. {
  142. if (mTransposeMatrices)
  143. {
  144. Matrix3 transMat = mat.transpose();
  145. setParam(name, (void*)&transMat, 9 * sizeof(float), arrayIndex);
  146. }
  147. else
  148. {
  149. setParam(name, (void*)&mat, 9 * sizeof(float), arrayIndex);
  150. }
  151. }
  152. void GpuParams::setParam(const String& name, const Color& color, UINT32 arrayIndex)
  153. {
  154. setParam(name, (void*)&color, 4 * sizeof(float), arrayIndex);
  155. }
  156. void GpuParams::setParam(const String& name, const void* value, UINT32 sizeBytes, UINT32 arrayIndex)
  157. {
  158. GpuParamDataDesc* desc = getParamDesc(name);
  159. if(desc == nullptr)
  160. {
  161. LOGWRN("Cannot find parameter with the name '" + name + "'");
  162. return;
  163. }
  164. if(arrayIndex >= desc->arraySize)
  165. {
  166. CM_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
  167. toString(desc->arraySize) + ". Requested size: " + toString(arrayIndex));
  168. }
  169. UINT32 elementSizeBytes = desc->elementSize * sizeof(UINT32);
  170. if(sizeBytes > elementSizeBytes)
  171. {
  172. CM_EXCEPT(InvalidParametersException, "Provided element size larger than maximum element size. Maximum size: " +
  173. toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
  174. }
  175. GpuParamBlockPtr paramBlock = mParamBlocks[desc->paramBlockSlot];
  176. if(paramBlock == nullptr)
  177. {
  178. LOGWRN("Parameter exists but there is no ParamBlock set.");
  179. return;
  180. }
  181. paramBlock->write((desc->cpuMemOffset + arrayIndex * desc->arrayElementStride) * sizeof(UINT32), value, sizeBytes);
  182. // Set unused bytes to 0
  183. if(sizeBytes < elementSizeBytes)
  184. {
  185. UINT32 diffSize = elementSizeBytes - sizeBytes;
  186. paramBlock->zeroOut((desc->cpuMemOffset + arrayIndex * desc->arrayElementStride + sizeBytes) * sizeof(UINT32), diffSize);
  187. }
  188. }
  189. void GpuParams::setTexture(const String& name, TextureHandle& val)
  190. {
  191. auto paramIter = mParamDesc.textures.find(name);
  192. if(paramIter == mParamDesc.textures.end())
  193. {
  194. LOGWRN("Texture with the name '" + name + "' doesn't exist.");
  195. return;
  196. }
  197. mTextures[paramIter->second.slot] = val;
  198. }
  199. TextureHandle GpuParams::getTexture(UINT32 slot)
  200. {
  201. if(slot < 0 || slot >= (UINT32)mTextures.size())
  202. {
  203. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  204. toString(mTextures.size() - 1) + ". Requested: " + toString(slot));
  205. }
  206. return mTextures[slot];
  207. }
  208. void GpuParams::setSamplerState(const String& name, SamplerStateHandle& val)
  209. {
  210. auto paramIter = mParamDesc.samplers.find(name);
  211. if(paramIter == mParamDesc.samplers.end())
  212. {
  213. LOGWRN("Sampler with the name '" + name + "' doesn't exist.");
  214. return;
  215. }
  216. mSamplerStates[paramIter->second.slot] = val;
  217. }
  218. SamplerStateHandle GpuParams::getSamplerState(UINT32 slot)
  219. {
  220. if(slot < 0 || slot >= (UINT32)mSamplerStates.size())
  221. {
  222. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  223. toString(mSamplerStates.size() - 1) + ". Requested: " + toString(slot));
  224. }
  225. return mSamplerStates[slot];
  226. }
  227. void GpuParams::updateParamBuffers()
  228. {
  229. for(size_t i = 0; i < mParamBlocks.size(); i++)
  230. {
  231. if(mParamBlocks[i] != nullptr)
  232. mParamBlocks[i]->updateBuffer();
  233. }
  234. }
  235. GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const
  236. {
  237. auto paramIter = mParamDesc.params.find(name);
  238. if(paramIter != mParamDesc.params.end())
  239. return &paramIter->second;
  240. return nullptr;
  241. }
  242. }