diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 08d94553e5..017581be02 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -92,6 +92,19 @@ void GSRendererOGL::Lines2Sprites() v0.XYZ.Z = v1.XYZ.Z; v0.FOG = v1.FOG; + if (PRIM->TME && !PRIM->FST) { + GSVector4 st0 = GSVector4::loadl(&v0.ST.u64); + GSVector4 st1 = GSVector4::loadl(&v1.ST.u64); + GSVector4 Q = GSVector4(v1.RGBAQ.Q, v1.RGBAQ.Q, v1.RGBAQ.Q, v1.RGBAQ.Q); + GSVector4 st = st0.upld(st1) / Q; + + GSVector4::storel(&v0.ST.u64, st); + GSVector4::storeh(&v1.ST.u64, st); + + v0.RGBAQ.Q = 1.0f; + v1.RGBAQ.Q = 1.0f; + } + q[0] = v0; q[3] = v1; @@ -176,7 +189,7 @@ void GSRendererOGL::SetupIA(const float& sx, const float& sy) // the extra validation cost of the extra stage. // // Note: keep Geometry Shader in the replayer to ease debug. - if (GLLoader::found_geometry_shader && (m_vertex.next > 32 || GLLoader::in_replayer)) { // <=> 16 sprites (based on Shadow Hearts) + if (GLLoader::found_geometry_shader && !m_vt.m_accurate_stq && (m_vertex.next > 32 || GLLoader::in_replayer)) { // <=> 16 sprites (based on Shadow Hearts) m_gs_sel.sprite = 1; t = GL_LINES; diff --git a/plugins/GSdx/GSVector.h b/plugins/GSdx/GSVector.h index eca1ced450..e8e1f79214 100644 --- a/plugins/GSdx/GSVector.h +++ b/plugins/GSdx/GSVector.h @@ -2900,6 +2900,16 @@ public: return GSVector4(_mm_unpackhi_ps(m, a)); } + __forceinline GSVector4 upld(const GSVector4& a) const + { + return GSVector4(_mm_castpd_ps(_mm_unpacklo_pd(_mm_castps_pd(m), _mm_castps_pd(a.m)))); + } + + __forceinline GSVector4 uphd(const GSVector4& a) const + { + return GSVector4(_mm_castpd_ps(_mm_unpackhi_pd(_mm_castps_pd(m), _mm_castps_pd(a.m)))); + } + __forceinline GSVector4 l2h(const GSVector4& a) const { return GSVector4(_mm_movelh_ps(m, a)); @@ -3105,6 +3115,11 @@ GSVector.h:2973:15: error: shadows template parm 'int i' _mm_store_sd((double*)p, _mm_castps_pd(v.m)); } + __forceinline static void storeh(void* p, const GSVector4& v) + { + _mm_storeh_pd((double*)p, _mm_castps_pd(v.m)); + } + template __forceinline static void store(void* p, const GSVector4& v) { if(aligned) _mm_store_ps((float*)p, v.m); diff --git a/plugins/GSdx/GSVertexTrace.cpp b/plugins/GSdx/GSVertexTrace.cpp index e004b10ad1..9ea217d6e9 100644 --- a/plugins/GSdx/GSVertexTrace.cpp +++ b/plugins/GSdx/GSVertexTrace.cpp @@ -32,7 +32,7 @@ void GSVertexTrace::InitVectors() } GSVertexTrace::GSVertexTrace(const GSState* state) - : m_state(state), m_accurate_stq(false), m_primclass(GS_INVALID_CLASS) + : m_accurate_stq(false), m_state(state), m_primclass(GS_INVALID_CLASS) { m_force_filter = static_cast(theApp.GetConfigI("filter")); memset(&m_alpha, 0, sizeof(m_alpha)); diff --git a/plugins/GSdx/GSVertexTrace.h b/plugins/GSdx/GSVertexTrace.h index 439a5ef7ba..59c5a0de14 100644 --- a/plugins/GSdx/GSVertexTrace.h +++ b/plugins/GSdx/GSVertexTrace.h @@ -36,14 +36,13 @@ class alignas(32) GSVertexTrace : public GSAlignedClass<32> public: struct Vertex {GSVector4i c; GSVector4 p, t;}; struct VertexAlpha {int min, max; bool valid;}; + bool m_accurate_stq; protected: const GSState* m_state; static GSVector4 s_minmax; - bool m_accurate_stq; - typedef void (GSVertexTrace::*FindMinMaxPtr)(const void* vertex, const uint32* index, int count); FindMinMaxPtr m_fmm[2][2][2][2][2][4];