Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GS: Support upscaled region repeat #5853

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 45 additions & 73 deletions bin/resources/shaders/dx11/tfx.fx
Original file line number Diff line number Diff line change
Expand Up @@ -192,56 +192,42 @@ float4 sample_p(float u)
return Palette.Sample(PaletteSampler, u);
}

float4 clamp_wrap_uv(float4 uv)
float2 clamp_wrap_uv_2(uint mode, float2 uv, float tex_size, float2 min_max, uint2 msk_fix)
{
float4 tex_size;

if (PS_INVALID_TEX0 == 1)
tex_size = WH.zwzw;
else
tex_size = WH.xyxy;

if(PS_WMS == PS_WMT)
if (mode == 2)
{
if(PS_WMS == 2)
{
uv = clamp(uv, MinMax.xyxy, MinMax.zwzw);
}
else if(PS_WMS == 3)
{
#if PS_FST == 0
return clamp(uv, min_max.xx, min_max.yy);
}
if (mode == 3)
{
#if PS_FST == 0
// wrap negative uv coords to avoid an off by one error that shifted
// textures. Fixes Xenosaga's hair issue.
uv = frac(uv);
#endif
uv = (float4)(((uint4)(uv * tex_size) & MskFix.xyxy) | MskFix.zwzw) / tex_size;
}
#endif

uv *= tex_size;
float2 masked = float2((uint2(uv) & msk_fix.xx) | msk_fix.yy);

if (msk_fix.x & 1) // For upscaling, let the bottom bit mask everything below
masked += frac(uv);

return masked / tex_size;
}
return uv;
}

float4 clamp_wrap_uv(float4 uv)
{
float2 tex_size;

if (PS_INVALID_TEX0 == 1)
tex_size = WH.zw;
else
{
if(PS_WMS == 2)
{
uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz);
}
else if(PS_WMS == 3)
{
#if PS_FST == 0
uv.xz = frac(uv.xz);
#endif
uv.xz = (float2)(((uint2)(uv.xz * tex_size.xx) & MskFix.xx) | MskFix.zz) / tex_size.xx;
}
if(PS_WMT == 2)
{
uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww);
}
else if(PS_WMT == 3)
{
#if PS_FST == 0
uv.yw = frac(uv.yw);
#endif
uv.yw = (float2)(((uint2)(uv.yw * tex_size.yy) & MskFix.yy) | MskFix.ww) / tex_size.yy;
}
}
tex_size = WH.xy;

uv.xz = clamp_wrap_uv_2(PS_WMS, uv.xz, tex_size.x, MinMax.xz, MskFix.xz);
uv.yw = clamp_wrap_uv_2(PS_WMT, uv.yw, tex_size.y, MinMax.yw, MskFix.yw);

return uv;
}
Expand Down Expand Up @@ -326,42 +312,28 @@ float4 fetch_c(int2 uv)
// Depth sampling
//////////////////////////////////////////////////////////////////////

int2 clamp_wrap_uv_depth(int2 uv)
int clamp_wrap_uv_depth_1(uint mode, int uv, int2 msk_fix)
{
int4 mask = (int4)MskFix << 4;
if (PS_WMS == PS_WMT)
int2 mask = msk_fix << 4;

if (mode == 2)
return clamp(uv, mask.x, mask.y | 0xF);
if (mode == 3)
{
if (PS_WMS == 2)
{
uv = clamp(uv, mask.xy, mask.zw);
}
else if (PS_WMS == 3)
{
uv = (uv & mask.xy) | mask.zw;
}
}
else
{
if (PS_WMS == 2)
{
uv.x = clamp(uv.x, mask.x, mask.z);
}
else if (PS_WMS == 3)
{
uv.x = (uv.x & mask.x) | mask.z;
}
if (PS_WMT == 2)
{
uv.y = clamp(uv.y, mask.y, mask.w);
}
else if (PS_WMT == 3)
{
uv.y = (uv.y & mask.y) | mask.w;
}
if (msk_fix.x & 1)
mask.x |= 0xF;
return (uv & mask.x) | mask.y;
}
return uv;
}

int2 clamp_wrap_uv_depth(int2 uv)
{
uv.x = clamp_wrap_uv_depth_1(PS_WMS, uv.x, (int2)MskFix.xz);
uv.y = clamp_wrap_uv_depth_1(PS_WMT, uv.y, (int2)MskFix.yw);
return uv;
}

float4 sample_depth(float2 st, float2 pos)
{
float2 uv_f = (float2)clamp_wrap_uv_depth(int2(st)) * (float2)PS_SCALE_FACTOR * (float2)(1.0f / 16.0f);
Expand Down
114 changes: 46 additions & 68 deletions bin/resources/shaders/opengl/tfx_fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -149,54 +149,43 @@ vec4 sample_p(float idx)
return texture(PaletteSampler, vec2(idx, 0.0f));
}

