diff --git a/plugins/GSdx/GLLoader.cpp b/plugins/GSdx/GLLoader.cpp index 32b2155c2c..810507c8ab 100644 --- a/plugins/GSdx/GLLoader.cpp +++ b/plugins/GSdx/GLLoader.cpp @@ -103,6 +103,7 @@ namespace GLLoader { bool found_geometry_shader = true; bool found_GL_NV_copy_image = false; bool found_GL_ARB_copy_image = false; + bool found_only_gl30 = false; bool check_gl_version(uint32 major, uint32 minor) { @@ -129,6 +130,10 @@ namespace GLLoader { found_geometry_shader = !!theApp.GetConfig("override_geometry_shader", -1); fprintf(stderr, "Override geometry shaders detection\n"); } + if ( (major_gl == 3) && minor_gl < 3) { + // Opensource driver spotted + found_only_gl30 = true; + } if ( (major_gl < major) || ( major_gl == major && minor_gl < minor ) ) { fprintf(stderr, "OPENGL %d.%d is not supported\n", major, minor); @@ -263,6 +268,13 @@ namespace GLLoader { found_GL_ARB_separate_shader_objects = !!theApp.GetConfig("override_GL_ARB_separate_shader_objects", -1); fprintf(stderr, "Override GL_ARB_separate_shader_objects detection\n"); } + if (theApp.GetConfig("ovveride_GL_ARB_copy_image", -1) != -1) { + // Same extension so override both + found_GL_ARB_copy_image = !!theApp.GetConfig("override_GL_ARB_copy_image", -1); + found_GL_NV_copy_image = !!theApp.GetConfig("override_GL_ARB_copy_image", -1); + fprintf(stderr, "Override GL_ARB_copy_image detection\n"); + fprintf(stderr, "Override GL_NV_copy_image detection\n"); + } return true; } diff --git a/plugins/GSdx/GLLoader.h b/plugins/GSdx/GLLoader.h index 83e315d0fa..c241b8e552 100644 --- a/plugins/GSdx/GLLoader.h +++ b/plugins/GSdx/GLLoader.h @@ -133,4 +133,5 @@ namespace GLLoader { extern bool found_GL_NV_copy_image; extern bool found_geometry_shader; extern bool fglrx_buggy_driver; + extern bool found_only_gl30; } diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 457b679028..3c6cbbf1c7 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -181,11 +181,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) if (m_window == NULL) { GLLoader::init_gl_function(); -#ifdef OGL_FREE_DRIVER if (!GLLoader::check_gl_version(3, 0)) return false; -#else - if (!GLLoader::check_gl_version(3, 3)) return false; -#endif if (!GLLoader::check_gl_supported_extension()) return false; } @@ -884,7 +880,17 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r) r.width(), r.height(), 1); #endif } else { - // FIXME fallback for open source driver + + GSTextureOGL* st_ogl = (GSTextureOGL*) st; + GSTextureOGL* dt_ogl = (GSTextureOGL*) dt; + + gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read); + + st_ogl->AttachRead(GL_COLOR_ATTACHMENT0); + dt_ogl->EnableUnit(0); + glCopyTexSubImage2D(dt_ogl->GetTarget(), 0, r.x, r.y, r.x, r.y, r.width(), r.height()); + + gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); } #if 0 @@ -1346,11 +1352,12 @@ 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 OGL_FREE_DRIVER - std::string version = "#version 130\n"; -#else - std::string version = "#version 330\n"; -#endif + std::string version; + if (GLLoader::found_only_gl30) { + version = "#version 130\n"; + } else { + version = "#version 330\n"; + } if (GLLoader::found_GL_ARB_shading_language_420pack) { version += "#extension GL_ARB_shading_language_420pack: require\n"; } else { @@ -1363,14 +1370,13 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st // version += "#define NO_STRUCT 1\n"; //} } else { -#ifdef OGL_FREE_DRIVER - version += "#define DISABLE_SSO\n"; -#endif + if (GLLoader::found_only_gl30) + version += "#define DISABLE_SSO\n"; + } + if (GLLoader::found_only_gl30) { + version += "#extension GL_ARB_explicit_attrib_location : require\n"; + version += "#extension GL_ARB_uniform_buffer_object : require\n"; } -#ifdef OGL_FREE_DRIVER - version += "#extension GL_ARB_explicit_attrib_location : require\n"; - version += "#extension GL_ARB_uniform_buffer_object : require\n"; -#endif // Allow to puts several shader in 1 files std::string shader_type; diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index 019751a6fa..918682a8a0 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -149,6 +149,12 @@ void GSTextureOGL::Attach(GLenum attachment) //fprintf(stderr, "FB status %x\n", gl_CheckFramebufferStatus(GL_FRAMEBUFFER)); } +void GSTextureOGL::AttachRead(GLenum attachment) +{ + gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0); + glReadBuffer(attachment); +} + bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch) { if (m_type == GSTexture::DepthStencil || m_type == GSTexture::Offscreen) ASSERT(0); diff --git a/plugins/GSdx/GSTextureOGL.h b/plugins/GSdx/GSTextureOGL.h index cf13dd60db..4a235b2ffc 100644 --- a/plugins/GSdx/GSTextureOGL.h +++ b/plugins/GSdx/GSTextureOGL.h @@ -44,6 +44,7 @@ class GSTextureOGL : public GSTexture void EnableUnit(uint32 unit); void Attach(GLenum attachment); + void AttachRead(GLenum attachment); bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); } bool IsDss() { return (m_type == GSTexture::DepthStencil); } diff --git a/plugins/GSdx/config.h b/plugins/GSdx/config.h index 3794cf7119..727931513d 100644 --- a/plugins/GSdx/config.h +++ b/plugins/GSdx/config.h @@ -41,6 +41,5 @@ #define ENABLE_OGL_DEBUG // Create a debug context and check opengl command status. Allow also to dump various textures/states. #endif -#ifdef EGL_API -#define OGL_FREE_DRIVER -#endif +// Allow to create only a 3.0 context for opensource driver +//#define OGL_FREE_DRIVER