From 52e3c3516d5016ef93f466c981b0c2915fab6380 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Thu, 7 Apr 2016 22:11:35 +0200 Subject: [PATCH] gsdx-ogl: GL_ARB_separate_shader_objects is now mandatory --- plugins/GSdx/GLLoader.cpp | 23 +------ plugins/GSdx/GLLoader.h | 10 --- plugins/GSdx/GLState.cpp | 4 -- plugins/GSdx/GLState.h | 2 - plugins/GSdx/GSDeviceOGL.cpp | 1 - plugins/GSdx/GSShaderOGL.cpp | 115 ++++------------------------------- plugins/GSdx/GSShaderOGL.h | 4 -- plugins/GSdx/GSWnd.cpp | 24 +++----- 8 files changed, 22 insertions(+), 161 deletions(-) diff --git a/plugins/GSdx/GLLoader.cpp b/plugins/GSdx/GLLoader.cpp index 0de2826f02..674f079202 100644 --- a/plugins/GSdx/GLLoader.cpp +++ b/plugins/GSdx/GLLoader.cpp @@ -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); diff --git a/plugins/GSdx/GLLoader.h b/plugins/GSdx/GLLoader.h index fe3e9e5bd7..4e77e140c6 100644 --- a/plugins/GSdx/GLLoader.h +++ b/plugins/GSdx/GLLoader.h @@ -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; diff --git a/plugins/GSdx/GLState.cpp b/plugins/GSdx/GLState.cpp index 1ecdb4a41f..ccff52587b 100644 --- a/plugins/GSdx/GLState.cpp +++ b/plugins/GSdx/GLState.cpp @@ -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; } } diff --git a/plugins/GSdx/GLState.h b/plugins/GSdx/GLState.h index 18931d6cd2..14a98e5691 100644 --- a/plugins/GSdx/GLState.h +++ b/plugins/GSdx/GLState.h @@ -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(); } diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index bdc60a805b..e82195df04 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -448,7 +448,6 @@ void GSDeviceOGL::Flip() void GSDeviceOGL::BeforeDraw() { - m_shader->UseProgram(); } void GSDeviceOGL::AfterDraw() diff --git a/plugins/GSdx/GSShaderOGL.cpp b/plugins/GSdx/GSShaderOGL.cpp index 9fc6c31a7a..34494e1edc 100644 --- a/plugins/GSdx/GSShaderOGL.cpp +++ b/plugins/GSdx/GSShaderOGL.cpp @@ -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::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); } diff --git a/plugins/GSdx/GSShaderOGL.h b/plugins/GSdx/GSShaderOGL.h index ef00002208..376285bb11 100644 --- a/plugins/GSdx/GSShaderOGL.h +++ b/plugins/GSdx/GSShaderOGL.h @@ -26,12 +26,10 @@ class GSShaderOGL { hash_map 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); diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index 638f983626..be9552143d 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -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);