BsGLSLProgramPipelineManager.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "BsGLSLProgramPipelineManager.h"
  2. #include "BsGLSLGpuProgram.h"
  3. #include "BsRenderStats.h"
  4. namespace BansheeEngine
  5. {
  6. template <class T>
  7. inline void hash_combine(std::size_t& seed, const T& v)
  8. {
  9. std::hash<T> hasher;
  10. seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
  11. }
  12. ::std::size_t GLSLProgramPipelineManager::ProgramPipelineKeyHashFunction::operator()
  13. (const GLSLProgramPipelineManager::ProgramPipelineKey &key) const
  14. {
  15. std::size_t seed = 0;
  16. hash_combine(seed, key.vertexProgKey);
  17. hash_combine(seed, key.fragmentProgKey);
  18. hash_combine(seed, key.geometryProgKey);
  19. hash_combine(seed, key.hullProgKey);
  20. hash_combine(seed, key.domainProgKey);
  21. return seed;
  22. }
  23. bool GLSLProgramPipelineManager::ProgramPipelineKeyEqual::operator()
  24. (const GLSLProgramPipelineManager::ProgramPipelineKey &a, const GLSLProgramPipelineManager::ProgramPipelineKey &b) const
  25. {
  26. return a.vertexProgKey == b.vertexProgKey && a.fragmentProgKey == b.fragmentProgKey && a.geometryProgKey == b.geometryProgKey &&
  27. a.hullProgKey == b.hullProgKey && a.domainProgKey == b.domainProgKey;
  28. }
  29. GLSLProgramPipelineManager::~GLSLProgramPipelineManager()
  30. {
  31. for (auto& pipeline : mPipelines)
  32. {
  33. glDeleteProgramPipelines(1, &pipeline.second.glHandle);
  34. BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_PipelineObject);
  35. }
  36. }
  37. const GLSLProgramPipeline* GLSLProgramPipelineManager::getPipeline(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* fragmentProgram,
  38. GLSLGpuProgram* geometryProgram, GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram)
  39. {
  40. ProgramPipelineKey key;
  41. key.vertexProgKey = vertexProgram != nullptr ? vertexProgram->getProgramID() : 0;
  42. key.fragmentProgKey = fragmentProgram != nullptr ? fragmentProgram->getProgramID() : 0;
  43. key.geometryProgKey = geometryProgram != nullptr ? geometryProgram->getProgramID() : 0;
  44. key.hullProgKey = hullProgram != nullptr ? hullProgram->getProgramID() : 0;
  45. key.domainProgKey = domainProgram != nullptr ? domainProgram->getProgramID() : 0;
  46. auto iterFind = mPipelines.find(key);
  47. if(iterFind == mPipelines.end())
  48. {
  49. GLSLProgramPipeline newPipeline;
  50. glGenProgramPipelines(1, &newPipeline.glHandle);
  51. if(vertexProgram != nullptr)
  52. {
  53. glUseProgramStages(newPipeline.glHandle, GL_VERTEX_SHADER_BIT, vertexProgram->getGLHandle());
  54. }
  55. if(fragmentProgram != nullptr)
  56. {
  57. glUseProgramStages(newPipeline.glHandle, GL_FRAGMENT_SHADER_BIT, fragmentProgram->getGLHandle());
  58. }
  59. if(geometryProgram != nullptr)
  60. {
  61. glUseProgramStages(newPipeline.glHandle, GL_GEOMETRY_SHADER_BIT, geometryProgram->getGLHandle());
  62. }
  63. if(hullProgram != nullptr)
  64. {
  65. glUseProgramStages(newPipeline.glHandle, GL_TESS_CONTROL_SHADER_BIT, hullProgram->getGLHandle());
  66. }
  67. if(domainProgram != nullptr)
  68. {
  69. glUseProgramStages(newPipeline.glHandle, GL_TESS_EVALUATION_SHADER_BIT, domainProgram->getGLHandle());
  70. }
  71. mPipelines[key] = newPipeline;
  72. BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_PipelineObject);
  73. return &mPipelines[key];
  74. }
  75. else
  76. return &iterFind->second;
  77. }
  78. }