gsdx hw:move vertices fixup for texture shuffle in RendererHw

Bonus: fix m_vt value
This commit is contained in:
Gregory Hainaut 2019-02-21 13:10:41 +01:00 committed by lightningterror
parent aa2b474d1a
commit e56f75fe9a
5 changed files with 107 additions and 152 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;