vec4 clamp_wrap_uv(vec4 uv)
vec2 clamp_wrap_uv_2(uint mode, vec2 uv, float tex_size, vec2 min_max, uvec2 msk_fix)
{
vec4 uv_out = uv;
#if PS_INVALID_TEX0 == 1
vec4 tex_size = WH.zwzw;
#else
vec4 tex_size = WH.xyxy;
#endif

#if PS_WMS == PS_WMT

#if PS_WMS == 2
uv_out = clamp(uv, MinMax.xyxy, MinMax.zwzw);
#elif PS_WMS == 3
#if PS_FST == 0
// wrap negative uv coords to avoid an off by one error that shifted
// textures. Fixes Xenosaga's hair issue.
uv = fract(uv);
#endif
uv_out = vec4((uvec4(uv * tex_size) & MskFix.xyxy) | MskFix.zwzw) / tex_size;
#endif

#else // PS_WMS != PS_WMT

#if PS_WMS == 2
uv_out.xz = clamp(uv.xz, MinMax.xx, MinMax.zz);
if (mode == 2)
{
return clamp(uv, min_max.xx, min_max.yy);
}
if (mode == 3)
{
#if PS_FST == 0
// wrap negative uv coords to avoid an off by one error that shifted
// textures. Fixes Xenosaga's hair issue.
uv = fract(uv);
#endif

#elif PS_WMS == 3
#if PS_FST == 0
uv.xz = fract(uv.xz);
#endif
uv_out.xz = vec2((uvec2(uv.xz * tex_size.xx) & MskFix.xx) | MskFix.zz) / tex_size.xx;
uv *= tex_size;
vec2 masked = vec2((uvec2(uv) & msk_fix.xx) | msk_fix.yy);

#endif
if ((msk_fix.x & 1) != 0) // For upscaling, let the bottom bit mask everything below
masked += fract(uv);

#if PS_WMT == 2
uv_out.yw = clamp(uv.yw, MinMax.yy, MinMax.ww);
return masked / tex_size;
}
return uv;
}

#elif PS_WMT == 3
#if PS_FST == 0
uv.yw = fract(uv.yw);
#endif
uv_out.yw = vec2((uvec2(uv.yw * tex_size.yy) & MskFix.yy) | MskFix.ww) / tex_size.yy;
vec4 clamp_wrap_uv(vec4 uv)
{
#if PS_INVALID_TEX0 == 1
vec2 tex_size = WH.zw;
#else
vec2 tex_size = WH.xy;
#endif

#endif
uv.xz = clamp_wrap_uv_2(PS_WMS, uv.xz, tex_size.x, MinMax.xz, MskFix.xz);
uv.yw = clamp_wrap_uv_2(PS_WMT, uv.yw, tex_size.y, MinMax.yw, MskFix.yw);

return uv_out;
return uv;
}

mat4 sample_4c(vec4 uv)
Expand Down Expand Up @@ -294,39 +283,28 @@ vec4 fetch_c(ivec2 uv)
//////////////////////////////////////////////////////////////////////
// Depth sampling
//////////////////////////////////////////////////////////////////////
ivec2 clamp_wrap_uv_depth(ivec2 uv)
int clamp_wrap_uv_depth_1(uint mode, int uv, ivec2 msk_fix)
{
ivec2 uv_out = uv;

// Keep the full precision
// It allow to multiply the ScalingFactor before the 1/16 coeff
ivec4 mask = ivec4(MskFix) << 4;
ivec2 mask = msk_fix << 4;

#if PS_WMS == PS_WMT

#if PS_WMS == 2
uv_out = clamp(uv, mask.xy, mask.zw);
#elif PS_WMS == 3
uv_out = (uv & mask.xy) | mask.zw;
#endif

#else // PS_WMS != PS_WMT

#if PS_WMS == 2
uv_out.x = clamp(uv.x, mask.x, mask.z);
#elif PS_WMS == 3
uv_out.x = (uv.x & mask.x) | mask.z;
#endif

#if PS_WMT == 2
uv_out.y = clamp(uv.y, mask.y, mask.w);
#elif PS_WMT == 3
uv_out.y = (uv.y & mask.y) | mask.w;
#endif

#endif
if (mode == 2)
return clamp(uv, mask.x, mask.y | 0xF);
if (mode == 3)
{
if ((msk_fix.x & 1) != 0)
mask.x |= 0xF;
return (uv & mask.x) | mask.y;
}
return uv;
}

return uv_out;
ivec2 clamp_wrap_uv_depth(ivec2 uv)
{
uv.x = clamp_wrap_uv_depth_1(PS_WMS, uv.x, ivec2(MskFix.xz));
uv.y = clamp_wrap_uv_depth_1(PS_WMT, uv.y, ivec2(MskFix.yw));
return uv;
}

vec4 sample_depth(vec2 st)
Expand Down
Loading