PipelineImpl.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "anki/gr/gl/PipelineImpl.h"
  6. #include "anki/gr/gl/ShaderImpl.h"
  7. #include "anki/util/Logger.h"
  8. namespace anki {
  9. //==============================================================================
  10. Error PipelineImpl::create(
  11. const ShaderHandle* progsBegin, const ShaderHandle* progsEnd,
  12. GlAllocator<U8> alloc)
  13. {
  14. ANKI_ASSERT(progsBegin != nullptr && progsEnd != nullptr);
  15. ANKI_ASSERT(progsBegin != progsEnd);
  16. Error err = ErrorCode::NONE;
  17. attachProgramsInternal(progsBegin, progsEnd - progsBegin);
  18. // Create and attach programs
  19. glGenProgramPipelines(1, &m_glName);
  20. ANKI_ASSERT(m_glName != 0);
  21. glBindProgramPipeline(m_glName);
  22. for(U i = 0; i < m_shaders.size(); i++)
  23. {
  24. ShaderHandle& prog = m_shaders[i];
  25. if(prog.isCreated())
  26. {
  27. GLbitfield bit;
  28. GLenum gltype =
  29. computeGlShaderType(static_cast<ShaderType>(i), &bit);
  30. ANKI_ASSERT(prog.getType() == gltype && "Attached wrong shader");
  31. (void)gltype;
  32. glUseProgramStages(m_glName, bit, prog._get().getGlName());
  33. }
  34. }
  35. // Validate and check error
  36. glValidateProgramPipeline(m_glName);
  37. GLint status = 0;
  38. glGetProgramPipelineiv(m_glName, GL_VALIDATE_STATUS, &status);
  39. if(!status)
  40. {
  41. GLint infoLen = 0;
  42. GLint charsWritten = 0;
  43. DArray<char> infoLogTxt;
  44. glGetProgramPipelineiv(m_glName, GL_INFO_LOG_LENGTH, &infoLen);
  45. err = infoLogTxt.create(alloc, infoLen + 1);
  46. if(!err)
  47. {
  48. glGetProgramPipelineInfoLog(
  49. m_glName, infoLen, &charsWritten, &infoLogTxt[0]);
  50. ANKI_LOGE("Ppline error log follows:\n%s", &infoLogTxt[0]);
  51. err = ErrorCode::USER_DATA;
  52. }
  53. }
  54. glBindProgramPipeline(0);
  55. return err;
  56. }
  57. //==============================================================================
  58. void PipelineImpl::destroy()
  59. {
  60. if(m_glName)
  61. {
  62. glDeleteProgramPipelines(1, &m_glName);
  63. m_glName = 0;
  64. }
  65. }
  66. //==============================================================================
  67. void PipelineImpl::attachProgramsInternal(
  68. const ShaderHandle* progs, PtrSize count)
  69. {
  70. U mask = 0;
  71. while(count-- != 0)
  72. {
  73. const ShaderHandle& prog = progs[count];
  74. ShaderType type = computeShaderTypeIndex(prog._get().getType());
  75. U idx = enumToType(type);
  76. ANKI_ASSERT(!m_shaders[idx].isCreated() && "Attaching the same");
  77. m_shaders[idx] = prog;
  78. mask |= 1 << idx;
  79. }
  80. // Check what we attached
  81. //
  82. if(mask & (1 << 5))
  83. {
  84. // Is compute
  85. ANKI_ASSERT((mask & (1 << 5)) == (1 << 5)
  86. && "Compute should be alone in the pipeline");
  87. }
  88. else
  89. {
  90. const U fragVert = (1 << 0) | (1 << 4);
  91. ANKI_ASSERT((mask & fragVert) && "Should contain vert and frag");
  92. (void)fragVert;
  93. const U tess = (1 << 1) | (1 << 2);
  94. if((mask & tess) != 0)
  95. {
  96. ANKI_ASSERT(((mask & tess) == 0x6)
  97. && "Should set both the tessellation shaders");
  98. }
  99. }
  100. }
  101. //==============================================================================
  102. void PipelineImpl::bind()
  103. {
  104. ANKI_ASSERT(isCreated());
  105. glBindProgramPipeline(m_glName);
  106. }
  107. //==============================================================================
  108. ShaderHandle PipelineImpl::getAttachedProgram(GLenum type) const
  109. {
  110. ANKI_ASSERT(isCreated());
  111. ShaderType stype = computeShaderTypeIndex(type);
  112. U idx = enumToType(stype);
  113. ShaderHandle prog = m_shaders[idx];
  114. ANKI_ASSERT(prog.isCreated() && "Asking for non-created program");
  115. return prog;
  116. }
  117. } // end namespace anki