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 ps;
|
||||||
GLuint gs;
|
GLuint gs;
|
||||||
GLuint vs;
|
GLuint vs;
|
||||||
|
GLuint pipeline;
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
fbo = 0;
|
fbo = 0;
|
||||||
|
@ -89,5 +90,6 @@ namespace GLState {
|
||||||
ps = 0;
|
ps = 0;
|
||||||
gs = 0;
|
gs = 0;
|
||||||
vs = 0;
|
vs = 0;
|
||||||
|
pipeline = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace GLState {
|
||||||
extern GLuint ps;
|
extern GLuint ps;
|
||||||
extern GLuint gs;
|
extern GLuint gs;
|
||||||
extern GLuint vs;
|
extern GLuint vs;
|
||||||
|
extern GLuint pipeline;
|
||||||
|
|
||||||
extern void Clear();
|
extern void Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,38 +92,27 @@ GSDeviceOGL::~GSDeviceOGL()
|
||||||
delete (m_va);
|
delete (m_va);
|
||||||
|
|
||||||
// Clean m_merge_obj
|
// 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);
|
delete (m_merge_obj.cb);
|
||||||
|
|
||||||
// Clean m_interlace
|
// 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);
|
delete (m_interlace.cb);
|
||||||
|
|
||||||
// Clean m_convert
|
// 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;
|
||||||
delete m_convert.dss_write;
|
delete m_convert.dss_write;
|
||||||
delete m_convert.cb;
|
delete m_convert.cb;
|
||||||
|
|
||||||
// Clean m_fxaa
|
// Clean m_fxaa
|
||||||
delete m_fxaa.cb;
|
delete m_fxaa.cb;
|
||||||
m_shader->Delete(m_fxaa.ps);
|
|
||||||
|
|
||||||
// Clean m_shaderfx
|
// Clean m_shaderfx
|
||||||
delete m_shaderfx.cb;
|
delete m_shaderfx.cb;
|
||||||
m_shader->Delete(m_shaderfx.ps);
|
|
||||||
|
|
||||||
// Clean m_date
|
// Clean m_date
|
||||||
delete m_date.dss;
|
delete m_date.dss;
|
||||||
|
|
||||||
// Clean shadeboost
|
// Clean shadeboost
|
||||||
delete m_shadeboost.cb;
|
delete m_shadeboost.cb;
|
||||||
m_shader->Delete(m_shadeboost.ps);
|
|
||||||
|
|
||||||
|
|
||||||
// Clean various opengl allocation
|
// Clean various opengl allocation
|
||||||
glDeleteFramebuffers(1, &m_fbo);
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
|
@ -133,11 +122,6 @@ GSDeviceOGL::~GSDeviceOGL()
|
||||||
delete m_vs_cb;
|
delete m_vs_cb;
|
||||||
delete m_ps_cb;
|
delete m_ps_cb;
|
||||||
glDeleteSamplers(1, &m_palette_ss);
|
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();
|
m_ps.clear();
|
||||||
|
|
||||||
|
@ -744,7 +728,6 @@ void GSDeviceOGL::SelfShaderTest()
|
||||||
GLuint p = CompilePS(sel); \
|
GLuint p = CompilePS(sel); \
|
||||||
nb_shader++; \
|
nb_shader++; \
|
||||||
perf += m_shader->DumpAsm(file, p); \
|
perf += m_shader->DumpAsm(file, p); \
|
||||||
m_shader->Delete(p); \
|
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
#define PRINT_TEST(s) \
|
#define PRINT_TEST(s) \
|
||||||
|
@ -1025,7 +1008,7 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
|
||||||
|
|
||||||
GSVector2i ds = dTex->GetSize();
|
GSVector2i ds = dTex->GetSize();
|
||||||
|
|
||||||
m_shader->Pipeline(m_convert.vs, 0, ps);
|
m_shader->BindPipeline(m_convert.vs, 0, ps);
|
||||||
|
|
||||||
// ************************************
|
// ************************************
|
||||||
// om
|
// om
|
||||||
|
@ -1263,7 +1246,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
|
||||||
|
|
||||||
ClearStencil(ds, 0);
|
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
|
// om
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,31 @@ GSShaderOGL::GSShaderOGL(bool debug) :
|
||||||
m_pipeline(0),
|
m_pipeline(0),
|
||||||
m_debug_shader(debug)
|
m_debug_shader(debug)
|
||||||
{
|
{
|
||||||
glCreateProgramPipelines(1, &m_pipeline);
|
// Create a default pipeline
|
||||||
glBindProgramPipeline(m_pipeline);
|
m_pipeline = LinkPipeline(0, 0, 0);
|
||||||
|
BindPipeline(m_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSShaderOGL::~GSShaderOGL()
|
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)
|
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)
|
bool GSShaderOGL::ValidateProgram(GLuint p)
|
||||||
{
|
{
|
||||||
if (!m_debug_shader) return true;
|
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%s", macro_sel.c_str());
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_prog_to_delete.push_back(program);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,8 +269,3 @@ int GSShaderOGL::DumpAsm(const std::string& file, GLuint p)
|
||||||
|
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSShaderOGL::Delete(GLuint s)
|
|
||||||
{
|
|
||||||
glDeleteProgram(s);
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ class GSShaderOGL {
|
||||||
GLuint m_pipeline;
|
GLuint m_pipeline;
|
||||||
const bool m_debug_shader;
|
const bool m_debug_shader;
|
||||||
|
|
||||||
|
std::vector<GLuint> m_prog_to_delete;
|
||||||
|
std::vector<GLuint> m_pipe_to_delete;
|
||||||
|
|
||||||
bool ValidateProgram(GLuint p);
|
bool ValidateProgram(GLuint p);
|
||||||
bool ValidatePipeline(GLuint p);
|
bool ValidatePipeline(GLuint p);
|
||||||
|
|
||||||
|
@ -34,11 +37,11 @@ class GSShaderOGL {
|
||||||
GSShaderOGL(bool debug);
|
GSShaderOGL(bool debug);
|
||||||
~GSShaderOGL();
|
~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 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);
|
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
|
// 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)
|
void GSDeviceOGL::SetupSampler(PSSamplerSelector ssel)
|
||||||
|
|
Loading…
Reference in New Issue