mirror of https://github.com/PCSX2/pcsx2.git
gsdx hw:move vertices fixup for texture shuffle in RendererHw
Bonus: fix m_vt value
This commit is contained in:
parent
aa2b474d1a
commit
e56f75fe9a
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue