Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/macos_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ jobs:
app_store_connect_api_key_json_file: 'key.json'

- name: Zip Build Artifacts
if: inputs.arch == 'x86-64'
# if: inputs.arch == 'x86-64'
run: |
TAG="$(git tag --points-at HEAD)"
if [ -z "$TAG" ]; then
Expand All @@ -211,7 +211,7 @@ jobs:
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz

- name: Upload Artifact
if: inputs.arch == 'x86-64'
# if: inputs.arch == 'x86-64'
uses: actions/upload-artifact@v7
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
Expand Down
72 changes: 71 additions & 1 deletion bin/resources/shaders/dx11/tfx.fx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define VS_IIP 0
#define VS_TME 1
#define VS_FST 1
#define VS_ROUND_UV 0
#endif

#ifndef GS_IIP
Expand Down Expand Up @@ -102,6 +103,9 @@
#define PS_NO_COLOR1 0
#define PS_DATE 0
#define PS_TEX_IS_FB 0
#define PS_COLOR_FEEDBACK 0
#define PS_DEPTH_FEEDBACK 0
#define PS_ROUND_UV 0
#endif

#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
Expand Down Expand Up @@ -135,6 +139,10 @@ struct VS_OUTPUT
#else
nointerpolation float4 c : COLOR0;
#endif

#if VS_ROUND_UV != 0
nointerpolation uint4 rounduv : TEXCOORD3;
#endif
};

struct PS_INPUT
Expand All @@ -147,6 +155,9 @@ struct PS_INPUT
#else
nointerpolation float4 c : COLOR0;
#endif
#if PS_ROUND_UV != 0
nointerpolation uint4 rounduv : TEXCOORD3;
#endif
#if (PS_DATE >= 1 && PS_DATE <= 3) || GS_FORWARD_PRIMID
uint primid : SV_PrimitiveID;
#endif
Expand Down Expand Up @@ -362,6 +373,37 @@ float4 clamp_wrap_uv(float4 uv)
return uv;
}

float4 round_uv(PS_INPUT input)
{
#if PS_ROUND_UV
// Check if we're at the prim top or left.
int2 topleft = int2(int2(input.p.xy) == int2(input.rounduv.xy));

// Get flags for whether to round U, V.
int2 round_flags = int2(input.rounduv.zw);

// Being on the top or left pixels converts round down to round up.
int2 round_down = int2(round_flags == PS_ROUND_UV_DOWN) & ~topleft;
int2 round_up = int2(round_flags == PS_ROUND_UV_UP) |
(int2(round_flags == PS_ROUND_UV_DOWN) & topleft);

float2 uv = input.ti.zw; // Unnormalized UVs.
float2 uvi = round(input.ti.zw / 8.0f) * 8.0f; // Nearest half texel.

// Round only if close to a half texel.
int2 close = int2(abs(uv - uvi) <= PS_ROUND_UV_THRESHOLD);
round_down &= close;
round_up &= close;

uv = bool2(round_down) ? uvi - PS_ROUND_UV_THRESHOLD : uv;
uv = bool2(round_up) ? uvi + PS_ROUND_UV_THRESHOLD : uv;

return float4(uv / 16.0f / WH.xy, uv); // Return normalized and unnormalized coords.
#else
return float4(0.0f, 0.0f, 0.0f, 0.0f);
#endif
}

float4x4 sample_4c(float4 uv, float uv_w, int2 xy)
{
float4x4 c;
Expand Down Expand Up @@ -796,6 +838,10 @@ float4 ps_color(PS_INPUT input)
#if PS_FST == 0
float2 st = input.t.xy / input.t.w;
float2 st_int = input.ti.zw / input.t.w;
#elif PS_ROUND_UV != 0
float4 ti_rounded = round_uv(input);
float2 st = ti_rounded.xy;
float2 st_int = ti_rounded.zw;
#else
float2 st = input.ti.xy;
float2 st_int = input.ti.zw;
Expand Down Expand Up @@ -1313,6 +1359,17 @@ cbuffer cb0
uint BaseVertex; // Only used in DX11.
};

uint4 extract_round_uv_bits(float q)
{
uint qi = asuint(q);
return uint4(
(qi >> 0) & 0xFFF, // Prim left
(qi >> 12) & 0xFFF, // Prim top
(qi >> 24) & 0xF, // Round U flags
(qi >> 28) & 0xF // Round V flags
);
}

VS_OUTPUT vs_main(VS_INPUT input)
{
// Clamp to max depth, gs doesn't wrap
Expand All @@ -1332,7 +1389,11 @@ VS_OUTPUT vs_main(VS_INPUT input)

if(VS_TME)
{
float2 uv = input.uv - TextureOffset;
#if VS_ROUND_UV == 0
float2 uv = input.uv - TextureOffset;
#else
float2 uv = input.st - TextureOffset;
#endif
float2 st = input.st - TextureOffset;

// Integer nomalized
Expand All @@ -1351,12 +1412,21 @@ VS_OUTPUT vs_main(VS_INPUT input)
// Float coords
output.t.xy = st;
output.t.w = input.q;

// Get UV rounding info saved in Q.
#if VS_ROUND_UV
output.rounduv = extract_round_uv_bits(input.q);
output.t.w = 1.0f;
#endif
}
else
{
output.t.xy = 0;
output.t.w = 1.0f;
output.ti = 0;
#if VS_ROUND_UV
output.rounduv = 0;
#endif
}

output.c = input.c;
Expand Down
39 changes: 39 additions & 0 deletions bin/resources/shaders/opengl/tfx_fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ in SHADER
#else
flat vec4 c;
#endif

#if PS_ROUND_UV != 0
flat uvec4 rounduv;
#endif
} PSin;

