// Copyright 2017 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #include "VideoBackends/OGL/OGLShader.h" #include "VideoBackends/OGL/ProgramShaderCache.h" namespace OGL { static GLenum GetGLShaderTypeForStage(ShaderStage stage) { switch (stage) { case ShaderStage::Vertex: return GL_VERTEX_SHADER; case ShaderStage::Geometry: return GL_GEOMETRY_SHADER; case ShaderStage::Pixel: return GL_FRAGMENT_SHADER; case ShaderStage::Compute: return GL_COMPUTE_SHADER; default: return 0; } } OGLShader::OGLShader(ShaderStage stage, GLenum gl_type, GLuint shader_id) : AbstractShader(stage), m_type(gl_type), m_id(shader_id) { } OGLShader::OGLShader(GLuint compute_program_id) : AbstractShader(ShaderStage::Compute), m_type(GL_COMPUTE_SHADER), m_compute_program_id(compute_program_id) { } OGLShader::~OGLShader() { if (m_stage != ShaderStage::Compute) glDeleteShader(m_id); else glDeleteProgram(m_compute_program_id); } bool OGLShader::HasBinary() const { // NOTE: GL shaders do not have binaries, programs do. return false; } AbstractShader::BinaryData OGLShader::GetBinary() const { return {}; } std::unique_ptr OGLShader::CreateFromSource(ShaderStage stage, const char* source, size_t length) { if (stage != ShaderStage::Compute) { GLenum shader_type = GetGLShaderTypeForStage(stage); GLuint shader_id = ProgramShaderCache::CompileSingleShader(shader_type, std::string(source, length)); if (!shader_id) return nullptr; return std::make_unique(stage, shader_type, shader_id); } // Compute shaders. SHADER prog; if (!ProgramShaderCache::CompileComputeShader(prog, std::string(source, length))) return nullptr; return std::make_unique(prog.glprogid); } } // namespace OGL