diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 06ae8ca7c6..6a7d8441ab 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -552,15 +552,11 @@ void GSDeviceOGL::CreateTextureFX() glBindSampler(1, m_palette_ss); // Pre compile the (remaining) Geometry & Vertex Shader - for (uint32 key = 0; key < countof(m_gs); key++) { - GSSelector sel(key); - if (!GLLoader::found_geometry_shader) - m_gs[key] = 0; - else if (sel.point == sel.sprite) // Invalid key - m_gs[key] = 0; - else - m_gs[key] = CompileGS(GSSelector(key)); - } + // One-Hot encoding + memset(m_gs, 0, sizeof(m_gs)); + m_gs[1] = CompileGS(GSSelector(1)); + m_gs[2] = CompileGS(GSSelector(2)); + m_gs[4] = CompileGS(GSSelector(4)); m_vs[0] = CompileVS(VSSelector(0)); @@ -913,7 +909,8 @@ GLuint GSDeviceOGL::CompileVS(VSSelector sel) /* Note: must be here because tfx_glsl is static */ GLuint GSDeviceOGL::CompileGS(GSSelector sel) { - std::string macro = format("#define GS_POINT %d\n", sel.point); + std::string macro = format("#define GS_POINT %d\n", sel.point) + + format("#define GS_LINE %d\n", sel.line); if (GLLoader::buggy_sso_dual_src) return m_shader->CompileShader("tfx_vgs.glsl", "gs_main", GL_GEOMETRY_SHADER, tfx_vgs_glsl, macro); diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 526d023325..bb3595083f 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -121,13 +121,13 @@ public: { GSVector4 Vertex_Scale_Offset; GSVector2i DepthMask; - GSVector2 TextureScale; + GSVector2 PointSize; VSConstantBuffer() { Vertex_Scale_Offset = GSVector4::zero(); DepthMask = GSVector2i(0, 0); - TextureScale = GSVector2(0, 0); + PointSize = GSVector2(0, 0); } __forceinline bool Update(const VSConstantBuffer* cb) @@ -173,8 +173,9 @@ public: { uint32 sprite:1; uint32 point:1; + uint32 line:1; - uint32 _free:30; + uint32 _free:29; }; uint32 key; @@ -458,7 +459,7 @@ public: } m_profiler; GLuint m_vs[1]; - GLuint m_gs[1<<2]; + GLuint m_gs[1<<3]; GLuint m_ps_ss[1<<4]; GSDepthStencilOGL* m_om_dss[1<<5]; hash_map m_ps; diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index a7c4128f52..5f25692472 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -39,6 +39,7 @@ GSRendererOGL::GSRendererOGL() UserHacks_TCO_y = ((UserHacks_TCOffset >> 16) & 0xFFFF) / -1000.0f; UserHacks_safe_fbmask = theApp.GetConfigB("UserHacks_safe_fbmask"); UserHacks_merge_sprite = theApp.GetConfigB("UserHacks_merge_pp_sprite"); + UserHacks_unscale_pt_ln = theApp.GetConfigB("UserHacks_unscale_point_line"); m_prim_overlap = PRIM_OVERLAP_UNKNOW; ResetStates(); @@ -49,6 +50,7 @@ GSRendererOGL::GSRendererOGL() UserHacks_TCO_y = 0; UserHacks_safe_fbmask = false; UserHacks_merge_sprite = false; + UserHacks_unscale_pt_ln = false; } } @@ -1317,16 +1319,13 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour // GS - -#if 0 - if (m_vt.m_primclass == GS_POINT_CLASS) { +#if 1 + if (UserHacks_unscale_pt_ln && m_vt.m_primclass == GS_POINT_CLASS) { // Upscaling point will create aliasing because point has a size of 0 pixels. // This code tries to replace point with sprite. So a point in 4x will be replaced by - // a 4x4 sprite. + // a 4x4 flat sprite. m_gs_sel.point = 1; - // FIXME this formula is potentially wrong - GSVector4 point_size = GSVector4(rtscale.x / rtsize.x, rtscale.y / rtsize.y) * 2.0f; - vs_cb.TextureScale = vs_cb.TextureScale.xyxy(point_size); + vs_cb.PointSize = GSVector2(2.0f * rtscale.x / rtsize.x, 2.0f * rtscale.y / rtsize.y); } #endif m_gs_sel.sprite = m_vt.m_primclass == GS_SPRITE_CLASS; diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index 84f0f730ed..618b61adb0 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -54,6 +54,7 @@ class GSRendererOGL final : public GSRendererHW float UserHacks_TCO_x, UserHacks_TCO_y; bool UserHacks_safe_fbmask; bool UserHacks_merge_sprite; + bool UserHacks_unscale_pt_ln; GSDeviceOGL::VSConstantBuffer vs_cb; GSDeviceOGL::PSConstantBuffer ps_cb; diff --git a/plugins/GSdx/GSdx.cpp b/plugins/GSdx/GSdx.cpp index 73a50d21a9..0008f7e942 100644 --- a/plugins/GSdx/GSdx.cpp +++ b/plugins/GSdx/GSdx.cpp @@ -342,6 +342,7 @@ void GSdxApp::Init() m_default_configuration["UserHacks_HalfPixelOffset"] = "0"; m_default_configuration["UserHacks_merge_pp_sprite"] = "0"; m_default_configuration["UserHacks_MSAA"] = "0"; + m_default_configuration["UserHacks_unscale_point_line"] = "0"; m_default_configuration["UserHacks_round_sprite_offset"] = "0"; m_default_configuration["UserHacks_safe_fbmask"] = "0"; m_default_configuration["UserHacks_SkipDraw"] = "0"; diff --git a/plugins/GSdx/res/glsl/tfx_vgs.glsl b/plugins/GSdx/res/glsl/tfx_vgs.glsl index 80da9f47a6..06a69a8de6 100644 --- a/plugins/GSdx/res/glsl/tfx_vgs.glsl +++ b/plugins/GSdx/res/glsl/tfx_vgs.glsl @@ -106,34 +106,64 @@ layout(lines) in; #endif layout(triangle_strip, max_vertices = 6) out; +#if GS_POINT == 1 + +void gs_main() +{ + // Transform a point to a NxN sprite + vertex point = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c); + + // Get new position + vec4 lt_p = gl_in[0].gl_Position; + vec4 rb_p = gl_in[0].gl_Position + vec4(PointSize.x, PointSize.y, 0.0f, 0.0f); + vec4 lb_p = rb_p; + vec4 rt_p = rb_p; + lb_p.x = lt_p.x; + rt_p.y = lt_p.y; + + // Triangle 1 + gl_Position = lt_p; + out_vertex(point); + + gl_Position = lb_p; + out_vertex(point); + + gl_Position = rt_p; + out_vertex(point); + EndPrimitive(); + + // Triangle 2 + gl_Position = lb_p; + out_vertex(point); + + gl_Position = rt_p; + out_vertex(point); + + gl_Position = rb_p; + out_vertex(point); + EndPrimitive(); +} + +#else + void gs_main() { // left top => GSin[0]; // right bottom => GSin[1]; -#if GS_POINT == 1 - vertex rb = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c); -#else vertex rb = vertex(GSin[1].t_float, GSin[1].t_int, GSin[1].c); -#endif vertex lt = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c); -#if GS_POINT == 1 - vec4 rb_p = gl_in[0].gl_Position + vec4(PointSize.x, PointSize.y, 0.0f, 0.0f); -#else vec4 rb_p = gl_in[1].gl_Position; -#endif vec4 lb_p = rb_p; vec4 rt_p = rb_p; vec4 lt_p = gl_in[0].gl_Position; -#if GS_POINT == 0 // flat depth lt_p.z = rb_p.z; // flat fog and texture perspective lt.t_float.zw = rb.t_float.zw; // flat color lt.c = rb.c; -#endif // Swap texture and position coordinate vertex lb = rb; @@ -172,3 +202,5 @@ void gs_main() } #endif + +#endif diff --git a/plugins/GSdx/res/glsl_source.h b/plugins/GSdx/res/glsl_source.h index 276a1b997a..1a1f18f738 100644 --- a/plugins/GSdx/res/glsl_source.h +++ b/plugins/GSdx/res/glsl_source.h @@ -773,34 +773,64 @@ static const char* const tfx_vgs_glsl = "#endif\n" "layout(triangle_strip, max_vertices = 6) out;\n" "\n" + "#if GS_POINT == 1\n" + "\n" + "void gs_main()\n" + "{\n" + " // Transform a point to a NxN sprite\n" + " vertex point = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);\n" + "\n" + " // Get new position\n" + " vec4 lt_p = gl_in[0].gl_Position;\n" + " vec4 rb_p = gl_in[0].gl_Position + vec4(PointSize.x, PointSize.y, 0.0f, 0.0f);\n" + " vec4 lb_p = rb_p;\n" + " vec4 rt_p = rb_p;\n" + " lb_p.x = lt_p.x;\n" + " rt_p.y = lt_p.y;\n" + "\n" + " // Triangle 1\n" + " gl_Position = lt_p;\n" + " out_vertex(point);\n" + "\n" + " gl_Position = lb_p;\n" + " out_vertex(point);\n" + "\n" + " gl_Position = rt_p;\n" + " out_vertex(point);\n" + " EndPrimitive();\n" + "\n" + " // Triangle 2\n" + " gl_Position = lb_p;\n" + " out_vertex(point);\n" + "\n" + " gl_Position = rt_p;\n" + " out_vertex(point);\n" + "\n" + " gl_Position = rb_p;\n" + " out_vertex(point);\n" + " EndPrimitive();\n" + "}\n" + "\n" + "#else\n" + "\n" "void gs_main()\n" "{\n" " // left top => GSin[0];\n" " // right bottom => GSin[1];\n" - "#if GS_POINT == 1\n" - " vertex rb = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);\n" - "#else\n" " vertex rb = vertex(GSin[1].t_float, GSin[1].t_int, GSin[1].c);\n" - "#endif\n" " vertex lt = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);\n" "\n" - "#if GS_POINT == 1\n" - " vec4 rb_p = gl_in[0].gl_Position + vec4(PointSize.x, PointSize.y, 0.0f, 0.0f);\n" - "#else\n" " vec4 rb_p = gl_in[1].gl_Position;\n" - "#endif\n" " vec4 lb_p = rb_p;\n" " vec4 rt_p = rb_p;\n" " vec4 lt_p = gl_in[0].gl_Position;\n" "\n" - "#if GS_POINT == 0\n" " // flat depth\n" " lt_p.z = rb_p.z;\n" " // flat fog and texture perspective\n" " lt.t_float.zw = rb.t_float.zw;\n" " // flat color\n" " lt.c = rb.c;\n" - "#endif\n" "\n" " // Swap texture and position coordinate\n" " vertex lb = rb;\n" @@ -839,6 +869,8 @@ static const char* const tfx_vgs_glsl = "}\n" "\n" "#endif\n" + "\n" + "#endif\n" ; static const char* const tfx_fs_all_glsl =