gsdx-ogl: GL_ARB_separate_shader_objects is now mandatory

This commit is contained in:
Gregory Hainaut 2016-04-07 22:11:35 +02:00
parent f751f70b1e
commit 52e3c3516d
8 changed files with 22 additions and 161 deletions

View File

@ -41,15 +41,11 @@ PFNGLCLEARBUFFERFVPROC glClearBufferfv = NUL
PFNGLCLEARBUFFERIVPROC glClearBufferiv = NULL;
PFNGLCLEARBUFFERUIVPROC glClearBufferuiv = NULL;
PFNGLCOLORMASKIPROC glColorMaski = NULL;
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
PFNGLCREATESHADERPROC glCreateShader = NULL;
PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv = NULL;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL;
PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
PFNGLDELETESAMPLERSPROC glDeleteSamplers = NULL;
PFNGLDELETESHADERPROC glDeleteShader = NULL;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
PFNGLDETACHSHADERPROC glDetachShader = NULL;
PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL;
@ -69,7 +65,6 @@ PFNGLGETPROGRAMIVPROC glGetProgramiv = NUL
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
PFNGLGETSTRINGIPROC glGetStringi = NULL;
PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL;
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
PFNGLMAPBUFFERPROC glMapBuffer = NULL;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL;
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = NULL;
@ -111,10 +106,6 @@ PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf = NUL
PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv = NULL;
PFNGLSCISSORINDEXEDPROC glScissorIndexed = NULL;
PFNGLSCISSORINDEXEDVPROC glScissorIndexedv = NULL;
// NO GL4.1
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = NULL;
// GL4.3
PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData = NULL;
PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage = NULL;
@ -350,7 +341,7 @@ namespace GLLoader {
bool found_GL_ARB_texture_barrier = false;
bool found_GL_ARB_clip_control = false;
bool found_GL_ARB_direct_state_access = false;
bool found_GL_ARB_separate_shader_objects = false; // Issue with Catalyst...
bool found_GL_ARB_separate_shader_objects = false;
bool found_GL_ARB_buffer_storage = false;
// DX11 GPU
bool found_GL_ARB_draw_buffers_blend = false; // Not supported on AMD R600 (80 nm class chip, HD2900). Nvidia requires FERMI. Intel SB
@ -448,15 +439,7 @@ namespace GLLoader {
if (ext.compare("GL_ARB_draw_buffers_blend") == 0) found_GL_ARB_draw_buffers_blend = true;
// GL4.1
if (ext.compare("GL_ARB_viewport_array") == 0) found_GL_ARB_viewport_array = true;
if (ext.compare("GL_ARB_separate_shader_objects") == 0) {
if (!fglrx_buggy_driver && !mesa_amd_buggy_driver && !intel_buggy_driver) found_GL_ARB_separate_shader_objects = true;
else fprintf(stderr, "Buggy driver detected, GL_ARB_separate_shader_objects will be disabled\n"
#ifdef __linux__
"Note the extension will be fixed on Mesa 11.2 or 11.1.2.\n"
#endif
"AMD proprietary driver => https://community.amd.com/thread/194895\n"
"If you want to try it, you can set the variable override_GL_ARB_separate_shader_objects to 1 in the ini file\n");
}
if (ext.compare("GL_ARB_separate_shader_objects") == 0) found_GL_ARB_separate_shader_objects = true;
// GL4.2
if (ext.compare("GL_ARB_shading_language_420pack") == 0) found_GL_ARB_shading_language_420pack = true;
if (ext.compare("GL_ARB_texture_storage") == 0) found_GL_ARB_texture_storage = true;
@ -484,7 +467,7 @@ namespace GLLoader {
status &= status_and_override(found_GL_ARB_draw_buffers_blend, "GL_ARB_draw_buffers_blend");
// GL4.1
status &= status_and_override(found_GL_ARB_viewport_array, "GL_ARB_viewport_array");
status &= status_and_override(found_GL_ARB_separate_shader_objects, "GL_ARB_separate_shader_objects");
status &= status_and_override(found_GL_ARB_separate_shader_objects, "GL_ARB_separate_shader_objects", true);
// GL4.2
status &= status_and_override(found_GL_ARB_shader_image_load_store, "GL_ARB_shader_image_load_store");
status &= status_and_override(found_GL_ARB_shading_language_420pack, "GL_ARB_shading_language_420pack", true);

View File

@ -215,16 +215,12 @@ extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLCLEARBUFFERFVPROC glClearBufferfv;
extern PFNGLCLEARBUFFERIVPROC glClearBufferiv;
extern PFNGLCLEARBUFFERUIVPROC glClearBufferuiv;
extern PFNGLCOMPILESHADERPROC glCompileShader;
extern PFNGLCOLORMASKIPROC glColorMaski;
extern PFNGLCREATEPROGRAMPROC glCreateProgram;
extern PFNGLCREATESHADERPROC glCreateShader;
extern PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv;
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
extern PFNGLDELETESAMPLERSPROC glDeleteSamplers;
extern PFNGLDELETESHADERPROC glDeleteShader;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLDETACHSHADERPROC glDetachShader;
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
@ -244,7 +240,6 @@ extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
extern PFNGLGETSHADERIVPROC glGetShaderiv;
extern PFNGLGETSTRINGIPROC glGetStringi;
extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
extern PFNGLLINKPROGRAMPROC glLinkProgram;
extern PFNGLMAPBUFFERPROC glMapBuffer;
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
extern PFNGLPROGRAMPARAMETERIPROC glProgramParameteri;
@ -286,10 +281,6 @@ extern PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf;
extern PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv;
extern PFNGLSCISSORINDEXEDPROC glScissorIndexed;
extern PFNGLSCISSORINDEXEDVPROC glScissorIndexedv;
// NO GL4.1
extern PFNGLUSEPROGRAMPROC glUseProgram;
extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
// GL4.2
extern PFNGLBINDIMAGETEXTUREPROC glBindImageTexture;
extern PFNGLMEMORYBARRIERPROC glMemoryBarrier;
@ -356,7 +347,6 @@ namespace GLLoader {
extern bool in_replayer;
// GL
extern bool found_GL_ARB_separate_shader_objects;
extern bool found_GL_ARB_copy_image;
extern bool found_geometry_shader;
extern bool found_GL_ARB_gpu_shader5;

View File

@ -54,8 +54,6 @@ namespace GLState {
GLuint ps;
GLuint gs;
GLuint vs;
GLuint program;
bool dirty_prog;
void Clear() {
fbo = 0;
@ -91,7 +89,5 @@ namespace GLState {
ps = 0;
gs = 0;
vs = 0;
program = 0;
dirty_prog = true;
}
}

View File

@ -56,8 +56,6 @@ namespace GLState {
extern GLuint ps;
extern GLuint gs;
extern GLuint vs;
extern GLuint program; // monolith program (when sso isn't supported)
extern bool dirty_prog;
extern void Clear();
}

View File

@ -448,7 +448,6 @@ void GSDeviceOGL::Flip()
void GSDeviceOGL::BeforeDraw()
{
m_shader->UseProgram();
}
void GSDeviceOGL::AfterDraw()

View File

@ -28,16 +28,13 @@ GSShaderOGL::GSShaderOGL(bool debug) :
m_debug_shader(debug)
{
m_single_prog.clear();
if (GLLoader::found_GL_ARB_separate_shader_objects) {
glGenProgramPipelines(1, &m_pipeline);
glBindProgramPipeline(m_pipeline);
}
glGenProgramPipelines(1, &m_pipeline);
glBindProgramPipeline(m_pipeline);
}
GSShaderOGL::~GSShaderOGL()
{
if (GLLoader::found_GL_ARB_separate_shader_objects)
glDeleteProgramPipelines(1, &m_pipeline);
glDeleteProgramPipelines(1, &m_pipeline);
for (auto it = m_single_prog.begin(); it != m_single_prog.end() ; it++) glDeleteProgram(it->second);
m_single_prog.clear();
@ -48,9 +45,7 @@ void GSShaderOGL::VS(GLuint s)
if (GLState::vs != s)
{
GLState::vs = s;
GLState::dirty_prog = true;
if (GLLoader::found_GL_ARB_separate_shader_objects)
glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, s);
glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, s);
}
}
@ -64,10 +59,7 @@ void GSShaderOGL::PS(GLuint s)
{
// In debug always sets the program. It allow to replace the program in apitrace easily.
GLState::ps = s;
GLState::dirty_prog = true;
if (GLLoader::found_GL_ARB_separate_shader_objects) {
glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, s);
}
glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, s);
}
}
@ -76,33 +68,10 @@ void GSShaderOGL::GS(GLuint s)
if (GLState::gs != s)
{
GLState::gs = s;
GLState::dirty_prog = true;
if (GLLoader::found_GL_ARB_separate_shader_objects)
glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, s);
glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, s);
}
}
bool GSShaderOGL::ValidateShader(GLuint s)
{
if (!m_debug_shader) return true;
GLint status = 0;
glGetShaderiv(s, GL_COMPILE_STATUS, &status);
if (status) return true;
GLint log_length = 0;
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0) {
char* log = new char[log_length];
glGetShaderInfoLog(s, log_length, NULL, log);
fprintf(stderr, "%s", log);
delete[] log;
}
fprintf(stderr, "\n");
return false;
}
bool GSShaderOGL::ValidateProgram(GLuint p)
{
if (!m_debug_shader) return true;
@ -148,62 +117,14 @@ bool GSShaderOGL::ValidatePipeline(GLuint p)
return false;
}
GLuint GSShaderOGL::LinkNewProgram()
{
GLuint p = glCreateProgram();
if (GLState::vs) glAttachShader(p, GLState::vs);
if (GLState::ps) glAttachShader(p, GLState::ps);
if (GLState::gs) glAttachShader(p, GLState::gs);
glLinkProgram(p);
ValidateProgram(p);
return p;
}
void GSShaderOGL::UseProgram()
{
if (GLState::dirty_prog) {
if (!GLLoader::found_GL_ARB_separate_shader_objects) {
hash_map<uint64, GLuint >::iterator it;
// Note: shader are integer lookup pointer. They start from 1 and incr
// every time you create a new shader OR a new program.
// Note2: vs & gs are precompiled at startup. FGLRX and radeon got value < 128. GS has only 2 programs
// We migth be able to pack the value in a 32bits int
// I would need to check the behavior on Nvidia (pause/resume).
uint64 sel = (uint64)GLState::vs << 40 | (uint64)GLState::gs << 20 | GLState::ps;
it = m_single_prog.find(sel);
if (it == m_single_prog.end()) {
GLState::program = LinkNewProgram();
m_single_prog[sel] = GLState::program;
ValidateProgram(GLState::program);
glUseProgram(GLState::program);
} else {
GLuint prog = it->second;
if (prog != GLState::program) {
GLState::program = prog;
glUseProgram(GLState::program);
}
}
}
}
GLState::dirty_prog = false;
}
std::string GSShaderOGL::GenGlslHeader(const std::string& entry, GLenum type, const std::string& macro)
{
std::string header;
header = "#version 330 core\n";
// Need GL version 420
header += "#extension GL_ARB_shading_language_420pack: require\n";
if (GLLoader::found_GL_ARB_separate_shader_objects) {
// Need GL version 410
header += "#extension GL_ARB_separate_shader_objects: require\n";
}
// Need GL version 410
header += "#extension GL_ARB_separate_shader_objects: require\n";
if (GLLoader::found_GL_ARB_shader_image_load_store) {
// Need GL version 420
header += "#extension GL_ARB_shader_image_load_store: require\n";
@ -263,19 +184,9 @@ GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& ent
sources[0] = header.append(glsl_h_code).c_str();
#endif
if (GLLoader::found_GL_ARB_separate_shader_objects) {
program = glCreateShaderProgramv(type, shader_nb, sources);
} else {
program = glCreateShader(type);
glShaderSource(program, shader_nb, sources, NULL);
glCompileShader(program);
}
program = glCreateShaderProgramv(type, shader_nb, sources);
bool status;
if (GLLoader::found_GL_ARB_separate_shader_objects)
status = ValidateProgram(program);
else
status = ValidateShader(program);
bool status = ValidateProgram(program);
if (!status) {
// print extra info
@ -347,9 +258,5 @@ int GSShaderOGL::DumpAsm(const std::string& file, GLuint p)
void GSShaderOGL::Delete(GLuint s)
{
if (GLLoader::found_GL_ARB_separate_shader_objects) {
glDeleteProgram(s);
} else {
glDeleteShader(s);
}
glDeleteProgram(s);
}

View File

@ -26,12 +26,10 @@ class GSShaderOGL {
hash_map<uint64, GLuint > m_single_prog;
const bool m_debug_shader;
bool ValidateShader(GLuint p);
bool ValidateProgram(GLuint p);
bool ValidatePipeline(GLuint p);
std::string GenGlslHeader(const std::string& entry, GLenum type, const std::string& macro);
GLuint LinkNewProgram();
public:
GSShaderOGL(bool debug);
@ -41,8 +39,6 @@ class GSShaderOGL {
void PS(GLuint s);
void VS(GLuint s);
void UseProgram();
GLuint Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel = "");
int DumpAsm(const std::string& file, GLuint p);

View File

@ -100,15 +100,14 @@ void GSWndGL::PopulateGlFunction()
GL_EXT_LOAD_OPT(glBlendEquationSeparateiARB);
GL_EXT_LOAD_OPT(glBlendFuncSeparateiARB);
// GL4.1
GL_EXT_LOAD_OPT(glCreateShaderProgramv);
GL_EXT_LOAD_OPT(glBindProgramPipeline);
GL_EXT_LOAD_OPT(glDeleteProgramPipelines);
GL_EXT_LOAD_OPT(glGenProgramPipelines);
GL_EXT_LOAD_OPT(glGetProgramPipelineiv);
GL_EXT_LOAD_OPT(glGetProgramPipelineInfoLog);
GL_EXT_LOAD_OPT(glValidateProgramPipeline);
GL_EXT_LOAD_OPT(glUseProgramStages);
GL_EXT_LOAD_OPT(glProgramUniform1i); // but no GL4.2
GL_EXT_LOAD(glCreateShaderProgramv);
GL_EXT_LOAD(glBindProgramPipeline);
GL_EXT_LOAD(glDeleteProgramPipelines);
GL_EXT_LOAD(glGenProgramPipelines);
GL_EXT_LOAD(glGetProgramPipelineiv);
GL_EXT_LOAD(glGetProgramPipelineInfoLog);
GL_EXT_LOAD(glValidateProgramPipeline);
GL_EXT_LOAD(glUseProgramStages);
GL_EXT_LOAD_OPT(glGetProgramBinary);
GL_EXT_LOAD_OPT(glViewportIndexedf);
GL_EXT_LOAD_OPT(glViewportIndexedfv);
@ -116,13 +115,6 @@ void GSWndGL::PopulateGlFunction()
GL_EXT_LOAD_OPT(glScissorIndexedv);
// NO GL4.1
GL_EXT_LOAD(glDeleteProgram);
GL_EXT_LOAD(glDeleteShader);
GL_EXT_LOAD(glCompileShader);
GL_EXT_LOAD(glCreateProgram);
GL_EXT_LOAD(glCreateShader);
GL_EXT_LOAD(glUseProgram);
GL_EXT_LOAD(glGetShaderInfoLog);
GL_EXT_LOAD(glLinkProgram);
// GL4.2
GL_EXT_LOAD_OPT(glBindImageTexture);
GL_EXT_LOAD_OPT(glMemoryBarrier);