From a163677cece081a713e560ece2cb9eb8370251f9 Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Fri, 17 May 2013 18:28:51 +0000 Subject: [PATCH] gsdx ogl: New config option to disable separate shader program. Not enabled by default * workaround AMD driver bleding issue (got at least a nice rendering in GoW) * would run on the opensource driver when they support geometry shader Stil got some crash on the driver. Arg!!! FGLRX user if you want to do some trials uncomment #define DISABLE_GL41_SSO in GSdx/config.h git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5630 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSDeviceOGL.cpp | 76 +++++++++++++++++++++++++++++++++++- plugins/GSdx/GSDeviceOGL.h | 6 +++ plugins/GSdx/config.h | 4 ++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 39a3463c50..17aafb5121 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -611,12 +611,56 @@ static void set_uniform_buffer_binding(GLuint prog, GLchar* name, GLuint binding } #endif +#ifdef DISABLE_GL41_SSO +GLuint GSDeviceOGL::link_prog() +{ + GLuint single_prog = glCreateProgram(); + if (m_state.vs) glAttachShader(single_prog, m_state.vs); + if (m_state.ps) glAttachShader(single_prog, m_state.ps); + if (m_state.gs) glAttachShader(single_prog, m_state.gs); + + glLinkProgram(single_prog); + + GLint status; + glGetProgramiv(single_prog, GL_LINK_STATUS, &status); + if (!status) { + GLint log_length = 0; + glGetProgramiv(single_prog, GL_INFO_LOG_LENGTH, &log_length); + if (log_length > 0) { + char* log = new char[log_length]; + glGetProgramInfoLog(single_prog, log_length, NULL, log); + fprintf(stderr, "%s", log); + delete[] log; + } + fprintf(stderr, "\n"); + } + + if (m_state.vs) glDetachShader(single_prog, m_state.vs); + if (m_state.ps) glDetachShader(single_prog, m_state.ps); + if (m_state.gs) glDetachShader(single_prog, m_state.gs); + + return single_prog; +} +#endif + void GSDeviceOGL::BeforeDraw() { #ifdef OGL_DEBUG DebugInput(); #endif +#ifdef DISABLE_GL41_SSO + uint32 sel = m_state.vs << 24 | m_state.gs << 30 | m_state.ps; + auto single_prog = m_single_prog.find(sel); + if (single_prog == m_single_prog.end()) { + m_single_prog[sel] = link_prog(); + single_prog = m_single_prog.find(sel); + } + + glUseProgram(single_prog->second); + +#endif + #ifdef DISABLE_GL42 set_uniform_buffer_binding(m_state.vs, "cb20", 20); set_uniform_buffer_binding(m_state.ps, "cb21", 21); @@ -1104,7 +1148,9 @@ void GSDeviceOGL::VSSetShader(GLuint vs) if(m_state.vs != vs) { m_state.vs = vs; +#ifndef DISABLE_GL41_SSO glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, vs); +#endif } } @@ -1113,7 +1159,9 @@ void GSDeviceOGL::GSSetShader(GLuint gs) if(m_state.gs != gs) { m_state.gs = gs; +#ifndef DISABLE_GL41_SSO glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, gs); +#endif } } @@ -1154,7 +1202,9 @@ void GSDeviceOGL::PSSetShader(GLuint ps) if(m_state.ps != ps) { m_state.ps = ps; +#ifndef DISABLE_GL41_SSO glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, ps); +#endif } // Sampler and texture must be set at the same time @@ -1268,10 +1318,18 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st // Build a header string // ***************************************************** // First select the version (must be the first line so we need to generate it -#ifdef DISABLE_GL42 - std::string version = "#version 330\n#extension GL_ARB_separate_shader_objects : require\n#define DISABLE_GL42\n"; +#ifdef DISABLE_GL41_SSO + #ifdef DISABLE_GL42 + std::string version = "#version 330\n#define DISABLE_GL42\n"; + #else + std::string version = "#version 330\n#extension GL_ARB_shading_language_420pack: require\n"; + #endif #else + #ifdef DISABLE_GL42 + std::string version = "#version 330\n#extension GL_ARB_separate_shader_objects : require\n#define DISABLE_GL42\n"; + #else std::string version = "#version 330\n#extension GL_ARB_shading_language_420pack: require\n#extension GL_ARB_separate_shader_objects : require\n"; + #endif #endif //std::string version = "#version 420\n"; @@ -1338,6 +1396,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st header.copy(header_str, header.size(), 0); header_str[header.size()] = '\0'; +#ifndef DISABLE_GL41_SSO #if 0 // Could be useful one day const GLchar* ShaderSource[1]; @@ -1346,6 +1405,11 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st #else *program = glCreateShaderProgramv(type, 2, sources_array); #endif +#else + *program = glCreateShader(type); + glShaderSource(*program, 2, sources_array, NULL); + glCompileShader(*program); +#endif free(source_str); free(header_str); @@ -1357,10 +1421,18 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st fprintf(stderr, "\n%s", macro_sel.c_str()); GLint log_length = 0; +#ifndef DISABLE_GL41_SSO glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length); +#else + glGetShaderiv(*program, GL_INFO_LOG_LENGTH, &log_length); +#endif if (log_length > 0) { char* log = new char[log_length]; +#ifndef DISABLE_GL41_SSO glGetProgramInfoLog(*program, log_length, NULL, log); +#else + glGetShaderInfoLog(*program, log_length, NULL, log); +#endif fprintf(stderr, "%s", log); delete[] log; } diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index ad18b5624c..f17aa7acf3 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -656,4 +656,10 @@ class GSDeviceOGL : public GSDevice void SetupGS(GSSelector sel); void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); + +#ifdef DISABLE_GL41_SSO + hash_map m_single_prog; + GLuint link_prog(); +#endif + }; diff --git a/plugins/GSdx/config.h b/plugins/GSdx/config.h index 80c47392b9..de278d120e 100644 --- a/plugins/GSdx/config.h +++ b/plugins/GSdx/config.h @@ -36,4 +36,8 @@ //#define DISABLE_DATE +// Set manually uniform buffer index //#define DISABLE_GL42 + +// Debug: use single program for all shaders. +//#define DISABLE_GL41_SSO