#define TARGET_0_QUALIFIER out
Expand Down Expand Up @@ -304,6 +308,37 @@ vec4 clamp_wrap_uv(vec4 uv)
return uv_out;
}

vec4 round_uv()
{
#if PS_ROUND_UV
// Check if we're at the prim top or left.
ivec2 topleft = ivec2(equal(ivec2(gl_FragCoord.xy), ivec2(PSin.rounduv.xy)));

// Get flags for whether to round U, V.
ivec2 round_flags = ivec2(PSin.rounduv.zw);

// Being on the top or left pixels converts round down to round up.
ivec2 round_down = ivec2(equal(round_flags, ivec2(PS_ROUND_UV_DOWN))) & ~topleft;
ivec2 round_up = ivec2(equal(round_flags, ivec2(PS_ROUND_UV_UP))) |
(ivec2(equal(round_flags, ivec2(PS_ROUND_UV_DOWN))) & topleft);

vec2 uv = PSin.t_int.zw; // Unnormalized UVs.
vec2 uvi = round(PSin.t_int.zw / 8.0f) * 8.0f; // Nearest half texel.

// Round only if close to a half texel.
ivec2 close = ivec2(lessThanEqual(abs(uv - uvi), vec2(PS_ROUND_UV_THRESHOLD)));
round_down &= close;
round_up &= close;

uv = mix(uv, uvi - vec2(PS_ROUND_UV_THRESHOLD), bvec2(round_down));
uv = mix(uv, uvi + vec2(PS_ROUND_UV_THRESHOLD), bvec2(round_up));

return vec4(uv / 16.0f / WH.xy, uv); // Return normalized and unnormalized coords.
#else
return vec4(0.0f);
#endif
}

mat4 sample_4c(vec4 uv)
{
mat4 c;
Expand Down Expand Up @@ -722,6 +757,10 @@ vec4 ps_color()
#if (PS_FST == 0)
vec2 st = PSin.t_float.xy / vec2(PSin.t_float.w);
vec2 st_int = PSin.t_int.zw / vec2(PSin.t_float.w);
#elif PS_ROUND_UV != 0
vec4 t_int_rounded = round_uv();
vec2 st = t_int_rounded.xy;
vec2 st_int = t_int_rounded.zw;
#else
// Note xy are normalized coordinate
vec2 st = PSin.t_int.xy;
Expand Down
46 changes: 43 additions & 3 deletions bin/resources/shaders/opengl/tfx_vgs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,24 @@ out SHADER
#else
flat vec4 c;
#endif
#if VS_ROUND_UV != 0
flat uvec4 rounduv;
#endif
} VSout;

const float exp_min32 = exp2(-32.0f);

uvec4 extract_round_uv_bits(float q)
{
uint qi = floatBitsToUint(q);
return uvec4(
(qi >> 0) & 0xFFF, // Prim left
(qi >> 12) & 0xFFF, // Prim top
(qi >> 24) & 0xF, // Round U flags
(qi >> 28) & 0xF // Round V flags
);
}

#if VS_EXPAND == 0

layout(location = 0) in vec2 i_st;
Expand All @@ -43,7 +57,11 @@ layout(location = 7) in vec4 i_f;

void texture_coord()
{
vec2 uv = vec2(i_uv) - TextureOffset;
#if VS_ROUND_UV == 0
vec2 uv = vec2(i_uv) - TextureOffset;
#else
vec2 uv = i_st - TextureOffset;
#endif
vec2 st = i_st - TextureOffset;

// Float coordinate
Expand All @@ -59,6 +77,12 @@ void texture_coord()
// Some games uses float coordinate for post-processing effect
VSout.t_int.zw = st / TextureScale;
#endif

// Get UV rounding info saved in Q.
#if VS_ROUND_UV
VSout.rounduv = extract_round_uv_bits(i_q);
VSout.t_float.w = 1.0f;
#endif
}

void vs_main()
Expand All @@ -78,7 +102,7 @@ void vs_main()
texture_coord();

VSout.c = i_c;
VSout.t_float.z = i_f.x; // pack for with texture
VSout.t_float.z = i_f.x; // pack fog with texture

#if VS_POINT_SIZE
gl_PointSize = PointSize.x;
Expand Down Expand Up @@ -108,6 +132,9 @@ struct ProcessedVertex
vec4 t_float;
vec4 t_int;
vec4 c;
#if VS_ROUND_UV
uvec4 rounduv;
#endif
};

ProcessedVertex load_vertex(uint index)
Expand All @@ -131,7 +158,11 @@ ProcessedVertex load_vertex(uint index)
vtx.p.z = float(z) * exp_min32;
vtx.p.w = 1.0f;

vec2 uv = vec2(i_uv) - TextureOffset;
#if VS_ROUND_UV == 0
vec2 uv = vec2(i_uv) - TextureOffset;
#else
vec2 uv = i_st - TextureOffset;
#endif
vec2 st = i_st - TextureOffset;

vtx.t_float.xy = st;
Expand All @@ -144,6 +175,12 @@ ProcessedVertex load_vertex(uint index)
vtx.t_int.zw = st / TextureScale;
#endif

// Get UV rounding info saved in Q.
#if VS_ROUND_UV
vtx.rounduv = extract_round_uv_bits(i_q);
vtx.t_float.w = 1.0f;
#endif

vtx.c = i_c;
vtx.t_float.z = i_f.x;

Expand Down Expand Up @@ -210,6 +247,9 @@ void main()
VSout.t_float = vtx.t_float;
VSout.t_int = vtx.t_int;
VSout.c = vtx.c;
#if VS_ROUND_UV
VSout.rounduv = vtx.rounduv;
#endif
}

#endif // VS_EXPAND
Expand Down
Loading
Loading