diff --git a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp index 49a6693614..6f7040c7bd 100644 --- a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp @@ -218,83 +218,17 @@ void GSRendererDX11::EmulateZbuffer() void GSRendererDX11::EmulateTextureShuffleAndFbmask() { - size_t count = m_vertex.next; - GSVertex* v = &m_vertex.buff[0]; - if (m_texture_shuffle) { m_ps_sel.shuffle = 1; m_ps_sel.dfmt = 0; - const GIFRegXYOFFSET& o = m_context->XYOFFSET; + bool write_ba; + bool read_ba; - // vertex position is 8 to 16 pixels, therefore it is the 16-31 bits of the colors - int pos = (v[0].XYZ.X - o.OFX) & 0xFF; - bool write_ba = (pos > 112 && pos < 136); - // Read texture is 8 to 16 pixels (same as above) - float tw = (float)(1u << m_context->TEX0.TW); - int tex_pos = (PRIM->FST) ? v[0].U : (int)(tw * v[0].ST.S); - tex_pos &= 0xFF; - m_ps_sel.read_ba = (tex_pos > 112 && tex_pos < 144); + ConvertSpriteTextureShuffle(write_ba, read_ba); - // Convert the vertex info to a 32 bits color format equivalent - if (PRIM->FST) - { - - for(size_t i = 0; i < count; i += 2) - { - if (write_ba) - v[i].XYZ.X -= 128u; - else - v[i+1].XYZ.X += 128u; - - if (m_ps_sel.read_ba) - v[i].U -= 128u; - else - v[i+1].U += 128u; - - // Height is too big (2x). - int tex_offset = v[i].V & 0xF; - GSVector4i offset(o.OFY, tex_offset, o.OFY, tex_offset); - - GSVector4i tmp(v[i].XYZ.Y, v[i].V, v[i+1].XYZ.Y, v[i+1].V); - tmp = GSVector4i(tmp - offset).srl32(1) + offset; - - v[i].XYZ.Y = (uint16)tmp.x; - v[i].V = (uint16)tmp.y; - v[i+1].XYZ.Y = (uint16)tmp.z; - v[i+1].V = (uint16)tmp.w; - } - } - else - { - const float offset_8pix = 8.0f / tw; - - for(size_t i = 0; i < count; i += 2) - { - if (write_ba) - v[i].XYZ.X -= 128u; - else - v[i+1].XYZ.X += 128u; - - if (m_ps_sel.read_ba) - v[i].ST.S -= offset_8pix; - else - v[i+1].ST.S += offset_8pix; - - // Height is too big (2x). - GSVector4i offset(o.OFY, o.OFY); - - GSVector4i tmp(v[i].XYZ.Y, v[i+1].XYZ.Y); - tmp = GSVector4i(tmp - offset).srl32(1) + offset; - - //fprintf(stderr, "Before %d, After %d\n", v[i+1].XYZ.Y, tmp.y); - v[i].XYZ.Y = (uint16)tmp.x; - v[i].ST.T /= 2.0f; - v[i+1].XYZ.Y = (uint16)tmp.y; - v[i+1].ST.T /= 2.0f; - } - } + m_ps_sel.read_ba = read_ba; // Please bang my head against the wall! // 1/ Reduce the frame mask to a 16 bit format @@ -309,13 +243,9 @@ void GSRendererDX11::EmulateTextureShuffleAndFbmask() if (rg_mask != 0xFF) { if (write_ba) - { m_om_bsel.wb = 1; - } else - { m_om_bsel.wr = 1; - } } else if ((fbmask & 0xFF) != 0xFF) { @@ -328,13 +258,9 @@ void GSRendererDX11::EmulateTextureShuffleAndFbmask() if (ba_mask != 0xFF) { if (write_ba) - { m_om_bsel.wa = 1; - } else - { m_om_bsel.wg = 1; - } } else if ((fbmask & 0xFF) != 0xFF) { diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp index 3543934d32..1c6db501b8 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp @@ -428,6 +428,97 @@ void GSRendererHW::Lines2Sprites() } } +// Fix the vertex position/tex_coordinate from 16 bits color to 32 bits color +void GSRendererHW::ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba) +{ + size_t count = m_vertex.next; + GSVertex* v = &m_vertex.buff[0]; + const GIFRegXYOFFSET& o = m_context->XYOFFSET; + + // vertex position is 8 to 16 pixels, therefore it is the 16-31 bits of the colors + int pos = (v[0].XYZ.X - o.OFX) & 0xFF; + write_ba = (pos > 112 && pos < 136); + + // Read texture is 8 to 16 pixels (same as above) + float tw = (float)(1u << m_context->TEX0.TW); + int tex_pos = (PRIM->FST) ? v[0].U : (int)(tw * v[0].ST.S); + tex_pos &= 0xFF; + read_ba = (tex_pos > 112 && tex_pos < 144); + + if (PRIM->FST) { + GL_INS("First vertex is P: %d => %d T: %d => %d", v[0].XYZ.X, v[1].XYZ.X, v[0].U, v[1].U); + + for(size_t i = 0; i < count; i += 2) { + if (write_ba) + v[i].XYZ.X -= 128u; + else + v[i+1].XYZ.X += 128u; + + if (read_ba) + v[i].U -= 128u; + else + v[i+1].U += 128u; + + // Height is too big (2x). + int tex_offset = v[i].V & 0xF; + GSVector4i offset(o.OFY, tex_offset, o.OFY, tex_offset); + + GSVector4i tmp(v[i].XYZ.Y, v[i].V, v[i+1].XYZ.Y, v[i+1].V); + tmp = GSVector4i(tmp - offset).srl32(1) + offset; + + v[i].XYZ.Y = (uint16)tmp.x; + v[i].V = (uint16)tmp.y; + v[i+1].XYZ.Y = (uint16)tmp.z; + v[i+1].V = (uint16)tmp.w; + } + } else { + const float offset_8pix = 8.0f / tw; + GL_INS("First vertex is P: %d => %d T: %f => %f (offset %f)", v[0].XYZ.X, v[1].XYZ.X, v[0].ST.S, v[1].ST.S, offset_8pix); + + for(size_t i = 0; i < count; i += 2) { + if (write_ba) + v[i].XYZ.X -= 128u; + else + v[i+1].XYZ.X += 128u; + + if (read_ba) + v[i].ST.S -= offset_8pix; + else + v[i+1].ST.S += offset_8pix; + + // Height is too big (2x). + GSVector4i offset(o.OFY, o.OFY); + + GSVector4i tmp(v[i].XYZ.Y, v[i+1].XYZ.Y); + tmp = GSVector4i(tmp - offset).srl32(1) + offset; + + //fprintf(stderr, "Before %d, After %d\n", v[i+1].XYZ.Y, tmp.y); + v[i].XYZ.Y = (uint16)tmp.x; + v[i].ST.T /= 2.0f; + v[i+1].XYZ.Y = (uint16)tmp.y; + v[i+1].ST.T /= 2.0f; + } + } + + // Update vertex trace too. Avoid issue to compute bounding box + if (write_ba) + m_vt.m_min.p.x -= 8.0f; + else + m_vt.m_max.p.x += 8.0f; + + + float delta_Y = m_vt.m_max.p.y - m_vt.m_min.p.y; + m_vt.m_max.p.y -= delta_Y / 2.0f; + + if (read_ba) + m_vt.m_min.t.x -= 8.0f; + else + m_vt.m_max.t.x += 8.0f; + + float delta_T = m_vt.m_max.t.y - m_vt.m_min.t.y; + m_vt.m_max.t.y -= delta_T / 2.0f; +} + GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Source* tex) { if (m_userHacks_HPO <= 1 || GetUpscaleMultiplier() == 1) return GSVector4(0.0f); diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.h b/plugins/GSdx/Renderers/HW/GSRendererHW.h index 53c03fbacb..d6187acfb3 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.h +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.h @@ -167,6 +167,7 @@ public: GSVector2i GetCustomResolution(); void SetScaling(); void Lines2Sprites(); + void ConvertSpriteTextureShuffle(bool& write_ba, bool& read_ba); GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex); GSVector4i ComputeBoundingBox(const GSVector2& rtscale, const GSVector2i& rtsize); void MergeSprite(GSTextureCache::Source* tex); diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp index dcfb495b70..01ab5c7bc4 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp @@ -211,85 +211,22 @@ void GSRendererOGL::EmulateZbuffer() void GSRendererOGL::EmulateTextureShuffleAndFbmask() { - size_t count = m_vertex.next; - GSVertex* v = &m_vertex.buff[0]; - if (m_texture_shuffle) { m_ps_sel.shuffle = 1; m_ps_sel.dfmt = 0; - const GIFRegXYOFFSET& o = m_context->XYOFFSET; + bool write_ba; + bool read_ba; - // vertex position is 8 to 16 pixels, therefore it is the 16-31 bits of the colors - int pos = (v[0].XYZ.X - o.OFX) & 0xFF; - bool write_ba = (pos > 112 && pos < 136); - // Read texture is 8 to 16 pixels (same as above) - float tw = (float)(1u << m_context->TEX0.TW); - int tex_pos = (PRIM->FST) ? v[0].U : (int)(tw * v[0].ST.S); - tex_pos &= 0xFF; - m_ps_sel.read_ba = (tex_pos > 112 && tex_pos < 144); - - // Convert the vertex info to a 32 bits color format equivalent - if (PRIM->FST) { - GL_INS("First vertex is P: %d => %d T: %d => %d", v[0].XYZ.X, v[1].XYZ.X, v[0].U, v[1].U); - - for(size_t i = 0; i < count; i += 2) { - if (write_ba) - v[i].XYZ.X -= 128u; - else - v[i+1].XYZ.X += 128u; - - if (m_ps_sel.read_ba) - v[i].U -= 128u; - else - v[i+1].U += 128u; - - // Height is too big (2x). - int tex_offset = v[i].V & 0xF; - GSVector4i offset(o.OFY, tex_offset, o.OFY, tex_offset); - - GSVector4i tmp(v[i].XYZ.Y, v[i].V, v[i+1].XYZ.Y, v[i+1].V); - tmp = GSVector4i(tmp - offset).srl32(1) + offset; - - v[i].XYZ.Y = (uint16)tmp.x; - v[i].V = (uint16)tmp.y; - v[i+1].XYZ.Y = (uint16)tmp.z; - v[i+1].V = (uint16)tmp.w; - } - } else { - const float offset_8pix = 8.0f / tw; - GL_INS("First vertex is P: %d => %d T: %f => %f (offset %f)", v[0].XYZ.X, v[1].XYZ.X, v[0].ST.S, v[1].ST.S, offset_8pix); - - for(size_t i = 0; i < count; i += 2) { - if (write_ba) - v[i].XYZ.X -= 128u; - else - v[i+1].XYZ.X += 128u; - - if (m_ps_sel.read_ba) - v[i].ST.S -= offset_8pix; - else - v[i+1].ST.S += offset_8pix; - - // Height is too big (2x). - GSVector4i offset(o.OFY, o.OFY); - - GSVector4i tmp(v[i].XYZ.Y, v[i+1].XYZ.Y); - tmp = GSVector4i(tmp - offset).srl32(1) + offset; - - //fprintf(stderr, "Before %d, After %d\n", v[i+1].XYZ.Y, tmp.y); - v[i].XYZ.Y = (uint16)tmp.x; - v[i].ST.T /= 2.0f; - v[i+1].XYZ.Y = (uint16)tmp.y; - v[i+1].ST.T /= 2.0f; - } - } + ConvertSpriteTextureShuffle(write_ba, read_ba); // If date is enabled you need to test the green channel instead of the // alpha channel. Only enable this code in DATE mode to reduce the number // of shader. m_ps_sel.write_rg = !write_ba && m_context->TEST.DATE; + m_ps_sel.read_ba = read_ba; + // Please bang my head against the wall! // 1/ Reduce the frame mask to a 16 bit format const uint32& m = m_context->FRAME.FBMSK; @@ -302,10 +239,10 @@ void GSRendererOGL::EmulateTextureShuffleAndFbmask() // 2 Select the new mask (Please someone put SSE here) if (rg_mask != 0xFF) { if (write_ba) { - GL_INS("Color shuffle %s => B", m_ps_sel.read_ba ? "B" : "R"); + GL_INS("Color shuffle %s => B", read_ba ? "B" : "R"); m_om_csel.wb = 1; } else { - GL_INS("Color shuffle %s => R", m_ps_sel.read_ba ? "B" : "R"); + GL_INS("Color shuffle %s => R", read_ba ? "B" : "R"); m_om_csel.wr = 1; } if (rg_mask) @@ -314,10 +251,10 @@ void GSRendererOGL::EmulateTextureShuffleAndFbmask() if (ba_mask != 0xFF) { if (write_ba) { - GL_INS("Color shuffle %s => A", m_ps_sel.read_ba ? "A" : "G"); + GL_INS("Color shuffle %s => A", read_ba ? "A" : "G"); m_om_csel.wa = 1; } else { - GL_INS("Color shuffle %s => G", m_ps_sel.read_ba ? "A" : "G"); + GL_INS("Color shuffle %s => G", read_ba ? "A" : "G"); m_om_csel.wg = 1; } if (ba_mask) diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index 08b867ff83..ea3b9cd793 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -615,8 +615,8 @@ float4 ps_color(PS_INPUT input) float2 st = (input.t.xy * WH.xy) / (input.t.w * WH.zw); // no st_int yet #elif PS_FST == 0 - float2 st = input.t.xy / (input.t.w); - float2 st_int = input.ti.zw / (input.t.w); + float2 st = input.t.xy / input.t.w; + float2 st_int = input.ti.zw / input.t.w; #else float2 st = input.ti.xy; float2 st_int = input.ti.zw;