SHARE
TWEET

Untitled

a guest Jul 22nd, 2019 86 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "gpu_program_opengl.h"
  2.  
  3. namespace eq {
  4.  
  5. namespace render {
  6.  
  7. namespace gl {
  8.  
  9. GPUProgramOpenGL::GPUProgramOpenGL(std::shared_ptr<const GLContext> gl_context,
  10.     std::shared_ptr<const GLContext> gl_context_aux,
  11.     std::shared_ptr<Synchronized<resource::ResourceManager<GLShaderGLSL>>> gl_shader_glsl_manager) :
  12.     m_gl_context(gl_context), m_gl_context_aux(gl_context_aux),
  13.     m_gl_shader_glsl_manager(gl_shader_glsl_manager) {
  14.    
  15.     std::unique_lock contextLock(*m_gl_context_aux, std::defer_lock);
  16.     if (m_gl_context->GetHandle() != GLContext::GetCurrent())
  17.         contextLock.lock();
  18.  
  19.     const_cast<std::unique_ptr<const GLProgram>&>(m_gl_program) = std::make_unique<GLProgram>();
  20. }
  21.  
  22. GPUProgramOpenGL::~GPUProgramOpenGL() {
  23.  
  24.     std::unique_lock contextLock(*m_gl_context_aux, std::defer_lock);
  25.     if (m_gl_context->GetHandle() != GLContext::GetCurrent())
  26.         contextLock.lock();
  27.  
  28.     const_cast<std::unique_ptr<const GLProgram>&>(m_gl_program).reset();
  29. }
  30.  
  31. void GPUProgramOpenGL::SetUniformData(const UniformData& uniform_data)  {
  32.  
  33.     GLint current_program = 0;
  34.     GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, &current_program))
  35.     if (m_gl_program->GetProgram() != current_program)
  36.         GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
  37.  
  38.     SetUniform(uniform_data.uniform, (void*)uniform_data.data.data());
  39. }
  40.  
  41. void GPUProgramOpenGL::SetUniformData(const std::vector<UniformData>& uniform_data_vector)  {
  42.  
  43.     GLint current_program = 0;
  44.     GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, &current_program))
  45.     if (m_gl_program->GetProgram() != current_program)
  46.         GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
  47.  
  48.     for (const auto& uniform_data : uniform_data_vector)
  49.         SetUniform(uniform_data.uniform, (void*)uniform_data.data.data());
  50. }
  51.  
  52. void GPUProgramOpenGL::SetUniformData(const UniformDataView& uniform_data_view) {
  53.  
  54.     GLint current_program = 0;
  55.     GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, &current_program))
  56.     if (m_gl_program->GetProgram() != current_program)
  57.         GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
  58.  
  59.     SetUniform(uniform_data_view.uniform, uniform_data_view.data);
  60. }
  61.  
  62. void GPUProgramOpenGL::SetUniformData(const std::vector<UniformDataView>& uniform_data_view_vector) {
  63.  
  64.     GLint current_program = 0;
  65.     GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, &current_program))
  66.     if (m_gl_program->GetProgram() != current_program)
  67.         GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
  68.  
  69.     for (const auto& uniform_data_view : uniform_data_view_vector)
  70.         SetUniform(uniform_data_view.uniform, uniform_data_view.data);
  71. }
  72.  
  73. void GPUProgramOpenGL::SetUniformBuffer(const std::shared_ptr<UniformBuffer> uniform_buffer, size_t offset, size_t size) {
  74.  
  75.     GLint current_program = 0;
  76.     GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, &current_program))
  77.     if (m_gl_program->GetProgram() != current_program)
  78.         GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
  79.  
  80.     GLuint binding = 0;
  81.  
  82.     for (auto& uniform_block : m_uniform_block_map) {
  83.         if (uniform_block.second.name == uniform_buffer->GetUniformBlock().name) {
  84.             auto visitor = std::make_unique<MemoryBufferVisitorSetActive>(m_gl_context.get(), GL_UNIFORM_BUFFER, binding, 0, size ? size : uniform_buffer->GetMemoryBuffer()->GetSize());
  85.             uniform_buffer->GetMemoryBuffer()->Accept(visitor.get());
  86.             GL_ASSERT(glUniformBlockBinding(m_gl_program->GetProgram(), uniform_block.second.id, binding))
  87.         }
  88.         binding++;
  89.     }
  90. }
  91.  
  92. void GPUProgramOpenGL::SetUniformBuffer(const std::vector<std::shared_ptr<UniformBuffer>>& uniformBufferVector) {
  93.     for (auto& uniformBuffer : uniformBufferVector)
  94.         SetUniformBuffer(uniformBuffer);
  95. }
  96.  
  97. void GPUProgramOpenGL::SetUniformData(const UniformGroup& uniformGroup) {
  98.     SetUniformData(uniformGroup.uniform_data_vector);
  99.     SetUniformData(uniformGroup.uniform_data_view_vector);
  100.     SetUniformBuffer(uniformGroup.uniform_buffer_vector);
  101. }
  102.  
  103. void GPUProgramOpenGL::Load(const resource::ResourceName& resource_name) {
  104.  
  105.     GPUProgram::Load(resource_name);
  106.  
  107.     auto istream = SingletonFilesystem::GetInstance()->Get().MakeUniqueIstream(resource_name.filename);
  108.  
  109.     std::istreambuf_iterator<char> eos;
  110.     std::string xml_text(std::istreambuf_iterator<char>(*istream), eos);
  111.  
  112.     rapidxml::xml_document<> xml_doc;
  113.     xml_doc.parse<0>(const_cast<char*>(xml_text.c_str()));
  114.  
  115.     auto xml_root_node = xml_doc.first_node();
  116.  
  117.     std::map<GLenum, std::vector<std::string>> shader_names_map;
  118.  
  119.     std::string_view xml_root_node_name(xml_root_node->name());
  120.  
  121.     if (xml_root_node_name == "GPUProgram") {
  122.  
  123.         auto xml_program_node = xml_root_node->first_node("Program");
  124.         if (xml_program_node) {
  125.  
  126.             auto xml_opengl_node = xml_program_node->first_node("OpenGL");
  127.             if (xml_opengl_node) {
  128.  
  129.                 auto xml_glsl_node = xml_opengl_node->first_node("GLSL");
  130.                 if (xml_glsl_node) {
  131.  
  132.                     for (auto xml_glsl_child_node = xml_glsl_node->first_node(); xml_glsl_child_node; xml_glsl_child_node = xml_glsl_child_node->next_sibling()) {
  133.  
  134.                         std::string_view xml_glsl_child_node_name(xml_glsl_child_node->name());
  135.  
  136.                         if (xml_glsl_child_node_name == "VertexShader") {
  137.                             auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
  138.                             if (xml_name_attribute)
  139.                                 shader_names_map[GL_VERTEX_SHADER].push_back(xml_name_attribute->value());
  140.                         }
  141.                         else if (xml_glsl_child_node_name == "FragmentShader") {
  142.                             auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
  143.                             if (xml_name_attribute)
  144.                                 shader_names_map[GL_FRAGMENT_SHADER].push_back(xml_name_attribute->value());
  145.                         }
  146.                         else if (xml_glsl_child_node_name == "GeometryShader") {
  147.                             auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
  148.                             if (xml_name_attribute)
  149.                                 shader_names_map[GL_GEOMETRY_SHADER].push_back(xml_name_attribute->value());
  150.                         }
  151.                         else if (xml_glsl_child_node_name == "TesselationControlShader") {
  152.                             auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
  153.                             if (xml_name_attribute)
  154.                                 shader_names_map[GL_TESS_CONTROL_SHADER].push_back(xml_name_attribute->value());
  155.                         }
  156.                         else if (xml_glsl_child_node_name == "TesselationEvaluationShader") {
  157.                             auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
  158.                             if (xml_name_attribute)
  159.                                 shader_names_map[GL_TESS_EVALUATION_SHADER].push_back(xml_name_attribute->value());
  160.                         }
  161.                     }
  162.                 }
  163.             }
  164.         }
  165.     }
  166.  
  167.     auto gl_shader_glsl_manager = m_gl_shader_glsl_manager.lock();
  168.  
  169.     if (gl_shader_glsl_manager) {
  170.  
  171.         for (const auto& shader_names : shader_names_map) {
  172.             for (const auto& shader_name : shader_names.second) {
  173.  
  174.                 resource::ResourceFuture<GLShaderGLSL> gl_shader_resource;
  175.  
  176.                 {
  177.                     std::lock_guard<typename std::decay<decltype(gl_shader_glsl_manager->GetLockable())>::type> manager_lock(gl_shader_glsl_manager->GetLockable());
  178.                     gl_shader_resource = gl_shader_glsl_manager->Get().GetResource({
  179.                         std::wstring(std::begin(shader_name), std::end(shader_name)) },
  180.                         std::make_tuple(m_gl_context, m_gl_context_aux, shader_names.first));
  181.                 }
  182.  
  183.                 std::unique_lock context_lock(*m_gl_context_aux, std::defer_lock);
  184.                 if (m_gl_context->GetHandle() != GLContext::GetCurrent())
  185.                     context_lock.lock();
  186.  
  187.                 m_gl_program->AttachShader(gl_shader_resource.get()->GetShader());
  188.             }
  189.         }
  190.  
  191.         std::unique_lock context_lock(*m_gl_context_aux, std::defer_lock);
  192.         if (m_gl_context->GetHandle() != GLContext::GetCurrent())
  193.             context_lock.lock();
  194.  
  195.         std::string link_log;
  196.         auto linkResult = m_gl_program->Link(link_log);
  197.  
  198.         for (auto attribute : m_vertex_attributes_layout_in.attributes) {
  199.             if (attribute.first.id == -1) {
  200.                 GL_ASSERT(attribute.first.id = glGetAttribLocation(m_gl_program->GetProgram(), attribute.first.name.c_str()))
  201.             }
  202.         }
  203.  
  204.         std::sort(m_vertex_attributes_layout_in.attributes.begin(), m_vertex_attributes_layout_in.attributes.end(),
  205.             [](const std::pair<VertexAttribute, size_t>& a1, const std::pair<VertexAttribute, size_t>& a2) { return a1.first.id < a2.first.id; });
  206.  
  207.         for (auto& uniform : m_uniform_map) {
  208.             if (uniform.second.id == -1) {
  209.                 GL_ASSERT(uniform.second.id = glGetUniformLocation(m_gl_program->GetProgram(), uniform.second.name.c_str()))
  210.                 if (uniform.second.id == -1) {
  211.                     auto logger = SingletonLogger::GetInstance();
  212.                     std::lock_guard<typename std::decay<decltype(logger->GetLockable())>::type> logger_lock(logger->GetLockable());
  213.                     logger->Get().LogMessage({ LoggerMessageType::WARNING, L"Uniform variable [" + std::wstring(std::begin(uniform.second.name),std::end(uniform.second.name)) + L"] was not found in " + resource_name.filename + L" GLSL Program" });
  214.                 }
  215.                 /*
  216.                 else {
  217.                     GLsizei length = 0; GLint size = 0; GLenum type = 0;
  218.                     GLchar name[256];
  219.                     glGetActiveUniform(m_glProgram->GetProgram(), uniform.id, 256, &length, &size, &type, name);
  220.                 }
  221.                 */
  222.             }
  223.         }
  224.  
  225.         for (auto& uniform_block : m_uniform_block_map) {
  226.  
  227.             if (uniform_block.second.id == -1)
  228.                 GL_ASSERT(uniform_block.second.id = glGetUniformBlockIndex(m_gl_program->GetProgram(), uniform_block.second.name.c_str()))
  229.  
  230.             if (uniform_block.second.id == -1) {
  231.                 auto logger = SingletonLogger::GetInstance();
  232.                 std::lock_guard<typename std::decay<decltype(logger->GetLockable())>::type> logger_lock(logger->GetLockable());
  233.                 logger->Get().LogMessage({ LoggerMessageType::WARNING, L"UniformBlock variable [" + std::wstring(std::begin(uniform_block.second.name),std::end(uniform_block.second.name)) + L"] was not found in " + resource_name.filename + L" GLSL Program" });
  234.             }
  235.  
  236.             else {
  237.                 GLint size;
  238.                 GL_ASSERT(glGetActiveUniformBlockiv(m_gl_program->GetProgram(), uniform_block.second.id, GL_UNIFORM_BLOCK_DATA_SIZE, &size))
  239.                 uniform_block.second.size = size;
  240.  
  241.                 for (auto& uniform : uniform_block.second.uniform_map) {
  242.                     GLuint index;
  243.                     std::string name = uniform_block.second.name + "." + uniform.second.first.name;
  244.                     auto np = name.c_str();
  245.                     GL_ASSERT(glGetUniformIndices(m_gl_program->GetProgram(), 1, &np, &index))
  246.  
  247.                     uniform.second.first.id = index;
  248.                     GLint offset;
  249.                     GL_ASSERT(glGetActiveUniformsiv(m_gl_program->GetProgram(), 1, &index, GL_UNIFORM_OFFSET, &offset))
  250.                     uniform.second.second = offset;
  251.                 }          
  252.             }
  253.         }
  254.  
  255.         auto logger = SingletonLogger::GetInstance();
  256.         std::lock_guard<typename std::decay<decltype(logger->GetLockable())>::type> logger_lock(logger->GetLockable());
  257.  
  258.         if (linkResult)
  259.             logger->Get().LogMessage({ LoggerMessageType::INFORMATION, L"GLSL Program " + resource_name.filename + L" linked successfully." });
  260.         else
  261.             logger->Get().LogMessage({ LoggerMessageType::WARNING, L"GLSL Program " + resource_name.filename + L" failed to link. Linking error : \n" + std::wstring(std::begin(link_log), std::end(link_log)) });
  262.     }
  263. }
  264.  
  265. std::shared_ptr<const GLContext> GPUProgramOpenGL::GetGLContext() const {
  266.  
  267.     return m_gl_context;
  268. }
  269.  
  270. const GLProgram* GPUProgramOpenGL::GetGLProgram() const {
  271.  
  272.     return m_gl_program.get();
  273. }
  274.  
  275. void GPUProgramOpenGL::SetUniform(const Uniform& uniform, void* data) {
  276.  
  277.     GLint location = uniform.id;
  278.     if (uniform.id == -1)
  279.         GL_ASSERT(location = glGetUniformLocation(m_gl_program->GetProgram(), uniform.name.c_str()))
  280.  
  281.     if (location != -1) {
  282.  
  283.         switch (uniform.type) {
  284.  
  285.         case UniformType::INT32:
  286.             GL_ASSERT(glUniform1iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
  287.             break;
  288.         case UniformType::FLOAT:
  289.             GL_ASSERT(glUniform1fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
  290.             break;
  291.         case UniformType::VEC2INT32:
  292.             GL_ASSERT(glUniform2iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
  293.             break;
  294.         case UniformType::VEC2FLOAT:
  295.             GL_ASSERT(glUniform2fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
  296.             break;
  297.         case UniformType::VEC3INT32:
  298.             GL_ASSERT(glUniform3iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
  299.             break;
  300.         case UniformType::VEC3FLOAT:
  301.             GL_ASSERT(glUniform3fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
  302.             break;
  303.         case UniformType::VEC4INT32:
  304.             GL_ASSERT(glUniform4iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
  305.             break;
  306.         case UniformType::VEC4FLOAT:
  307.             GL_ASSERT(glUniform4fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
  308.             break;
  309.         case UniformType::MAT3:
  310.             GL_ASSERT(glUniformMatrix3fv(location, (GLsizei)uniform.count, GL_FALSE, reinterpret_cast<const GLfloat*>(data)))
  311.             break;
  312.         case UniformType::MAT4:
  313.             GL_ASSERT(glUniformMatrix4fv(location, (GLsizei)uniform.count, GL_FALSE, reinterpret_cast<const GLfloat*>(data)))
  314.             break;
  315.         }
  316.     }
  317. }
  318.  
  319. void GPUProgramOpenGL::MemoryBufferVisitorSetActive::Visit(MemoryBuffer* memory_buffer) {
  320.  
  321.  
  322. }
  323.  
  324. void GPUProgramOpenGL::MemoryBufferVisitorSetActive::Visit(sr::MemoryBufferSoftware* memory_buffer) {
  325.  
  326. }
  327.  
  328. void GPUProgramOpenGL::MemoryBufferVisitorSetActive::Visit(MemoryBufferOpenGL* memory_buffer) {
  329.     if (memory_buffer->GetGLContext().get() == m_gl_context) {
  330.  
  331.         GLenum pname;
  332.  
  333.         switch (m_target) {
  334.         case GL_UNIFORM_BUFFER:
  335.             pname = GL_UNIFORM_BUFFER_BINDING;
  336.             break;
  337.         default:
  338.             assert(false);
  339.         }
  340.  
  341.         GLuint buffer;
  342.         GL_ASSERT(glGetIntegeri_v(pname, m_index, (GLint*)&buffer))
  343.  
  344.         if (buffer != memory_buffer->GetGLBuffer()->GetBuffer())
  345.             //GL_ASSERT(glBindBufferBase(m_target, m_index, memoryBuffer->GetGLBuffer()->GetBuffer()));
  346.             GL_ASSERT(glBindBufferRange(m_target, m_index, memory_buffer->GetGLBuffer()->GetBuffer(), m_offset, m_size))
  347.     }
  348. }
  349.  
  350. } // namespace gl
  351.  
  352. } // namespace render
  353.  
  354. } // namespace eq
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top