CmGpuParam.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmGpuParamDesc.h"
  4. #include "CmGpuParamBlock.h"
  5. #include "CmDebug.h"
  6. #include "CmException.h"
  7. #include "CmMatrix3.h"
  8. #include "CmMatrix4.h"
  9. namespace BansheeEngine
  10. {
  11. /**
  12. * @brief A handle that allows you to set a GpuProgram parameter.
  13. *
  14. * @note This is primarily used an as optimization is performance critical bits of code
  15. * where it is important to locate and set parameters quickly without any lookups.
  16. * You just retrieve the handle once and then set the parameter value many times
  17. * with minimal performance impact.
  18. */
  19. template<class T>
  20. class CM_EXPORT GpuDataParamBase
  21. {
  22. private:
  23. friend class GpuParams;
  24. struct InternalData
  25. {
  26. InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks, bool transpose)
  27. :paramDesc(paramDesc), paramBlocks(paramBlocks), transpose(transpose), isDestroyed(false)
  28. { }
  29. InternalData()
  30. :paramDesc(nullptr), paramBlocks(nullptr), transpose(false), isDestroyed(true)
  31. { }
  32. ~InternalData()
  33. { }
  34. GpuParamDataDesc* paramDesc;
  35. GpuParamBlock** paramBlocks;
  36. bool transpose;
  37. bool isDestroyed;
  38. };
  39. template<class Type>
  40. struct TransposePolicy
  41. {
  42. static Type transpose(const Type& value) { return value; }
  43. static bool transposeEnabled(bool enabled) { return false; }
  44. };
  45. template<>
  46. struct TransposePolicy<Matrix3>
  47. {
  48. static Matrix3 transpose(const Matrix3& value) { return value.transpose(); }
  49. static bool transposeEnabled(bool enabled) { return enabled; }
  50. };
  51. template<>
  52. struct TransposePolicy<Matrix4>
  53. {
  54. static Matrix4 transpose(const Matrix4& value) { return value.transpose(); }
  55. static bool transposeEnabled(bool enabled) { return enabled; }
  56. };
  57. public:
  58. GpuDataParamBase()
  59. :mData(cm_shared_ptr<InternalData>())
  60. { }
  61. void set(const T& value, UINT32 arrayIdx = 0)
  62. {
  63. if(mData->isDestroyed)
  64. CM_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
  65. GpuParamDataDesc* paramDesc = mData->paramDesc;
  66. #if CM_DEBUG_MODE
  67. if(arrayIdx >= paramDesc->arraySize)
  68. {
  69. CM_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
  70. toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
  71. }
  72. #endif
  73. UINT32 sizeBytes = sizeof(T);
  74. GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
  75. if(TransposePolicy<T>::transposeEnabled(mData->transpose))
  76. {
  77. T transposed = TransposePolicy<T>::transpose(value);
  78. paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
  79. }
  80. else
  81. paramBlock->write((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
  82. // Set unused bytes to 0
  83. UINT32 elementSizeBytes = paramDesc->elementSize * sizeof(UINT32);
  84. if(sizeBytes < elementSizeBytes)
  85. {
  86. UINT32 diffSize = elementSizeBytes - sizeBytes;
  87. paramBlock->zeroOut((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32) + sizeBytes, diffSize);
  88. }
  89. }
  90. T get(UINT32 arrayIdx = 0)
  91. {
  92. if(mData->isDestroyed)
  93. CM_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
  94. GpuParamDataDesc* paramDesc = mData->paramDesc;
  95. #if CM_DEBUG_MODE
  96. if(arrayIdx >= paramDesc->arraySize)
  97. {
  98. CM_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " +
  99. toString(paramDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
  100. }
  101. #endif
  102. UINT32 sizeBytes = sizeof(T);
  103. GpuParamBlock* paramBlock = mData->paramBlocks[paramDesc->paramBlockSlot];
  104. T value;
  105. paramBlock->read((paramDesc->cpuMemOffset + arrayIdx * paramDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
  106. if(TransposePolicy<T>::transposeEnabled(mData->transpose))
  107. return TransposePolicy<T>::transpose(value);
  108. else
  109. return value;
  110. }
  111. void destroy()
  112. {
  113. mData->isDestroyed = true;
  114. }
  115. private:
  116. GpuDataParamBase(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks, bool transpose)
  117. :mData(cm_shared_ptr<InternalData>(paramDesc, paramBlocks, transpose))
  118. { }
  119. private:
  120. std::shared_ptr<InternalData> mData;
  121. };
  122. typedef GpuDataParamBase<float> GpuParamFloat;
  123. typedef GpuDataParamBase<Vector2> GpuParamVec2;
  124. typedef GpuDataParamBase<Vector3> GpuParamVec3;
  125. typedef GpuDataParamBase<Vector4> GpuParamVec4;
  126. typedef GpuDataParamBase<Matrix3> GpuParamMat3;
  127. typedef GpuDataParamBase<Matrix4> GpuParamMat4;
  128. /**
  129. * @copydoc GpuDataParamBase
  130. */
  131. class CM_EXPORT GpuParamStruct
  132. {
  133. private:
  134. friend class GpuParams;
  135. struct InternalData
  136. {
  137. InternalData(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks);
  138. InternalData();
  139. ~InternalData();
  140. GpuParamDataDesc* paramDesc;
  141. GpuParamBlock** paramBlocks;
  142. bool isDestroyed;
  143. };
  144. public:
  145. GpuParamStruct();
  146. void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
  147. void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
  148. UINT32 getElementSize() const;
  149. void destroy();
  150. private:
  151. GpuParamStruct(GpuParamDataDesc* paramDesc, GpuParamBlock** paramBlocks);
  152. private:
  153. std::shared_ptr<InternalData> mData;
  154. };
  155. /**
  156. * @copydoc GpuDataParamBase
  157. */
  158. class CM_EXPORT GpuParamTexture
  159. {
  160. private:
  161. friend class GpuParams;
  162. struct InternalData
  163. {
  164. InternalData(GpuParamObjectDesc* paramDesc, HTexture* textures);
  165. InternalData();
  166. ~InternalData();
  167. GpuParamObjectDesc* paramDesc;
  168. HTexture* textures;
  169. bool isDestroyed;
  170. };
  171. public:
  172. GpuParamTexture();
  173. void set(const HTexture& texture);
  174. HTexture get();
  175. void destroy();
  176. private:
  177. GpuParamTexture(GpuParamObjectDesc* paramDesc, HTexture* textures);
  178. private:
  179. std::shared_ptr<InternalData> mData;
  180. };
  181. /**
  182. * @copydoc GpuDataParamBase
  183. */
  184. class CM_EXPORT GpuParamSampState
  185. {
  186. private:
  187. friend class GpuParams;
  188. struct InternalData
  189. {
  190. InternalData(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates);
  191. InternalData();
  192. ~InternalData();
  193. GpuParamObjectDesc* paramDesc;
  194. HSamplerState* samplerStates;
  195. bool isDestroyed;
  196. };
  197. public:
  198. GpuParamSampState();
  199. void set(const HSamplerState& texture);
  200. HSamplerState get();
  201. void destroy();
  202. private:
  203. GpuParamSampState(GpuParamObjectDesc* paramDesc, HSamplerState* samplerStates);
  204. private:
  205. std::shared_ptr<InternalData> mData;
  206. };
  207. }