gl: Refactor shader compilation

This commit is contained in:
AniLeo 2020-05-16 06:50:28 +01:00 committed by Ani
parent 661636efef
commit 3db2f23e02
10 changed files with 43 additions and 138 deletions

View file

@ -44,8 +44,7 @@ namespace gl
{ {
if (!compiled) if (!compiled)
{ {
m_shader.create(gl::glsl::shader::type::compute); m_shader.create(gl::glsl::shader::type::compute, m_src);
m_shader.source(m_src);
m_shader.compile(); m_shader.compile();
m_program.create(); m_program.create();

View file

@ -2,7 +2,6 @@
#include "GLFragmentProgram.h" #include "GLFragmentProgram.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "GLHelpers.h"
#include "GLFragmentProgram.h" #include "GLFragmentProgram.h"
#include "GLCommonDecompiler.h" #include "GLCommonDecompiler.h"
#include "../GCM.h" #include "../GCM.h"
@ -341,7 +340,8 @@ GLFragmentProgram::~GLFragmentProgram()
void GLFragmentProgram::Decompile(const RSXFragmentProgram& prog) void GLFragmentProgram::Decompile(const RSXFragmentProgram& prog)
{ {
u32 size; u32 size;
GLFragmentDecompilerThread decompiler(shader, parr, prog, size); std::string source;
GLFragmentDecompilerThread decompiler(source, parr, prog, size);
if (!g_cfg.video.disable_native_float16) if (!g_cfg.video.disable_native_float16)
{ {
@ -365,55 +365,18 @@ void GLFragmentProgram::Decompile(const RSXFragmentProgram& prog)
FragmentConstantOffsetCache.push_back(offset); FragmentConstantOffsetCache.push_back(offset);
} }
} }
shader.create(gl::glsl::shader::type::fragment, source);
} }
void GLFragmentProgram::Compile() void GLFragmentProgram::Compile()
{ {
if (id) shader.compile();
{ id = shader.id();
glDeleteShader(id);
}
id = glCreateShader(GL_FRAGMENT_SHADER);
const char* str = shader.c_str();
const int strlen = ::narrow<int>(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
}
} }
void GLFragmentProgram::Delete() void GLFragmentProgram::Delete()
{ {
shader.clear(); shader.remove();
if (id)
{
glDeleteShader(id);
id = 0; id = 0;
} }
}

View file

@ -2,6 +2,7 @@
#include "../Common/FragmentProgramDecompiler.h" #include "../Common/FragmentProgramDecompiler.h"
#include "../Common/GLSLTypes.h" #include "../Common/GLSLTypes.h"
#include "Emu/RSX/RSXFragmentProgram.h" #include "Emu/RSX/RSXFragmentProgram.h"
#include "GLHelpers.h"
namespace glsl namespace glsl
{ {
@ -56,8 +57,8 @@ public:
~GLFragmentProgram(); ~GLFragmentProgram();
ParamArray parr; ParamArray parr;
u32 id = 0; u32 id;
std::string shader; gl::glsl::shader shader;
std::vector<size_t> FragmentConstantOffsetCache; std::vector<size_t> FragmentConstantOffsetCache;
/** /**

View file

@ -2407,6 +2407,7 @@ public:
class shader class shader
{ {
public: public:
std::string source;
enum class type enum class type
{ {
fragment = GL_FRAGMENT_SHADER, fragment = GL_FRAGMENT_SHADER,
@ -2415,12 +2416,10 @@ public:
}; };
private: private:
GLuint m_id = GL_NONE; GLuint m_id = GL_NONE;
type shader_type = type::vertex; type shader_type = type::vertex;
public: public:
shader() = default; shader() = default;
shader(GLuint id) shader(GLuint id)
@ -2428,15 +2427,9 @@ public:
set_id(id); set_id(id);
} }
shader(type type_)
{
create(type_);
}
shader(type type_, const std::string& src) shader(type type_, const std::string& src)
{ {
create(type_); create(type_, src);
source(src);
} }
~shader() ~shader()
@ -2445,24 +2438,18 @@ public:
remove(); 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<GLenum>(type_));
shader_type = type_; shader_type = type_;
source = src;
} }
void source(const std::string& src) const shader& compile()
{ {
const char* str = src.c_str(); m_id = glCreateShader(static_cast<GLenum>(shader_type));
const GLint length = ::narrow<GLint>(src.length()); const char* str = source.c_str();
const GLint length = ::narrow<GLint>(source.length());
if (g_cfg.video.log_programs) if (g_cfg.video.log_programs)
{ {
std::string base_name; std::string base_name;
@ -2483,10 +2470,6 @@ public:
} }
glShaderSource(m_id, 1, &str, &length); glShaderSource(m_id, 1, &str, &length);
}
shader& compile()
{
glCompileShader(m_id); glCompileShader(m_id);
GLint status = GL_FALSE; GLint status = GL_FALSE;
@ -2768,7 +2751,7 @@ public:
} }
} }
uint id() const GLuint id() const
{ {
return m_id; return m_id;
} }

View file

@ -55,12 +55,10 @@ namespace gl
{ {
if (!compiled) if (!compiled)
{ {
fs.create(gl::glsl::shader::type::fragment); fs.create(gl::glsl::shader::type::fragment, fs_src);
fs.source(fs_src);
fs.compile(); fs.compile();
vs.create(gl::glsl::shader::type::vertex); vs.create(gl::glsl::shader::type::vertex, vs_src);
vs.source(vs_src);
vs.compile(); vs.compile();
program_handle.create(); program_handle.create();

View file

@ -79,8 +79,8 @@ struct GLTraits
rsx_log.notice("*** vp id = %d", vertexProgramData.id); rsx_log.notice("*** vp id = %d", vertexProgramData.id);
rsx_log.notice("*** fp id = %d", fragmentProgramData.id); rsx_log.notice("*** fp id = %d", fragmentProgramData.id);
rsx_log.notice("*** vp shader = \n%s", vertexProgramData.shader.c_str()); rsx_log.notice("*** vp shader = \n%s", vertexProgramData.shader.source.c_str());
rsx_log.notice("*** fp shader = \n%s", fragmentProgramData.shader.c_str()); rsx_log.notice("*** fp shader = \n%s", fragmentProgramData.shader.source.c_str());
return result; return result;
} }

View file

@ -150,8 +150,7 @@ namespace gl
builder << program_common::interpreter::get_vertex_interpreter(); builder << program_common::interpreter::get_vertex_interpreter();
const std::string s = builder.str(); const std::string s = builder.str();
m_vs.create(glsl::shader::type::vertex); m_vs.create(glsl::shader::type::vertex, s);
m_vs.source(s);
m_vs.compile(); m_vs.compile();
} }
@ -303,8 +302,7 @@ namespace gl
builder << program_common::interpreter::get_fragment_interpreter(); builder << program_common::interpreter::get_fragment_interpreter();
const std::string s = builder.str(); const std::string s = builder.str();
prog_data.fs.create(glsl::shader::type::fragment); prog_data.fs.create(glsl::shader::type::fragment, s);
prog_data.fs.source(s);
prog_data.fs.compile(); prog_data.fs.compile();
} }

View file

@ -52,12 +52,10 @@ namespace gl
"}\n" "}\n"
}; };
m_fs.create(gl::glsl::shader::type::fragment); m_fs.create(gl::glsl::shader::type::fragment, fs);
m_fs.source(fs);
m_fs.compile(); m_fs.compile();
m_vs.create(gl::glsl::shader::type::vertex); m_vs.create(gl::glsl::shader::type::vertex, vs);
m_vs.source(vs);
m_vs.compile(); m_vs.compile();
m_program.create(); m_program.create();

View file

@ -4,7 +4,6 @@
#include "Emu/System.h" #include "Emu/System.h"
#include "GLCommonDecompiler.h" #include "GLCommonDecompiler.h"
#include "GLHelpers.h"
#include "../Common/GLSLCommon.h" #include "../Common/GLSLCommon.h"
#include <algorithm> #include <algorithm>
@ -267,55 +266,21 @@ GLVertexProgram::~GLVertexProgram()
void GLVertexProgram::Decompile(const RSXVertexProgram& prog) void GLVertexProgram::Decompile(const RSXVertexProgram& prog)
{ {
GLVertexDecompilerThread decompiler(prog, shader, parr); std::string source;
GLVertexDecompilerThread decompiler(prog, source, parr);
decompiler.Task(); decompiler.Task();
shader.create(gl::glsl::shader::type::vertex, source);
} }
void GLVertexProgram::Compile() void GLVertexProgram::Compile()
{ {
if (id) shader.compile();
{ id = shader.id();
glDeleteShader(id);
}
id = glCreateShader(GL_VERTEX_SHADER);
const char* str = shader.c_str();
const int strlen = ::narrow<int>(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();
}
} }
void GLVertexProgram::Delete() void GLVertexProgram::Delete()
{ {
shader.clear(); shader.remove();
if (id)
{
glDeleteShader(id);
id = 0; id = 0;
} }
}

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "../Common/VertexProgramDecompiler.h" #include "../Common/VertexProgramDecompiler.h"
#include "Emu/RSX/RSXVertexProgram.h" #include "Emu/RSX/RSXVertexProgram.h"
#include "GLHelpers.h"
enum enum
{ {
@ -54,9 +55,8 @@ public:
~GLVertexProgram(); ~GLVertexProgram();
ParamArray parr; ParamArray parr;
u32 id = 0; u32 id;
std::string shader; gl::glsl::shader shader;
bool interleaved;
void Decompile(const RSXVertexProgram& prog); void Decompile(const RSXVertexProgram& prog);
void Compile(); void Compile();