diff --git a/Source/Core/VideoBackends/OGL/OGLShader.cpp b/Source/Core/VideoBackends/OGL/OGLShader.cpp index fc13b5b975..ee96f1c352 100644 --- a/Source/Core/VideoBackends/OGL/OGLShader.cpp +++ b/Source/Core/VideoBackends/OGL/OGLShader.cpp @@ -24,15 +24,16 @@ static GLenum GetGLShaderTypeForStage(ShaderStage stage) } } -OGLShader::OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id) +OGLShader::OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id, std::string source) : AbstractShader(stage), m_id(ProgramShaderCache::GenerateShaderID()), m_type(gl_type), - m_gl_id(gl_id) + m_gl_id(gl_id), m_source(std::move(source)) { } -OGLShader::OGLShader(GLuint gl_compute_program_id) +OGLShader::OGLShader(GLuint gl_compute_program_id, std::string source) : AbstractShader(ShaderStage::Compute), m_id(ProgramShaderCache::GenerateShaderID()), - m_type(GL_COMPUTE_SHADER), m_gl_compute_program_id(gl_compute_program_id) + m_type(GL_COMPUTE_SHADER), m_gl_compute_program_id(gl_compute_program_id), + m_source(std::move(source)) { } @@ -47,22 +48,22 @@ OGLShader::~OGLShader() std::unique_ptr OGLShader::CreateFromSource(ShaderStage stage, const char* source, size_t length) { + std::string source_str(source, length); if (stage != ShaderStage::Compute) { GLenum shader_type = GetGLShaderTypeForStage(stage); - GLuint shader_id = - ProgramShaderCache::CompileSingleShader(shader_type, std::string(source, length)); + GLuint shader_id = ProgramShaderCache::CompileSingleShader(shader_type, source_str); if (!shader_id) return nullptr; - return std::make_unique(stage, shader_type, shader_id); + return std::make_unique(stage, shader_type, shader_id, std::move(source_str)); } // Compute shaders. SHADER prog; - if (!ProgramShaderCache::CompileComputeShader(prog, std::string(source, length))) + if (!ProgramShaderCache::CompileComputeShader(prog, source_str)) return nullptr; - return std::make_unique(prog.glprogid); + return std::make_unique(prog.glprogid, std::move(source_str)); } } // namespace OGL diff --git a/Source/Core/VideoBackends/OGL/OGLShader.h b/Source/Core/VideoBackends/OGL/OGLShader.h index ad0432ada4..5289e1933f 100644 --- a/Source/Core/VideoBackends/OGL/OGLShader.h +++ b/Source/Core/VideoBackends/OGL/OGLShader.h @@ -16,14 +16,15 @@ namespace OGL class OGLShader final : public AbstractShader { public: - explicit OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id); - explicit OGLShader(GLuint gl_compute_program_id); + explicit OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id, std::string source); + explicit OGLShader(GLuint gl_compute_program_id, std::string source); ~OGLShader() override; u64 GetID() const { return m_id; } GLenum GetGLShaderType() const { return m_type; } GLuint GetGLShaderID() const { return m_gl_id; } GLuint GetGLComputeProgramID() const { return m_gl_compute_program_id; } + const std::string& GetSource() const { return m_source; } static std::unique_ptr CreateFromSource(ShaderStage stage, const char* source, size_t length); @@ -33,6 +34,7 @@ private: GLenum m_type; GLuint m_gl_id = 0; GLuint m_gl_compute_program_id = 0; + std::string m_source; }; } // namespace OGL diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 6afdfd05a9..85084979c3 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -291,7 +291,7 @@ bool ProgramShaderCache::CompileComputeShader(SHADER& shader, const std::string& // original shaders aren't needed any more glDeleteShader(shader_id); - if (!CheckProgramLinkResult(shader.glprogid, full_code, "", "")) + if (!CheckProgramLinkResult(shader.glprogid, &full_code, nullptr, nullptr)) { shader.Destroy(); return false; @@ -374,8 +374,8 @@ bool ProgramShaderCache::CheckShaderCompileResult(GLuint id, GLenum type, const return true; } -bool ProgramShaderCache::CheckProgramLinkResult(GLuint id, const std::string& vcode, - const std::string& pcode, const std::string& gcode) +bool ProgramShaderCache::CheckProgramLinkResult(GLuint id, const std::string* vcode, + const std::string* pcode, const std::string* gcode) { GLint linkStatus; glGetProgramiv(id, GL_LINK_STATUS, &linkStatus); @@ -393,9 +393,13 @@ bool ProgramShaderCache::CheckProgramLinkResult(GLuint id, const std::string& vc StringFromFormat("%sbad_p_%d.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); std::ofstream file; File::OpenFStream(file, filename, std::ios_base::out); - file << s_glsl_header << vcode << s_glsl_header << pcode; - if (!gcode.empty()) - file << s_glsl_header << gcode; + if (vcode) + file << s_glsl_header << *vcode << '\n'; + if (gcode) + file << s_glsl_header << *gcode << '\n'; + if (pcode) + file << s_glsl_header << *pcode << '\n'; + file << info_log; file.close(); @@ -573,7 +577,10 @@ PipelineProgram* ProgramShaderCache::GetPipelineProgram(const GLVertexFormat* ve if (!s_is_shared_context && vao != s_last_VAO) glBindVertexArray(s_last_VAO); - if (!ProgramShaderCache::CheckProgramLinkResult(prog->shader.glprogid, {}, {}, {})) + if (!ProgramShaderCache::CheckProgramLinkResult( + prog->shader.glprogid, vertex_shader ? &vertex_shader->GetSource() : nullptr, + geometry_shader ? &geometry_shader->GetSource() : nullptr, + pixel_shader ? &pixel_shader->GetSource() : nullptr)) { prog->shader.Destroy(); return nullptr; diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h index 06cabcc689..4aeb40a6c9 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h @@ -77,8 +77,8 @@ public: static bool CompileComputeShader(SHADER& shader, const std::string& code); static GLuint CompileSingleShader(GLenum type, const std::string& code); static bool CheckShaderCompileResult(GLuint id, GLenum type, const std::string& code); - static bool CheckProgramLinkResult(GLuint id, const std::string& vcode, const std::string& pcode, - const std::string& gcode); + static bool CheckProgramLinkResult(GLuint id, const std::string* vcode, const std::string* pcode, + const std::string* gcode); static StreamBuffer* GetUniformBuffer(); static u32 GetUniformBufferAlignment(); static void UploadConstants();