From a9927a6e33bcf408b63e8f8ea57aa2e87633003a Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Wed, 21 Dec 2011 23:09:36 +0000 Subject: [PATCH] gsdx-ogl: LINUX-ONLY * rework a little the shader to be hopefully compatible with nvidia * request a pure 4.2 context (all gpu 4.1 capable support 4.2 anyway) git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5003 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/CMakeLists.txt | 1 + plugins/GSdx/GSDeviceOGL.cpp | 54 ++++++++++++++--------- plugins/GSdx/GSTexture.h | 2 +- plugins/GSdx/GSTextureOGL.cpp | 14 +----- plugins/GSdx/GSTextureOGL.h | 2 + plugins/GSdx/GSWnd.cpp | 2 +- plugins/GSdx/res/tfx.glsl | 81 +++++++++++++---------------------- 7 files changed, 68 insertions(+), 88 deletions(-) diff --git a/plugins/GSdx/CMakeLists.txt b/plugins/GSdx/CMakeLists.txt index 3208a45ff0..18694b7f40 100644 --- a/plugins/GSdx/CMakeLists.txt +++ b/plugins/GSdx/CMakeLists.txt @@ -206,5 +206,6 @@ else(PACKAGE_MODE) install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) + install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/tfx.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) endif(PACKAGE_MODE) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index c683aed0b7..690c5a8039 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -170,12 +170,26 @@ bool GSDeviceOGL::Create(GSWnd* wnd) fprintf(stderr, "Error: Failed to init glew :%s\n", glewGetErrorString(glew_ok)); return false; } - // FIXME upgrade to 4.2 when AMD drivers are ready - // Note need glew 1.7 too - if (!GLEW_VERSION_4_1) { - fprintf(stderr, "4.1 is not supported!\n"); - return false; - } + // Note: don't rely on glew to avoid to pull glew1.7 + // Instead we just copy/adapt the 10 lines of code + // if (!GLEW_VERSION_4_2) { + // fprintf(stderr, "4.2 is not supported!\n"); + // return false; + // } + const GLubyte* s; + s = glGetString(GL_VERSION); + if (s == NULL) return false; + + GLuint dot; + while (s[dot] != '\0' && s[dot] != '.') dot++; + if (dot == 0) return false; + + GLuint major = s[dot-1]-'0'; + GLuint minor = s[dot+1]-'0'; + if ( (major < 4) || ( major == 4 && minor < 2 ) ) return false; + + + } // FIXME disable it when code is ready @@ -465,7 +479,7 @@ bool GSDeviceOGL::Reset(int w, int h) // Opengl allocate the backbuffer with the window. The render is done in the backbuffer when // there isn't any FBO. Only a dummy texture is created to easily detect when the rendering is done // in the backbuffer - m_backbuffer = new GSTextureOGL(0, w, h, false, 0); + m_backbuffer = new GSTextureOGL(0, w, h, false, GSTextureOGL::Backbuffer); return true; } @@ -484,8 +498,7 @@ void GSDeviceOGL::DrawPrimitive() void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) { - GSTextureOGL* t_ogl = (GSTextureOGL*)t; - if (t == m_backbuffer) { + if (static_cast(t)->IsBackbuffer()) { // FIXME I really not sure OMSetFBO(0); //glClearBufferfv(GL_COLOR, GL_LEFT, c.v); @@ -497,7 +510,7 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) // FIXME I need to clarify this FBO attachment stuff // I would like to avoid FBO for a basic clean operation OMSetFBO(m_fbo); - t_ogl->Attach(GL_COLOR_ATTACHMENT0); + static_cast(t)->Attach(GL_COLOR_ATTACHMENT0); glClearBufferfv(GL_COLOR, 0, c.v); } } @@ -544,6 +557,7 @@ GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w { // I'm not sure about the object type for offscreen buffer // TODO later; + assert(0); // Need to find format equivalent. Then I think it will be straight forward @@ -680,7 +694,7 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, // 2/ in case some GSdx code expect thing in dx order. // Only flipping the backbuffer is transparent (I hope)... GSVector4 flip_sr = sr; - if (dt == m_backbuffer) { + if (static_cast(dt)->IsBackbuffer()) { flip_sr.y = 1.0f - sr.y; flip_sr.w = 1.0f - sr.w; } @@ -1073,20 +1087,17 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto m_ctx->OMSetRenderTargets(1, &rtv, dsv); } #endif - GSTextureOGL* rt_ogl = (GSTextureOGL*)rt; - GSTextureOGL* ds_ogl = (GSTextureOGL*)ds; - - if (m_backbuffer == rt_ogl) { + if (static_cast(rt)->IsBackbuffer()) { OMSetFBO(0); - assert(ds_ogl == NULL); // no depth-stencil without FBO + assert(ds == NULL); // no depth-stencil without FBO } else { OMSetFBO(m_fbo); - assert(rt_ogl != NULL); // a render target must exists - rt_ogl->Attach(GL_COLOR_ATTACHMENT0); - if (ds_ogl != NULL) - ds_ogl->Attach(GL_DEPTH_STENCIL_ATTACHMENT); + assert(rt != NULL); // a render target must exists + static_cast(rt)->Attach(GL_COLOR_ATTACHMENT0); + if (ds != NULL) + static_cast(ds)->Attach(GL_DEPTH_STENCIL_ATTACHMENT); } // Viewport -> glViewport @@ -1115,7 +1126,8 @@ 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 - std::string version = "#version 410\n#extension GL_ARB_shading_language_420pack: enable\n"; + //std::string version = "#version 410\n#extension GL_ARB_shading_language_420pack: enable\n"; + std::string version = "#version 420\n"; // Allow to puts several shader in 1 files std::string shader_type; diff --git a/plugins/GSdx/GSTexture.h b/plugins/GSdx/GSTexture.h index 43ac3f6bfa..cd779c4c8c 100644 --- a/plugins/GSdx/GSTexture.h +++ b/plugins/GSdx/GSTexture.h @@ -35,7 +35,7 @@ protected: public: struct GSMap {uint8* bits; int pitch;}; - enum {RenderTarget = 1, DepthStencil, Texture, Offscreen}; + enum {RenderTarget = 1, DepthStencil, Texture, Offscreen, Backbuffer}; public: GSTexture(); diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index e99b555a80..1f398f638d 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -58,26 +58,14 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format) // glReadBuffer // glBlitFramebuffer + // TODO: we can render directly into a texture so I'm not sure rendertarget are useful anymore !!! // ************************************************************* - // Doc - // It might need a texture structure to replace ID3D11Texture2D. - // - // == The function need to set (from parameter) - // : m_size.x - // : m_size.y - // : m_type - // : m_format - // : m_msaa m_size.x = w; m_size.y = h; m_format = format; m_type = type; m_msaa = msaa; - // == Might be useful to save - // : m_texture_target (like GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE etc...) - // : m_texture_id (return by glGen*) - // // == Then generate the texture or buffer. // D3D11_BIND_RENDER_TARGET: Bind a texture as a render target for the output-merger stage. // => glGenRenderbuffers with GL_COLOR_ATTACHMENTi (Hum glGenTextures might work too) diff --git a/plugins/GSdx/GSTextureOGL.h b/plugins/GSdx/GSTextureOGL.h index 4e55225048..ba9f3bab53 100644 --- a/plugins/GSdx/GSTextureOGL.h +++ b/plugins/GSdx/GSTextureOGL.h @@ -43,4 +43,6 @@ class GSTextureOGL : public GSTexture void EnableUnit(uint unit); void Attach(GLenum attachment); + + bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); } }; diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index 2b10f67825..3ef9cf3c2b 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -370,7 +370,7 @@ bool GSWnd::Attach(void* handle, bool managed) int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 4, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_MINOR_VERSION_ARB, 2, // FIXME : Request a debug context to ease opengl development // Note: don't support deprecated feature (pre openg 3.1) GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, diff --git a/plugins/GSdx/res/tfx.glsl b/plugins/GSdx/res/tfx.glsl index 600444594a..11f50b8b98 100644 --- a/plugins/GSdx/res/tfx.glsl +++ b/plugins/GSdx/res/tfx.glsl @@ -39,6 +39,14 @@ #define PS_DATE 0 #endif +struct vertex +{ + vec4 p; + vec4 t; + vec4 tp; + vec4 c; +}; + #ifdef VERTEX_SHADER layout(location = 0) in vec2 i_t; layout(location = 1) in vec4 i_c; @@ -47,13 +55,7 @@ layout(location = 3) in uvec2 i_p; layout(location = 4) in uint i_z; layout(location = 5) in vec4 i_f; -layout(location = 0) out VSout -{ - vec4 o_p; - vec4 o_t; - vec4 o_tp; - vec4 o_c; -}; +layout(location = 0) out vertex OUT; out gl_PerVertex { vec4 gl_Position; @@ -87,9 +89,9 @@ void vs_main() vec4 p = vec4(i_p, z, 0) - vec4(0.05f, 0.05f, 0, 0); - o_p = p * VertexScale - VertexOffset; + OUT.p = p * VertexScale - VertexOffset; #if VS_RTCOPY - o_tp = (p * VertexScale - VertexOffset) * vec4(0.5, -0.5, 0, 0) + 0.5; + OUT.tp = (p * VertexScale - VertexOffset) * vec4(0.5, -0.5, 0, 0) + 0.5; #endif gl_Position = p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position @@ -97,23 +99,23 @@ void vs_main() { if(VS_FST != 0) { - o_t.xy = i_t * TextureScale; - o_t.w = 1.0f; + OUT.t.xy = i_t * TextureScale; + OUT.t.w = 1.0f; } else { - o_t.xy = i_t; - o_t.w = i_q; + OUT.t.xy = i_t; + OUT.t.w = i_q; } } else { - o_t.xy = vec2(0.0f, 0.0f); - o_t.w = 1.0f; + OUT.t.xy = vec2(0.0f, 0.0f); + OUT.t.w = 1.0f; } - o_c = i_c; - o_t.z = i_f.a; + OUT.c = i_c; + OUT.t.z = i_f.a; } #endif @@ -131,21 +133,9 @@ out gl_PerVertex { float gl_ClipDistance[]; }; -layout(location = 0) in GSin -{ - vec4 p; - vec4 t; - vec4 tp; - vec4 c; -} GSin[]; +layout(location = 0) in vertex GSin[]; -layout(location = 0) out GSout -{ - vec4 p; - vec4 t; - vec4 tp; - vec4 c; -} GSout; +layout(location = 0) out vertex GSout; #if GS_PRIM == 0 layout(points) in; @@ -201,14 +191,6 @@ void gs_main() layout(lines) in; layout(triangle_strip, max_vertices = 4) out; -void set_output(uint i) -{ - GSout.p = GSin[i].p; - GSout.t = GSin[i].t; - GSout.tp = GSin[i].tp; - GSout.c = GSin[i].c; -} - void gs_main() { // left top => GSin[0]; @@ -216,7 +198,7 @@ void gs_main() // left top - set_output(0); + GSout = GSin[0]; GSout.p.z = GSin[1].p.z; GSout.t.zw = GSin[1].t.zw; @@ -227,7 +209,7 @@ void gs_main() EmitVertex(); // left bottom - set_output(1); + GSout = GSin[1]; gl_Position = gl_in[1].gl_Position; // FIXME is it useful gl_Position.x = GSin[0].p.x; GSout.p.x = GSin[0].p.x; @@ -235,7 +217,7 @@ void gs_main() EmitVertex(); // rigth top - set_output(1); + GSout = GSin[1]; gl_Position = gl_in[1].gl_Position; // FIXME is it useful gl_Position.y = GSin[0].p.y; GSout.p.y = GSin[0].p.y; @@ -243,7 +225,7 @@ void gs_main() EmitVertex(); // rigth bottom - set_output(1); + GSout = GSin[1]; gl_Position = GSin[1].p; // FIXME is it useful EmitVertex(); @@ -254,13 +236,7 @@ void gs_main() #endif #ifdef FRAGMENT_SHADER -layout(location = 0) in PSin -{ - vec4 p; - vec4 t; - vec4 tp; - vec4 c; -} PSin; +layout(location = 0) in vertex PSin; // Same buffer but 2 colors for dual source blending layout(location = 0, index = 0) out vec4 SV_Target0; @@ -401,7 +377,7 @@ vec4 sample_color(vec2 st, float q) } vec4 t; - if(PS_FMT <= FMT_16 && PS_WMS < 3 && PS_WMT < 3) + if((PS_FMT <= FMT_16) && (PS_WMS < 3) && (PS_WMT < 3)) { t = sample_c(clampuv(st)); } @@ -603,6 +579,8 @@ vec4 ps_color() { // FIXME !!!! //c.rgb *= c.rgb < 128./255; + bvec3 factor = bvec3(128.0f/255.0f, 128.0f/255.0f, 128.0f/255.0f); + c.rgb *= vec3(factor); } if(PS_CLR1 != 0) // needed for Cd * (As/Ad/F + 1) blending modes @@ -619,7 +597,6 @@ void ps_main() { vec4 c = ps_color(); - // FIXME: I'm not sure about the value of others field // output.c1 = c.a * 2; // used for alpha blending SV_Target1 = vec4(c.a*2, c.a*2, c.a*2, c.a * 2);