From 3db2f23e0243ecfdf373a5a10215a734867fc8d3 Mon Sep 17 00:00:00 2001 From: AniLeo Date: Sat, 16 May 2020 06:50:28 +0100 Subject: [PATCH] gl: Refactor shader compilation --- rpcs3/Emu/RSX/GL/GLCompute.h | 5 +-- rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp | 53 ++++-------------------- rpcs3/Emu/RSX/GL/GLFragmentProgram.h | 5 ++- rpcs3/Emu/RSX/GL/GLHelpers.h | 37 +++++------------ rpcs3/Emu/RSX/GL/GLOverlays.h | 6 +-- rpcs3/Emu/RSX/GL/GLProgramBuffer.h | 4 +- rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp | 6 +-- rpcs3/Emu/RSX/GL/GLTextOut.h | 6 +-- rpcs3/Emu/RSX/GL/GLVertexProgram.cpp | 51 ++++------------------- rpcs3/Emu/RSX/GL/GLVertexProgram.h | 8 ++-- 10 files changed, 43 insertions(+), 138 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.h b/rpcs3/Emu/RSX/GL/GLCompute.h index 850656c8f7..9e1374edb0 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.h +++ b/rpcs3/Emu/RSX/GL/GLCompute.h @@ -44,8 +44,7 @@ namespace gl { if (!compiled) { - m_shader.create(gl::glsl::shader::type::compute); - m_shader.source(m_src); + m_shader.create(gl::glsl::shader::type::compute, m_src); m_shader.compile(); m_program.create(); @@ -317,4 +316,4 @@ namespace gl } void destroy_compute_tasks(); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index a7f33f92d7..dbbcd8521c 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -2,7 +2,6 @@ #include "GLFragmentProgram.h" #include "Emu/System.h" -#include "GLHelpers.h" #include "GLFragmentProgram.h" #include "GLCommonDecompiler.h" #include "../GCM.h" @@ -341,7 +340,8 @@ GLFragmentProgram::~GLFragmentProgram() void GLFragmentProgram::Decompile(const RSXFragmentProgram& prog) { u32 size; - GLFragmentDecompilerThread decompiler(shader, parr, prog, size); + std::string source; + GLFragmentDecompilerThread decompiler(source, parr, prog, size); if (!g_cfg.video.disable_native_float16) { @@ -365,55 +365,18 @@ void GLFragmentProgram::Decompile(const RSXFragmentProgram& prog) FragmentConstantOffsetCache.push_back(offset); } } + + shader.create(gl::glsl::shader::type::fragment, source); } void GLFragmentProgram::Compile() { - if (id) - { - glDeleteShader(id); - } - - id = glCreateShader(GL_FRAGMENT_SHADER); - - const char* str = shader.c_str(); - const int strlen = ::narrow(shader.length()); - - fs::file(fs::get_cache_dir() + "shaderlog/FragmentProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str); - - glShaderSource(id, 1, &str, &strlen); - glCompileShader(id); - - GLint compileStatus = GL_FALSE; - glGetShaderiv(id, GL_COMPILE_STATUS, &compileStatus); // Determine the result of the glCompileShader call - if (compileStatus != GL_TRUE) // If the shader failed to compile... - { - GLint infoLength; - glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infoLength); // Retrieve the length in bytes (including trailing NULL) of the shader info log - - if (infoLength > 0) - { - GLsizei len; - char* buf = new char[infoLength]; // Buffer to store infoLog - - glGetShaderInfoLog(id, infoLength, &len, buf); // Retrieve the shader info log into our buffer - rsx_log.error("Failed to compile shader: %s", buf); // Write log to the console - - delete[] buf; - } - - rsx_log.notice("%s", shader); // Log the text of the shader that failed to compile - Emu.Pause(); // Pause the emulator, we can't really continue from here - } + shader.compile(); + id = shader.id(); } void GLFragmentProgram::Delete() { - shader.clear(); - - if (id) - { - glDeleteShader(id); - id = 0; - } + shader.remove(); + id = 0; } diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.h b/rpcs3/Emu/RSX/GL/GLFragmentProgram.h index 77b2612183..a9d1373924 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.h +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.h @@ -2,6 +2,7 @@ #include "../Common/FragmentProgramDecompiler.h" #include "../Common/GLSLTypes.h" #include "Emu/RSX/RSXFragmentProgram.h" +#include "GLHelpers.h" namespace glsl { @@ -56,8 +57,8 @@ public: ~GLFragmentProgram(); ParamArray parr; - u32 id = 0; - std::string shader; + u32 id; + gl::glsl::shader shader; std::vector FragmentConstantOffsetCache; /** diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 0688ffe787..7e82e2b937 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -2407,6 +2407,7 @@ public: class shader { public: + std::string source; enum class type { fragment = GL_FRAGMENT_SHADER, @@ -2415,12 +2416,10 @@ public: }; private: - GLuint m_id = GL_NONE; type shader_type = type::vertex; public: - shader() = default; shader(GLuint id) @@ -2428,15 +2427,9 @@ public: set_id(id); } - shader(type type_) - { - create(type_); - } - shader(type type_, const std::string& src) { - create(type_); - source(src); + create(type_, src); } ~shader() @@ -2445,24 +2438,18 @@ public: remove(); } - void recreate(type type_) + void create(type type_, const std::string& src) { - if (created()) - remove(); - - create(type_); - } - - void create(type type_) - { - m_id = glCreateShader(static_cast(type_)); shader_type = type_; + source = src; } - void source(const std::string& src) const + shader& compile() { - const char* str = src.c_str(); - const GLint length = ::narrow(src.length()); + m_id = glCreateShader(static_cast(shader_type)); + const char* str = source.c_str(); + const GLint length = ::narrow(source.length()); + if (g_cfg.video.log_programs) { std::string base_name; @@ -2483,10 +2470,6 @@ public: } glShaderSource(m_id, 1, &str, &length); - } - - shader& compile() - { glCompileShader(m_id); GLint status = GL_FALSE; @@ -2768,7 +2751,7 @@ public: } } - uint id() const + GLuint id() const { return m_id; } diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 3dc134ad0a..c25a2d9dac 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -55,12 +55,10 @@ namespace gl { if (!compiled) { - fs.create(gl::glsl::shader::type::fragment); - fs.source(fs_src); + fs.create(gl::glsl::shader::type::fragment, fs_src); fs.compile(); - vs.create(gl::glsl::shader::type::vertex); - vs.source(vs_src); + vs.create(gl::glsl::shader::type::vertex, vs_src); vs.compile(); program_handle.create(); diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 2fedc1b775..0472ca6520 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -79,8 +79,8 @@ struct GLTraits rsx_log.notice("*** vp id = %d", vertexProgramData.id); rsx_log.notice("*** fp id = %d", fragmentProgramData.id); - rsx_log.notice("*** vp shader = \n%s", vertexProgramData.shader.c_str()); - rsx_log.notice("*** fp shader = \n%s", fragmentProgramData.shader.c_str()); + rsx_log.notice("*** vp shader = \n%s", vertexProgramData.shader.source.c_str()); + rsx_log.notice("*** fp shader = \n%s", fragmentProgramData.shader.source.c_str()); return result; } diff --git a/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp b/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp index c1efb73013..7924384e84 100644 --- a/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp +++ b/rpcs3/Emu/RSX/GL/GLShaderInterpreter.cpp @@ -150,8 +150,7 @@ namespace gl builder << program_common::interpreter::get_vertex_interpreter(); const std::string s = builder.str(); - m_vs.create(glsl::shader::type::vertex); - m_vs.source(s); + m_vs.create(glsl::shader::type::vertex, s); m_vs.compile(); } @@ -303,8 +302,7 @@ namespace gl builder << program_common::interpreter::get_fragment_interpreter(); const std::string s = builder.str(); - prog_data.fs.create(glsl::shader::type::fragment); - prog_data.fs.source(s); + prog_data.fs.create(glsl::shader::type::fragment, s); prog_data.fs.compile(); } diff --git a/rpcs3/Emu/RSX/GL/GLTextOut.h b/rpcs3/Emu/RSX/GL/GLTextOut.h index 59fd25a15a..a43be5a30c 100644 --- a/rpcs3/Emu/RSX/GL/GLTextOut.h +++ b/rpcs3/Emu/RSX/GL/GLTextOut.h @@ -52,12 +52,10 @@ namespace gl "}\n" }; - m_fs.create(gl::glsl::shader::type::fragment); - m_fs.source(fs); + m_fs.create(gl::glsl::shader::type::fragment, fs); m_fs.compile(); - m_vs.create(gl::glsl::shader::type::vertex); - m_vs.source(vs); + m_vs.create(gl::glsl::shader::type::vertex, vs); m_vs.compile(); m_program.create(); diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 38c0ba5735..619150fedd 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -4,7 +4,6 @@ #include "Emu/System.h" #include "GLCommonDecompiler.h" -#include "GLHelpers.h" #include "../Common/GLSLCommon.h" #include @@ -267,55 +266,21 @@ GLVertexProgram::~GLVertexProgram() void GLVertexProgram::Decompile(const RSXVertexProgram& prog) { - GLVertexDecompilerThread decompiler(prog, shader, parr); + std::string source; + GLVertexDecompilerThread decompiler(prog, source, parr); decompiler.Task(); + + shader.create(gl::glsl::shader::type::vertex, source); } void GLVertexProgram::Compile() { - if (id) - { - glDeleteShader(id); - } - - id = glCreateShader(GL_VERTEX_SHADER); - - const char* str = shader.c_str(); - const int strlen = ::narrow(shader.length()); - - if (g_cfg.video.log_programs) - fs::file(fs::get_cache_dir() + "shaderlog/VertexProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str); - - glShaderSource(id, 1, &str, &strlen); - glCompileShader(id); - - GLint r = GL_FALSE; - glGetShaderiv(id, GL_COMPILE_STATUS, &r); - if (r != GL_TRUE) - { - glGetShaderiv(id, GL_INFO_LOG_LENGTH, &r); - - if (r) - { - char* buf = new char[r + 1](); - GLsizei len; - glGetShaderInfoLog(id, r, &len, buf); - rsx_log.error("Failed to compile vertex shader: %s", buf); - delete[] buf; - } - - rsx_log.notice("%s", shader.c_str()); - Emu.Pause(); - } + shader.compile(); + id = shader.id(); } void GLVertexProgram::Delete() { - shader.clear(); - - if (id) - { - glDeleteShader(id); - id = 0; - } + shader.remove(); + id = 0; } diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.h b/rpcs3/Emu/RSX/GL/GLVertexProgram.h index ac9817e9d1..3c675a4b68 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.h +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.h @@ -1,6 +1,7 @@ #pragma once #include "../Common/VertexProgramDecompiler.h" #include "Emu/RSX/RSXVertexProgram.h" +#include "GLHelpers.h" enum { @@ -48,15 +49,14 @@ public: }; class GLVertexProgram -{ +{ public: GLVertexProgram(); ~GLVertexProgram(); ParamArray parr; - u32 id = 0; - std::string shader; - bool interleaved; + u32 id; + gl::glsl::shader shader; void Decompile(const RSXVertexProgram& prog); void Compile();