CmGpuParams.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. bool GpuParams::hasParam(const String& name) const
  73. {
  74. return getParamDesc(name) != nullptr;
  75. }
  76. bool GpuParams::hasTexture(const String& name) const
  77. {
  78. auto paramIter = mParamDesc.textures.find(name);
  79. if(paramIter != mParamDesc.textures.end())
  80. return true;
  81. return false;
  82. }
  83. bool GpuParams::hasSamplerState(const String& name) const
  84. {
  85. auto paramIter = mParamDesc.samplers.find(name);
  86. if(paramIter != mParamDesc.samplers.end())
  87. return true;
  88. return false;
  89. }
  90. bool GpuParams::hasParamBlock(const String& name) const
  91. {
  92. auto paramBlockIter = mParamDesc.paramBlocks.find(name);
  93. if(paramBlockIter != mParamDesc.paramBlocks.end())
  94. return true;
  95. return false;
  96. }
  97. void GpuParams::setParam(const String& name, float value, UINT32 arrayIndex)
  98. {
  99. setParam(name, (void*)&value, 1 * sizeof(float), arrayIndex);
  100. }
  101. void GpuParams::setParam(const String& name, int value, UINT32 arrayIndex)
  102. {
  103. setParam(name, (void*)&value, 1 * sizeof(int), arrayIndex);
  104. }
  105. void GpuParams::setParam(const String& name, bool value, UINT32 arrayIndex)
  106. {
  107. setParam(name, (void*)&value, 1 * sizeof(bool), arrayIndex);
  108. }
  109. void GpuParams::setParam(const String& name, const Vector4& vec, UINT32 arrayIndex)
  110. {
  111. setParam(name, (void*)&vec, 4 * sizeof(float), arrayIndex);
  112. }
  113. void GpuParams::setParam(const String& name, const Vector3& vec, UINT32 arrayIndex)
  114. {
  115. setParam(name, (void*)&vec, 3 * sizeof(float), arrayIndex);
  116. }
  117. void GpuParams::setParam(const String& name, const Vector2& vec, UINT32 arrayIndex)
  118. {
  119. setParam(name, (void*)&vec, 2 * sizeof(float), arrayIndex);
  120. }
  121. void GpuParams::setParam(const String& name, const Matrix4& mat, UINT32 arrayIndex)
  122. {
  123. if (mTransposeMatrices)
  124. {
  125. Matrix4 transMat = mat.transpose();
  126. setParam(name, (void*)&transMat, 16 * sizeof(float), arrayIndex);
  127. }
  128. else
  129. {
  130. setParam(name, (void*)&mat, 16 * sizeof(float), arrayIndex);
  131. }
  132. }
  133. void GpuParams::setParam(const String& name, const Matrix3& mat, UINT32 arrayIndex)
  134. {
  135. if (mTransposeMatrices)
  136. {
  137. Matrix3 transMat = mat.transpose();
  138. setParam(name, (void*)&transMat, 9 * sizeof(float), arrayIndex);
  139. }
  140. else
  141. {
  142. setParam(name, (void*)&mat, 9 * sizeof(float), arrayIndex);
  143. }
  144. }
  145. void GpuParams::setParam(const String& name, const Color& color, UINT32 arrayIndex)
  146. {
  147. setParam(name, (void*)&color, 4 * sizeof(float), arrayIndex);
  148. }
  149. void GpuParams::setParam(const String& name, const void* value, UINT32 sizeBytes, UINT32 arrayIndex)
  150. {
  151. GpuParamDataDesc* desc = getParamDesc(name);
  152. if(desc == nullptr)
  153. {
  154. LOGWRN("Cannot find parameter with the name '" + name + "'");
  155. return;
  156. }
  157. if(arrayIndex >= desc->arraySize)
  158. {
  159. CM_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
  160. toString(desc->arraySize) + ". Requested size: " + toString(arrayIndex));
  161. }
  162. UINT32 elementSizeBytes = desc->elementSize * sizeof(UINT32);
  163. if(sizeBytes > elementSizeBytes)
  164. {
  165. CM_EXCEPT(InvalidParametersException, "Provided element size larger than maximum element size. Maximum size: " +
  166. toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes));
  167. }
  168. GpuParamBlockPtr paramBlock = mParamBlocks[desc->paramBlockSlot];
  169. if(paramBlock == nullptr)
  170. {
  171. LOGWRN("Parameter exists but there is no ParamBlock set.");
  172. return;
  173. }
  174. paramBlock->write((desc->cpuMemOffset + arrayIndex * desc->elementSize) * sizeof(UINT32), value, sizeBytes);
  175. // Set unused bytes to 0
  176. if(sizeBytes < elementSizeBytes)
  177. {
  178. UINT32 diffSize = elementSizeBytes - sizeBytes;
  179. paramBlock->zeroOut((desc->cpuMemOffset + arrayIndex * desc->elementSize + sizeBytes) * sizeof(UINT32), diffSize);
  180. }
  181. }
  182. void GpuParams::setTexture(const String& name, TextureHandle& val)
  183. {
  184. auto paramIter = mParamDesc.textures.find(name);
  185. if(paramIter == mParamDesc.textures.end())
  186. {
  187. LOGWRN("Texture with the name '" + name + "' doesn't exist.");
  188. return;
  189. }
  190. mTextures[paramIter->second.slot] = val;
  191. }
  192. TextureHandle GpuParams::getTexture(UINT32 slot)
  193. {
  194. if(slot < 0 || slot >= (UINT32)mTextures.size())
  195. {
  196. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  197. toString(mTextures.size() - 1) + ". Requested: " + toString(slot));
  198. }
  199. return mTextures[slot];
  200. }
  201. void GpuParams::setSamplerState(const String& name, SamplerStateHandle& val)
  202. {
  203. auto paramIter = mParamDesc.samplers.find(name);
  204. if(paramIter == mParamDesc.samplers.end())
  205. {
  206. LOGWRN("Sampler with the name '" + name + "' doesn't exist.");
  207. return;
  208. }
  209. mSamplerStates[paramIter->second.slot] = val;
  210. }
  211. SamplerStateHandle GpuParams::getSamplerState(UINT32 slot)
  212. {
  213. if(slot < 0 || slot >= (UINT32)mSamplerStates.size())
  214. {
  215. CM_EXCEPT(InvalidParametersException, "Index out of range: Valid range: 0 .. " +
  216. toString(mSamplerStates.size() - 1) + ". Requested: " + toString(slot));
  217. }
  218. return mSamplerStates[slot];
  219. }
  220. GpuParamsPtr GpuParams::clone() const
  221. {
  222. GpuParamsPtr clonedParams(new GpuParams(*this));
  223. for(size_t i = 0; i < mParamBlocks.size(); i++)
  224. {
  225. if(mParamBlocks[i] != nullptr)
  226. clonedParams->mParamBlocks[i] = mParamBlocks[i]->clone();
  227. }
  228. return clonedParams;
  229. }
  230. void GpuParams::updateIfDirty()
  231. {
  232. for(size_t i = 0; i < mParamBlocks.size(); i++)
  233. {
  234. if(mParamBlocks[i] != nullptr)
  235. mParamBlocks[i]->updateIfDirty();
  236. }
  237. }
  238. GpuParamDataDesc* GpuParams::getParamDesc(const String& name) const
  239. {
  240. auto paramIter = mParamDesc.params.find(name);
  241. if(paramIter != mParamDesc.params.end())
  242. return &paramIter->second;
  243. return nullptr;
  244. }
  245. }