Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "gpu_program_opengl.h"
- namespace eq {
- namespace render {
- namespace gl {
- GPUProgramOpenGL::GPUProgramOpenGL(std::shared_ptr<const GLContext> gl_context,
- std::shared_ptr<const GLContext> gl_context_aux,
- std::shared_ptr<Synchronized<resource::ResourceManager<GLShaderGLSL>>> gl_shader_glsl_manager) :
- m_gl_context(gl_context), m_gl_context_aux(gl_context_aux),
- m_gl_shader_glsl_manager(gl_shader_glsl_manager) {
- std::unique_lock contextLock(*m_gl_context_aux, std::defer_lock);
- if (m_gl_context->GetHandle() != GLContext::GetCurrent())
- contextLock.lock();
- const_cast<std::unique_ptr<const GLProgram>&>(m_gl_program) = std::make_unique<GLProgram>();
- }
- GPUProgramOpenGL::~GPUProgramOpenGL() {
- std::unique_lock contextLock(*m_gl_context_aux, std::defer_lock);
- if (m_gl_context->GetHandle() != GLContext::GetCurrent())
- contextLock.lock();
- const_cast<std::unique_ptr<const GLProgram>&>(m_gl_program).reset();
- }
- void GPUProgramOpenGL::SetUniformData(const UniformData& uniform_data) {
- GLint current_program = 0;
- GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program))
- if (m_gl_program->GetProgram() != current_program)
- GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
- SetUniform(uniform_data.uniform, (void*)uniform_data.data.data());
- }
- void GPUProgramOpenGL::SetUniformData(const std::vector<UniformData>& uniform_data_vector) {
- GLint current_program = 0;
- GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program))
- if (m_gl_program->GetProgram() != current_program)
- GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
- for (const auto& uniform_data : uniform_data_vector)
- SetUniform(uniform_data.uniform, (void*)uniform_data.data.data());
- }
- void GPUProgramOpenGL::SetUniformData(const UniformDataView& uniform_data_view) {
- GLint current_program = 0;
- GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program))
- if (m_gl_program->GetProgram() != current_program)
- GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
- SetUniform(uniform_data_view.uniform, uniform_data_view.data);
- }
- void GPUProgramOpenGL::SetUniformData(const std::vector<UniformDataView>& uniform_data_view_vector) {
- GLint current_program = 0;
- GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program))
- if (m_gl_program->GetProgram() != current_program)
- GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
- for (const auto& uniform_data_view : uniform_data_view_vector)
- SetUniform(uniform_data_view.uniform, uniform_data_view.data);
- }
- void GPUProgramOpenGL::SetUniformBuffer(const std::shared_ptr<UniformBuffer> uniform_buffer, size_t offset, size_t size) {
- GLint current_program = 0;
- GL_ASSERT(glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program))
- if (m_gl_program->GetProgram() != current_program)
- GL_ASSERT(glUseProgram(m_gl_program->GetProgram()))
- GLuint binding = 0;
- for (auto& uniform_block : m_uniform_block_map) {
- if (uniform_block.second.name == uniform_buffer->GetUniformBlock().name) {
- auto visitor = std::make_unique<MemoryBufferVisitorSetActive>(m_gl_context.get(), GL_UNIFORM_BUFFER, binding, 0, size ? size : uniform_buffer->GetMemoryBuffer()->GetSize());
- uniform_buffer->GetMemoryBuffer()->Accept(visitor.get());
- GL_ASSERT(glUniformBlockBinding(m_gl_program->GetProgram(), uniform_block.second.id, binding))
- }
- binding++;
- }
- }
- void GPUProgramOpenGL::SetUniformBuffer(const std::vector<std::shared_ptr<UniformBuffer>>& uniformBufferVector) {
- for (auto& uniformBuffer : uniformBufferVector)
- SetUniformBuffer(uniformBuffer);
- }
- void GPUProgramOpenGL::SetUniformData(const UniformGroup& uniformGroup) {
- SetUniformData(uniformGroup.uniform_data_vector);
- SetUniformData(uniformGroup.uniform_data_view_vector);
- SetUniformBuffer(uniformGroup.uniform_buffer_vector);
- }
- void GPUProgramOpenGL::Load(const resource::ResourceName& resource_name) {
- GPUProgram::Load(resource_name);
- auto istream = SingletonFilesystem::GetInstance()->Get().MakeUniqueIstream(resource_name.filename);
- std::istreambuf_iterator<char> eos;
- std::string xml_text(std::istreambuf_iterator<char>(*istream), eos);
- rapidxml::xml_document<> xml_doc;
- xml_doc.parse<0>(const_cast<char*>(xml_text.c_str()));
- auto xml_root_node = xml_doc.first_node();
- std::map<GLenum, std::vector<std::string>> shader_names_map;
- std::string_view xml_root_node_name(xml_root_node->name());
- if (xml_root_node_name == "GPUProgram") {
- auto xml_program_node = xml_root_node->first_node("Program");
- if (xml_program_node) {
- auto xml_opengl_node = xml_program_node->first_node("OpenGL");
- if (xml_opengl_node) {
- auto xml_glsl_node = xml_opengl_node->first_node("GLSL");
- if (xml_glsl_node) {
- 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()) {
- std::string_view xml_glsl_child_node_name(xml_glsl_child_node->name());
- if (xml_glsl_child_node_name == "VertexShader") {
- auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
- if (xml_name_attribute)
- shader_names_map[GL_VERTEX_SHADER].push_back(xml_name_attribute->value());
- }
- else if (xml_glsl_child_node_name == "FragmentShader") {
- auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
- if (xml_name_attribute)
- shader_names_map[GL_FRAGMENT_SHADER].push_back(xml_name_attribute->value());
- }
- else if (xml_glsl_child_node_name == "GeometryShader") {
- auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
- if (xml_name_attribute)
- shader_names_map[GL_GEOMETRY_SHADER].push_back(xml_name_attribute->value());
- }
- else if (xml_glsl_child_node_name == "TesselationControlShader") {
- auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
- if (xml_name_attribute)
- shader_names_map[GL_TESS_CONTROL_SHADER].push_back(xml_name_attribute->value());
- }
- else if (xml_glsl_child_node_name == "TesselationEvaluationShader") {
- auto xml_name_attribute = xml_glsl_child_node->first_attribute("name");
- if (xml_name_attribute)
- shader_names_map[GL_TESS_EVALUATION_SHADER].push_back(xml_name_attribute->value());
- }
- }
- }
- }
- }
- }
- auto gl_shader_glsl_manager = m_gl_shader_glsl_manager.lock();
- if (gl_shader_glsl_manager) {
- for (const auto& shader_names : shader_names_map) {
- for (const auto& shader_name : shader_names.second) {
- resource::ResourceFuture<GLShaderGLSL> gl_shader_resource;
- {
- std::lock_guard<typename std::decay<decltype(gl_shader_glsl_manager->GetLockable())>::type> manager_lock(gl_shader_glsl_manager->GetLockable());
- gl_shader_resource = gl_shader_glsl_manager->Get().GetResource({
- std::wstring(std::begin(shader_name), std::end(shader_name)) },
- std::make_tuple(m_gl_context, m_gl_context_aux, shader_names.first));
- }
- std::unique_lock context_lock(*m_gl_context_aux, std::defer_lock);
- if (m_gl_context->GetHandle() != GLContext::GetCurrent())
- context_lock.lock();
- m_gl_program->AttachShader(gl_shader_resource.get()->GetShader());
- }
- }
- std::unique_lock context_lock(*m_gl_context_aux, std::defer_lock);
- if (m_gl_context->GetHandle() != GLContext::GetCurrent())
- context_lock.lock();
- std::string link_log;
- auto linkResult = m_gl_program->Link(link_log);
- for (auto attribute : m_vertex_attributes_layout_in.attributes) {
- if (attribute.first.id == -1) {
- GL_ASSERT(attribute.first.id = glGetAttribLocation(m_gl_program->GetProgram(), attribute.first.name.c_str()))
- }
- }
- std::sort(m_vertex_attributes_layout_in.attributes.begin(), m_vertex_attributes_layout_in.attributes.end(),
- [](const std::pair<VertexAttribute, size_t>& a1, const std::pair<VertexAttribute, size_t>& a2) { return a1.first.id < a2.first.id; });
- for (auto& uniform : m_uniform_map) {
- if (uniform.second.id == -1) {
- GL_ASSERT(uniform.second.id = glGetUniformLocation(m_gl_program->GetProgram(), uniform.second.name.c_str()))
- if (uniform.second.id == -1) {
- auto logger = SingletonLogger::GetInstance();
- std::lock_guard<typename std::decay<decltype(logger->GetLockable())>::type> logger_lock(logger->GetLockable());
- 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" });
- }
- /*
- else {
- GLsizei length = 0; GLint size = 0; GLenum type = 0;
- GLchar name[256];
- glGetActiveUniform(m_glProgram->GetProgram(), uniform.id, 256, &length, &size, &type, name);
- }
- */
- }
- }
- for (auto& uniform_block : m_uniform_block_map) {
- if (uniform_block.second.id == -1)
- GL_ASSERT(uniform_block.second.id = glGetUniformBlockIndex(m_gl_program->GetProgram(), uniform_block.second.name.c_str()))
- if (uniform_block.second.id == -1) {
- auto logger = SingletonLogger::GetInstance();
- std::lock_guard<typename std::decay<decltype(logger->GetLockable())>::type> logger_lock(logger->GetLockable());
- 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" });
- }
- else {
- GLint size;
- GL_ASSERT(glGetActiveUniformBlockiv(m_gl_program->GetProgram(), uniform_block.second.id, GL_UNIFORM_BLOCK_DATA_SIZE, &size))
- uniform_block.second.size = size;
- for (auto& uniform : uniform_block.second.uniform_map) {
- GLuint index;
- std::string name = uniform_block.second.name + "." + uniform.second.first.name;
- auto np = name.c_str();
- GL_ASSERT(glGetUniformIndices(m_gl_program->GetProgram(), 1, &np, &index))
- uniform.second.first.id = index;
- GLint offset;
- GL_ASSERT(glGetActiveUniformsiv(m_gl_program->GetProgram(), 1, &index, GL_UNIFORM_OFFSET, &offset))
- uniform.second.second = offset;
- }
- }
- }
- auto logger = SingletonLogger::GetInstance();
- std::lock_guard<typename std::decay<decltype(logger->GetLockable())>::type> logger_lock(logger->GetLockable());
- if (linkResult)
- logger->Get().LogMessage({ LoggerMessageType::INFORMATION, L"GLSL Program " + resource_name.filename + L" linked successfully." });
- else
- 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)) });
- }
- }
- std::shared_ptr<const GLContext> GPUProgramOpenGL::GetGLContext() const {
- return m_gl_context;
- }
- const GLProgram* GPUProgramOpenGL::GetGLProgram() const {
- return m_gl_program.get();
- }
- void GPUProgramOpenGL::SetUniform(const Uniform& uniform, void* data) {
- GLint location = uniform.id;
- if (uniform.id == -1)
- GL_ASSERT(location = glGetUniformLocation(m_gl_program->GetProgram(), uniform.name.c_str()))
- if (location != -1) {
- switch (uniform.type) {
- case UniformType::INT32:
- GL_ASSERT(glUniform1iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
- break;
- case UniformType::FLOAT:
- GL_ASSERT(glUniform1fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
- break;
- case UniformType::VEC2INT32:
- GL_ASSERT(glUniform2iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
- break;
- case UniformType::VEC2FLOAT:
- GL_ASSERT(glUniform2fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
- break;
- case UniformType::VEC3INT32:
- GL_ASSERT(glUniform3iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
- break;
- case UniformType::VEC3FLOAT:
- GL_ASSERT(glUniform3fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
- break;
- case UniformType::VEC4INT32:
- GL_ASSERT(glUniform4iv(location, (GLsizei)uniform.count, reinterpret_cast<const GLint*>(data)))
- break;
- case UniformType::VEC4FLOAT:
- GL_ASSERT(glUniform4fv(location, (GLsizei)uniform.count, reinterpret_cast<const GLfloat*>(data)))
- break;
- case UniformType::MAT3:
- GL_ASSERT(glUniformMatrix3fv(location, (GLsizei)uniform.count, GL_FALSE, reinterpret_cast<const GLfloat*>(data)))
- break;
- case UniformType::MAT4:
- GL_ASSERT(glUniformMatrix4fv(location, (GLsizei)uniform.count, GL_FALSE, reinterpret_cast<const GLfloat*>(data)))
- break;
- }
- }
- }
- void GPUProgramOpenGL::MemoryBufferVisitorSetActive::Visit(MemoryBuffer* memory_buffer) {
- }
- void GPUProgramOpenGL::MemoryBufferVisitorSetActive::Visit(sr::MemoryBufferSoftware* memory_buffer) {
- }
- void GPUProgramOpenGL::MemoryBufferVisitorSetActive::Visit(MemoryBufferOpenGL* memory_buffer) {
- if (memory_buffer->GetGLContext().get() == m_gl_context) {
- GLenum pname;
- switch (m_target) {
- case GL_UNIFORM_BUFFER:
- pname = GL_UNIFORM_BUFFER_BINDING;
- break;
- default:
- assert(false);
- }
- GLuint buffer;
- GL_ASSERT(glGetIntegeri_v(pname, m_index, (GLint*)&buffer))
- if (buffer != memory_buffer->GetGLBuffer()->GetBuffer())
- //GL_ASSERT(glBindBufferBase(m_target, m_index, memoryBuffer->GetGLBuffer()->GetBuffer()));
- GL_ASSERT(glBindBufferRange(m_target, m_index, memory_buffer->GetGLBuffer()->GetBuffer(), m_offset, m_size))
- }
- }
- } // namespace gl
- } // namespace render
- } // namespace eq
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement