OGL: Store shader source in OGLShader

So it can be dumped with info log when linking fails.
This commit is contained in:
Stenzek 2019-04-20 23:39:54 +10:00
parent bbd1ae16db
commit 5c95dc61fc
4 changed files with 30 additions and 20 deletions

View File

@ -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), : 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()), : 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> OGLShader::CreateFromSource(ShaderStage stage, const char* source, std::unique_ptr<OGLShader> OGLShader::CreateFromSource(ShaderStage stage, const char* source,
size_t length) size_t length)
{ {
std::string source_str(source, length);
if (stage != ShaderStage::Compute) if (stage != ShaderStage::Compute)
{ {
GLenum shader_type = GetGLShaderTypeForStage(stage); GLenum shader_type = GetGLShaderTypeForStage(stage);
GLuint shader_id = GLuint shader_id = ProgramShaderCache::CompileSingleShader(shader_type, source_str);
ProgramShaderCache::CompileSingleShader(shader_type, std::string(source, length));
if (!shader_id) if (!shader_id)
return nullptr; return nullptr;
return std::make_unique<OGLShader>(stage, shader_type, shader_id); return std::make_unique<OGLShader>(stage, shader_type, shader_id, std::move(source_str));
} }
// Compute shaders. // Compute shaders.
SHADER prog; SHADER prog;
if (!ProgramShaderCache::CompileComputeShader(prog, std::string(source, length))) if (!ProgramShaderCache::CompileComputeShader(prog, source_str))
return nullptr; return nullptr;
return std::make_unique<OGLShader>(prog.glprogid); return std::make_unique<OGLShader>(prog.glprogid, std::move(source_str));
} }
} // namespace OGL } // namespace OGL

View File

@ -16,14 +16,15 @@ namespace OGL
class OGLShader final : public AbstractShader class OGLShader final : public AbstractShader
{ {
public: public:
explicit OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id); explicit OGLShader(ShaderStage stage, GLenum gl_type, GLuint gl_id, std::string source);
explicit OGLShader(GLuint gl_compute_program_id); explicit OGLShader(GLuint gl_compute_program_id, std::string source);
~OGLShader() override; ~OGLShader() override;
u64 GetID() const { return m_id; } u64 GetID() const { return m_id; }
GLenum GetGLShaderType() const { return m_type; } GLenum GetGLShaderType() const { return m_type; }
GLuint GetGLShaderID() const { return m_gl_id; } GLuint GetGLShaderID() const { return m_gl_id; }
GLuint GetGLComputeProgramID() const { return m_gl_compute_program_id; } GLuint GetGLComputeProgramID() const { return m_gl_compute_program_id; }
const std::string& GetSource() const { return m_source; }
static std::unique_ptr<OGLShader> CreateFromSource(ShaderStage stage, const char* source, static std::unique_ptr<OGLShader> CreateFromSource(ShaderStage stage, const char* source,
size_t length); size_t length);
@ -33,6 +34,7 @@ private:
GLenum m_type; GLenum m_type;
GLuint m_gl_id = 0; GLuint m_gl_id = 0;
GLuint m_gl_compute_program_id = 0; GLuint m_gl_compute_program_id = 0;
std::string m_source;
}; };
} // namespace OGL } // namespace OGL

View File

@ -291,7 +291,7 @@ bool ProgramShaderCache::CompileComputeShader(SHADER& shader, const std::string&
// original shaders aren't needed any more // original shaders aren't needed any more
glDeleteShader(shader_id); glDeleteShader(shader_id);
if (!CheckProgramLinkResult(shader.glprogid, full_code, "", "")) if (!CheckProgramLinkResult(shader.glprogid, &full_code, nullptr, nullptr))
{ {
shader.Destroy(); shader.Destroy();
return false; return false;
@ -374,8 +374,8 @@ bool ProgramShaderCache::CheckShaderCompileResult(GLuint id, GLenum type, const
return true; return true;
} }
bool ProgramShaderCache::CheckProgramLinkResult(GLuint id, const std::string& vcode, bool ProgramShaderCache::CheckProgramLinkResult(GLuint id, const std::string* vcode,
const std::string& pcode, const std::string& gcode) const std::string* pcode, const std::string* gcode)
{ {
GLint linkStatus; GLint linkStatus;
glGetProgramiv(id, GL_LINK_STATUS, &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++); StringFromFormat("%sbad_p_%d.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
std::ofstream file; std::ofstream file;
File::OpenFStream(file, filename, std::ios_base::out); File::OpenFStream(file, filename, std::ios_base::out);
file << s_glsl_header << vcode << s_glsl_header << pcode; if (vcode)
if (!gcode.empty()) file << s_glsl_header << *vcode << '\n';
file << s_glsl_header << gcode; if (gcode)
file << s_glsl_header << *gcode << '\n';
if (pcode)
file << s_glsl_header << *pcode << '\n';
file << info_log; file << info_log;
file.close(); file.close();
@ -573,7 +577,10 @@ PipelineProgram* ProgramShaderCache::GetPipelineProgram(const GLVertexFormat* ve
if (!s_is_shared_context && vao != s_last_VAO) if (!s_is_shared_context && vao != s_last_VAO)
glBindVertexArray(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(); prog->shader.Destroy();
return nullptr; return nullptr;

View File

@ -77,8 +77,8 @@ public:
static bool CompileComputeShader(SHADER& shader, const std::string& code); static bool CompileComputeShader(SHADER& shader, const std::string& code);
static GLuint CompileSingleShader(GLenum type, 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 CheckShaderCompileResult(GLuint id, GLenum type, const std::string& code);
static bool CheckProgramLinkResult(GLuint id, const std::string& vcode, const std::string& pcode, static bool CheckProgramLinkResult(GLuint id, const std::string* vcode, const std::string* pcode,
const std::string& gcode); const std::string* gcode);
static StreamBuffer* GetUniformBuffer(); static StreamBuffer* GetUniformBuffer();
static u32 GetUniformBufferAlignment(); static u32 GetUniformBufferAlignment();
static void UploadConstants(); static void UploadConstants();