2
0

CmGLSLProgramPipelineManager.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "CmGLSLProgramPipelineManager.h"
  2. #include "CmGLSLGpuProgram.h"
  3. #include "CmGLSLProgram.h"
  4. namespace CamelotEngine
  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. const GLSLProgramPipeline* GLSLProgramPipelineManager::getPipeline(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* fragmentProgram,
  30. GLSLGpuProgram* geometryProgram, GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram)
  31. {
  32. ProgramPipelineKey key;
  33. key.vertexProgKey = vertexProgram != nullptr ? vertexProgram->getProgramID() : 0;
  34. key.fragmentProgKey = fragmentProgram != nullptr ? fragmentProgram->getProgramID() : 0;
  35. key.geometryProgKey = geometryProgram != nullptr ? geometryProgram->getProgramID() : 0;
  36. key.hullProgKey = hullProgram != nullptr ? hullProgram->getProgramID() : 0;
  37. key.domainProgKey = domainProgram != nullptr ? domainProgram->getProgramID() : 0;
  38. auto iterFind = mPipelines.find(key);
  39. if(iterFind == mPipelines.end())
  40. {
  41. GLSLProgramPipeline newPipeline;
  42. glGenProgramPipelines(1, &newPipeline.glHandle);
  43. if(vertexProgram != nullptr)
  44. {
  45. glUseProgramStages(newPipeline.glHandle, GL_VERTEX_SHADER_BIT, vertexProgram->getGLSLProgram()->getGLHandle());
  46. }
  47. if(fragmentProgram != nullptr)
  48. {
  49. glUseProgramStages(newPipeline.glHandle, GL_FRAGMENT_SHADER_BIT, fragmentProgram->getGLSLProgram()->getGLHandle());
  50. }
  51. if(geometryProgram != nullptr)
  52. {
  53. glUseProgramStages(newPipeline.glHandle, GL_GEOMETRY_SHADER_BIT, geometryProgram->getGLSLProgram()->getGLHandle());
  54. }
  55. if(hullProgram != nullptr)
  56. {
  57. glUseProgramStages(newPipeline.glHandle, GL_TESS_CONTROL_SHADER_BIT, hullProgram->getGLSLProgram()->getGLHandle());
  58. }
  59. if(domainProgram != nullptr)
  60. {
  61. glUseProgramStages(newPipeline.glHandle, GL_TESS_EVALUATION_SHADER_BIT, domainProgram->getGLSLProgram()->getGLHandle());
  62. }
  63. mPipelines[key] = newPipeline;
  64. return &mPipelines[key];
  65. }
  66. else
  67. return &iterFind->second;
  68. }
  69. }