mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: improve the shader program management
* keep a reference of program/pipeline created to ease the deletion * extend a bit the API to support multiple pipeline Final goal will be to use a pre link pipeline for SW shaders. And uses the default pipeline for HW shaders.
This commit is contained in:
parent
395e2f31d0
commit
95e3dcb448
|
@ -54,6 +54,7 @@ namespace GLState {
|
|||
GLuint ps;
|
||||
GLuint gs;
|
||||
GLuint vs;
|
||||
GLuint pipeline;
|
||||
|
||||
void Clear() {
|
||||
fbo = 0;
|
||||
|
@ -89,5 +90,6 @@ namespace GLState {
|
|||
ps = 0;
|
||||
gs = 0;
|
||||
vs = 0;
|
||||
pipeline = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace GLState {
|
|||
extern GLuint ps;
|
||||
extern GLuint gs;
|
||||
extern GLuint vs;
|
||||
extern GLuint pipeline;
|
||||
|
||||
extern void Clear();
|
||||
}
|
||||
|
|
|
@ -92,38 +92,27 @@ GSDeviceOGL::~GSDeviceOGL()
|
|||
delete (m_va);
|
||||
|
||||
// Clean m_merge_obj
|
||||
for (size_t i = 0; i < countof(m_merge_obj.ps); i++)
|
||||
m_shader->Delete(m_merge_obj.ps[i]);
|
||||
delete (m_merge_obj.cb);
|
||||
|
||||
// Clean m_interlace
|
||||
for (size_t i = 0; i < countof(m_interlace.ps); i++)
|
||||
m_shader->Delete(m_interlace.ps[i]);
|
||||
delete (m_interlace.cb);
|
||||
|
||||
// Clean m_convert
|
||||
m_shader->Delete(m_convert.vs);
|
||||
for (size_t i = 0; i < countof(m_convert.ps); i++)
|
||||
m_shader->Delete(m_convert.ps[i]);
|
||||
delete m_convert.dss;
|
||||
delete m_convert.dss_write;
|
||||
delete m_convert.cb;
|
||||
|
||||
// Clean m_fxaa
|
||||
delete m_fxaa.cb;
|
||||
m_shader->Delete(m_fxaa.ps);
|
||||
|
||||
// Clean m_shaderfx
|
||||
delete m_shaderfx.cb;
|
||||
m_shader->Delete(m_shaderfx.ps);
|
||||
|
||||
// Clean m_date
|
||||
delete m_date.dss;
|
||||
|
||||
// Clean shadeboost
|
||||
delete m_shadeboost.cb;
|
||||
m_shader->Delete(m_shadeboost.ps);
|
||||
|
||||
|
||||
// Clean various opengl allocation
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
|
@ -133,11 +122,6 @@ GSDeviceOGL::~GSDeviceOGL()
|
|||
delete m_vs_cb;
|
||||
delete m_ps_cb;
|
||||
glDeleteSamplers(1, &m_palette_ss);
|
||||
m_shader->Delete(m_apitrace);
|
||||
|
||||
for (uint32 key = 0; key < countof(m_vs); key++) m_shader->Delete(m_vs[key]);
|
||||
for (uint32 key = 0; key < countof(m_gs); key++) m_shader->Delete(m_gs[key]);
|
||||
for (auto it = m_ps.begin(); it != m_ps.end() ; it++) m_shader->Delete(it->second);
|
||||
|
||||
m_ps.clear();
|
||||
|
||||
|
@ -744,7 +728,6 @@ void GSDeviceOGL::SelfShaderTest()
|
|||
GLuint p = CompilePS(sel); \
|
||||
nb_shader++; \
|
||||
perf += m_shader->DumpAsm(file, p); \
|
||||
m_shader->Delete(p); \
|
||||
} while(0);
|
||||
|
||||
#define PRINT_TEST(s) \
|
||||
|
@ -1025,7 +1008,7 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
|
|||
|
||||
GSVector2i ds = dTex->GetSize();
|
||||
|
||||
m_shader->Pipeline(m_convert.vs, 0, ps);
|
||||
m_shader->BindPipeline(m_convert.vs, 0, ps);
|
||||
|
||||
// ************************************
|
||||
// om
|
||||
|
@ -1263,7 +1246,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
|||
|
||||
ClearStencil(ds, 0);
|
||||
|
||||
m_shader->Pipeline(m_convert.vs, 0, m_convert.ps[datm ? ShaderConvert_DATM_1 : ShaderConvert_DATM_0]);
|
||||
m_shader->BindPipeline(m_convert.vs, 0, m_convert.ps[datm ? ShaderConvert_DATM_1 : ShaderConvert_DATM_0]);
|
||||
|
||||
// om
|
||||
|
||||
|
|
|
@ -27,16 +27,31 @@ GSShaderOGL::GSShaderOGL(bool debug) :
|
|||
m_pipeline(0),
|
||||
m_debug_shader(debug)
|
||||
{
|
||||
glCreateProgramPipelines(1, &m_pipeline);
|
||||
glBindProgramPipeline(m_pipeline);
|
||||
// Create a default pipeline
|
||||
m_pipeline = LinkPipeline(0, 0, 0);
|
||||
BindPipeline(m_pipeline);
|
||||
}
|
||||
|
||||
GSShaderOGL::~GSShaderOGL()
|
||||
{
|
||||
glDeleteProgramPipelines(1, &m_pipeline);
|
||||
for (auto p : m_prog_to_delete) glDeleteProgram(p);
|
||||
glDeleteProgramPipelines(m_pipe_to_delete.size(), &m_pipe_to_delete[0]);
|
||||
}
|
||||
|
||||
void GSShaderOGL::Pipeline(GLuint vs, GLuint gs, GLuint ps)
|
||||
GLuint GSShaderOGL::LinkPipeline(GLuint vs, GLuint gs, GLuint ps)
|
||||
{
|
||||
GLuint p;
|
||||
glCreateProgramPipelines(1, &p);
|
||||
glUseProgramStages(p, GL_VERTEX_SHADER_BIT, vs);
|
||||
glUseProgramStages(p, GL_GEOMETRY_SHADER_BIT, gs);
|
||||
glUseProgramStages(p, GL_FRAGMENT_SHADER_BIT, ps);
|
||||
|
||||
m_pipe_to_delete.push_back(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void GSShaderOGL::BindPipeline(GLuint vs, GLuint gs, GLuint ps)
|
||||
{
|
||||
if (GLState::vs != vs)
|
||||
{
|
||||
|
@ -60,6 +75,14 @@ void GSShaderOGL::Pipeline(GLuint vs, GLuint gs, GLuint ps)
|
|||
}
|
||||
}
|
||||
|
||||
void GSShaderOGL::BindPipeline(GLuint pipe)
|
||||
{
|
||||
if (GLState::pipeline != pipe) {
|
||||
GLState::pipeline = pipe;
|
||||
glBindProgramPipeline(pipe);
|
||||
}
|
||||
}
|
||||
|
||||
bool GSShaderOGL::ValidateProgram(GLuint p)
|
||||
{
|
||||
if (!m_debug_shader) return true;
|
||||
|
@ -182,6 +205,9 @@ GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& ent
|
|||
fprintf(stderr, "\n%s", macro_sel.c_str());
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
m_prog_to_delete.push_back(program);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
|
@ -243,8 +269,3 @@ int GSShaderOGL::DumpAsm(const std::string& file, GLuint p)
|
|||
|
||||
return instructions;
|
||||
}
|
||||
|
||||
void GSShaderOGL::Delete(GLuint s)
|
||||
{
|
||||
glDeleteProgram(s);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ class GSShaderOGL {
|
|||
GLuint m_pipeline;
|
||||
const bool m_debug_shader;
|
||||
|
||||
std::vector<GLuint> m_prog_to_delete;
|
||||
std::vector<GLuint> m_pipe_to_delete;
|
||||
|
||||
bool ValidateProgram(GLuint p);
|
||||
bool ValidatePipeline(GLuint p);
|
||||
|
||||
|
@ -34,11 +37,11 @@ class GSShaderOGL {
|
|||
GSShaderOGL(bool debug);
|
||||
~GSShaderOGL();
|
||||
|
||||
void Pipeline(GLuint vs, GLuint gs, GLuint ps);
|
||||
void BindPipeline(GLuint vs, GLuint gs, GLuint ps);
|
||||
void BindPipeline(GLuint pipe);
|
||||
|
||||
GLuint Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel = "");
|
||||
GLuint LinkPipeline(GLuint vs, GLuint gs, GLuint ps);
|
||||
|
||||
int DumpAsm(const std::string& file, GLuint p);
|
||||
|
||||
void Delete(GLuint s);
|
||||
};
|
||||
|
|
|
@ -128,7 +128,7 @@ void GSDeviceOGL::SetupPipeline(const VSSelector& vsel, const GSSelector& gsel,
|
|||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
m_shader->Pipeline(m_vs[vsel], m_gs[gsel], ps);
|
||||
m_shader->BindPipeline(m_vs[vsel], m_gs[gsel], ps);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupSampler(PSSamplerSelector ssel)
|
||||
|
|
Loading…
Reference in New Issue