BsShader.cpp 5.8 KB

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