diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 719f713a13..1487183d39 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -377,7 +377,7 @@ private: OGLVertexArray attributeless_vao; OGLBuffer d24s8_abgr_buffer; GLsizeiptr d24s8_abgr_buffer_size; - OGLShader d24s8_abgr_shader; + OGLProgram d24s8_abgr_shader; GLint d24s8_abgr_tbo_size_u_id; GLint d24s8_abgr_viewport_u_id; }; diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 44f7b2c71f..d57a0ff890 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include "common/common_types.h" #include "video_core/renderer_opengl/gl_shader_util.h" @@ -96,11 +97,53 @@ public: return *this; } - /// Creates a new internal OpenGL resource and stores the handle - void Create(const char* vert_shader, const char* frag_shader) { + void Create(const char* source, GLenum type) { if (handle != 0) return; - handle = GLShader::LoadProgram(vert_shader, frag_shader); + if (source == nullptr) + return; + handle = GLShader::LoadShader(source, type); + } + + void Release() { + if (handle == 0) + return; + glDeleteShader(handle); + handle = 0; + } + + GLuint handle = 0; +}; + +class OGLProgram : private NonCopyable { +public: + OGLProgram() = default; + + OGLProgram(OGLProgram&& o) : handle(std::exchange(o.handle, 0)) {} + + ~OGLProgram() { + Release(); + } + + OGLProgram& operator=(OGLProgram&& o) { + Release(); + handle = std::exchange(o.handle, 0); + return *this; + } + + /// Creates a new program from given shader objects + void Create(bool separable_program, const std::vector& shaders) { + if (handle != 0) + return; + handle = GLShader::LoadProgram(separable_program, shaders); + } + + /// Creates a new program from given shader soruce code + void Create(const char* vert_shader, const char* frag_shader) { + OGLShader vert, frag; + vert.Create(vert_shader, GL_VERTEX_SHADER); + frag.Create(frag_shader, GL_FRAGMENT_SHADER); + Create(false, {vert.handle, frag.handle}); } /// Deletes the internal OpenGL resource diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 0b4f69e8f6..f827a26af9 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -73,7 +73,7 @@ private: // OpenGL object IDs OGLVertexArray vertex_array; OGLBuffer vertex_buffer; - OGLShader shader; + OGLProgram shader; /// Display information for top and bottom screens respectively std::array screen_infos;