BsShader.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. //__________________________ Banshee Project - A modern game development toolkit _________________________________//
  2. //_____________________________________ www.banshee-project.com __________________________________________________//
  3. //________________________ Copyright (c) 2014 Marko Pintera. All rights reserved. ________________________________//
  4. #include "BsShader.h"
  5. #include "BsTechnique.h"
  6. #include "BsException.h"
  7. #include "BsDebug.h"
  8. #include "BsShaderProxy.h"
  9. #include "BsShaderRTTI.h"
  10. namespace BansheeEngine
  11. {
  12. Shader::Shader(const String& name)
  13. :mName(name), mQueueSortType(QueueSortType::FrontToBack), mQueuePriority((UINT32)QueuePriority::Opaque),
  14. mSeparablePasses(true), mCoreDirtyFlags(0xFFFFFFFF)
  15. {
  16. }
  17. TechniquePtr Shader::addTechnique(const String& renderSystem, const String& renderer)
  18. {
  19. TechniquePtr technique = bs_shared_ptr<Technique, PoolAlloc>(renderSystem, renderer);
  20. mTechniques.push_back(technique);
  21. return technique;
  22. }
  23. void Shader::removeTechnique(UINT32 idx)
  24. {
  25. if(idx < 0 || idx >= mTechniques.size())
  26. BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx));
  27. int count = 0;
  28. auto iter = mTechniques.begin();
  29. while(count != idx)
  30. {
  31. ++count;
  32. ++iter;
  33. }
  34. mTechniques.erase(iter);
  35. }
  36. void Shader::removeTechnique(TechniquePtr technique)
  37. {
  38. auto iterFind = std::find(mTechniques.begin(), mTechniques.end(), technique);
  39. if(iterFind == mTechniques.end())
  40. BS_EXCEPT(InvalidParametersException, "Cannot remove specified technique because it wasn't found in this shader.");
  41. mTechniques.erase(iterFind);
  42. }
  43. TechniquePtr Shader::getBestTechnique() const
  44. {
  45. for(auto iter = mTechniques.begin(); iter != mTechniques.end(); ++iter)
  46. {
  47. if((*iter)->isSupported())
  48. {
  49. return *iter;
  50. }
  51. }
  52. return nullptr;
  53. // TODO - Low priority. Instead of returning null use an extremely simple technique that will be supported almost everywhere as a fallback.
  54. }
  55. void Shader::setQueueSortType(QueueSortType sortType)
  56. {
  57. mQueueSortType = sortType;
  58. markCoreDirty();
  59. }
  60. void Shader::setQueuePriority(UINT32 priority)
  61. {
  62. mQueuePriority = priority;
  63. markCoreDirty();
  64. }
  65. void Shader::setAllowSeparablePasses(bool enable)
  66. {
  67. mSeparablePasses = enable;
  68. markCoreDirty();
  69. }
  70. void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 rendererSemantic, UINT32 arraySize, UINT32 elementSize)
  71. {
  72. if(type == GPDT_STRUCT && elementSize <= 0)
  73. BS_EXCEPT(InvalidParametersException, "You need to provide a non-zero element size for a struct parameter.")
  74. SHADER_DATA_PARAM_DESC desc;
  75. desc.name = name;
  76. desc.gpuVariableName = gpuVariableName;
  77. desc.type = type;
  78. desc.arraySize = arraySize;
  79. desc.rendererSemantic = rendererSemantic;
  80. desc.elementSize = elementSize;
  81. mDataParams[name] = desc;
  82. mObjectParams.erase(name);
  83. markCoreDirty();
  84. }
  85. void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, UINT32 rendererSemantic)
  86. {
  87. SHADER_OBJECT_PARAM_DESC desc;
  88. desc.name = name;
  89. desc.gpuVariableName = gpuVariableName;
  90. desc.type = type;
  91. desc.rendererSemantic = rendererSemantic;
  92. mObjectParams[name] = desc;
  93. mDataParams.erase(name);
  94. markCoreDirty();
  95. }
  96. GpuParamType Shader::getParamType(const String& name) const
  97. {
  98. auto findIterData = mDataParams.find(name);
  99. if(findIterData != mDataParams.end())
  100. return GPT_DATA;
  101. auto findIterObject = mObjectParams.find(name);
  102. if(findIterObject != mObjectParams.end())
  103. return GPT_OBJECT;
  104. BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
  105. }
  106. const SHADER_DATA_PARAM_DESC& Shader::getDataParamDesc(const String& name) const
  107. {
  108. auto findIterData = mDataParams.find(name);
  109. if(findIterData != mDataParams.end())
  110. return findIterData->second;
  111. BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
  112. }
  113. const SHADER_OBJECT_PARAM_DESC& Shader::getObjectParamDesc(const String& name) const
  114. {
  115. auto findIterObject = mObjectParams.find(name);
  116. if(findIterObject != mObjectParams.end())
  117. return findIterObject->second;
  118. BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
  119. }
  120. bool Shader::hasDataParam(const String& name) const
  121. {
  122. auto findIterData = mDataParams.find(name);
  123. if(findIterData != mDataParams.end())
  124. return true;
  125. return false;
  126. }
  127. bool Shader::hasObjectParam(const String& name) const
  128. {
  129. auto findIterObject = mObjectParams.find(name);
  130. if(findIterObject != mObjectParams.end())
  131. return true;
  132. return false;
  133. }
  134. void Shader::removeParameter(const String& name)
  135. {
  136. mDataParams.erase(name);
  137. mObjectParams.erase(name);
  138. }
  139. void Shader::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, UINT32 rendererSemantic)
  140. {
  141. SHADER_PARAM_BLOCK_DESC desc;
  142. desc.name = name;
  143. desc.shared = shared;
  144. desc.usage = usage;
  145. desc.rendererSemantic = rendererSemantic;
  146. mParamBlocks[name] = desc;
  147. markCoreDirty();
  148. }
  149. bool Shader::isSampler(GpuParamObjectType type)
  150. {
  151. switch(type)
  152. {
  153. case GPOT_SAMPLER1D:
  154. case GPOT_SAMPLER2D:
  155. case GPOT_SAMPLER3D:
  156. case GPOT_SAMPLERCUBE:
  157. return true;
  158. }
  159. return false;
  160. }
  161. bool Shader::isTexture(GpuParamObjectType type)
  162. {
  163. switch(type)
  164. {
  165. case GPOT_TEXTURE1D:
  166. case GPOT_TEXTURE2D:
  167. case GPOT_TEXTURE3D:
  168. case GPOT_TEXTURECUBE:
  169. case GPOT_RWTEXTURE1D:
  170. case GPOT_RWTEXTURE2D:
  171. case GPOT_RWTEXTURE3D:
  172. return true;
  173. }
  174. return false;
  175. }
  176. bool Shader::isBuffer(GpuParamObjectType type)
  177. {
  178. switch(type)
  179. {
  180. case GPOT_BYTE_BUFFER:
  181. case GPOT_STRUCTURED_BUFFER:
  182. case GPOT_RWBYTE_BUFFER:
  183. case GPOT_RWAPPEND_BUFFER:
  184. case GPOT_RWCONSUME_BUFFER:
  185. case GPOT_RWSTRUCTURED_BUFFER:
  186. case GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER:
  187. case GPOT_RWTYPED_BUFFER:
  188. return true;
  189. }
  190. return false;
  191. }
  192. ShaderPtr Shader::create(const String& name)
  193. {
  194. ShaderPtr newShader = bs_core_ptr<Shader, PoolAlloc>(new (bs_alloc<Shader, PoolAlloc>()) Shader(name));
  195. newShader->_setThisPtr(newShader);
  196. newShader->initialize();
  197. return newShader;
  198. }
  199. ShaderProxyPtr Shader::_createProxy()
  200. {
  201. ShaderProxyPtr proxy = bs_shared_ptr<ShaderProxy>();
  202. proxy->dataParams = mDataParams;
  203. proxy->objectParams = mObjectParams;
  204. proxy->paramBlocks = mParamBlocks;
  205. proxy->queuePriority = mQueuePriority;
  206. proxy->queueSortType = mQueueSortType;
  207. proxy->separablePasses = mSeparablePasses;
  208. return proxy;
  209. }
  210. RTTITypeBase* Shader::getRTTIStatic()
  211. {
  212. return ShaderRTTI::instance();
  213. }
  214. RTTITypeBase* Shader::getRTTI() const
  215. {
  216. return Shader::getRTTIStatic();
  217. }
  218. }