Half Pixel Offset for Linear Filter

This seems to be a problem for even IRs when the user does not use the scaled EFB copies setting
This commit is contained in:
Patrick Ferry 2024-09-03 21:02:29 +01:00
parent 2c3b6215bd
commit 037d28e936
2 changed files with 28 additions and 4 deletions

View file

@ -2906,6 +2906,11 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c
float clamp_top;
float clamp_bottom;
float pixel_height;
float rcp_pixel_width;
float rcp_pixel_height;
float efb_scale;
u32 efb_copy_scaled;
u32 linear_filter;
u32 padding;
};
Uniforms uniforms;
@ -2930,6 +2935,11 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c
uniforms.clamp_bottom = (uniforms.src_top + uniforms.src_height);
uniforms.clamp_bottom -= (static_cast<float>(bottom_coord) + .5f) * rcp_efb_height;
uniforms.pixel_height = g_ActiveConfig.bCopyEFBScaled ? rcp_efb_height : 1.0f / EFB_HEIGHT;
uniforms.rcp_pixel_width = rcp_efb_width;
uniforms.rcp_pixel_height = rcp_efb_height;
uniforms.efb_scale = static_cast<float>(g_framebuffer_manager->GetEFBScale());
uniforms.efb_copy_scaled = g_ActiveConfig.bCopyEFBScaled ? 1u : 0u;
uniforms.linear_filter = linear_filter ? 1u : 0u;
uniforms.padding = 0;
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));

View file

@ -61,6 +61,11 @@ static void WriteHeader(APIType api_type, ShaderCode& out)
" float gamma_rcp;\n"
" float2 clamp_tb;\n"
" float pixel_height;\n"
" float rcp_pixel_width;\n"
" float rcp_pixel_height;\n"
" float efb_scale;\n"
" uint efb_copy_scaled;\n"
" uint linear_filter;\n"
"}};\n");
}
@ -106,18 +111,27 @@ ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data)
out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n");
out.Write("uint4 SampleEFB(float3 uv, float y_offset) {{\n"
" float clamp_top = src_offset.y + clamp_tb.x;\n"
" float clamp_bottom = (src_offset.y + src_size.y) - clamp_tb.y;\n");
" float clamp_bottom = (src_offset.y + src_size.y) - clamp_tb.y;\n"
" float shift_x = 0.0f;\n"
" float shift_y = 0.0f;\n");
// Linear filtering half pixel offset for even IRs
out.Write(" if(linear_filter == 1 && efb_copy_scaled == 0 && mod(efb_scale, 2.0f) == 0){{\n"
" shift_x = rcp_pixel_width / 2.f;\n"
" shift_y = rcp_pixel_height / 2.f;\n"
" }}\n");
// Reverse the direction for OpenGL
if (api_type == APIType::OpenGL)
{
out.Write(" clamp_top = src_offset.y + clamp_tb.y;\n"
" clamp_bottom = (src_offset.y + src_size.y) - clamp_tb.x;\n"
" y_offset = -y_offset;\n");
" y_offset = -y_offset;\n"
" shift_y = -shift_y;\n");
}
out.Write(" float clamp_y = clamp(uv.y + (y_offset * pixel_height), clamp_top, clamp_bottom);\n"
" float4 tex_sample = texture(samp0, float3(uv.x, clamp_y, {}));\n",
out.Write(" float clamp_y = clamp(uv.y + shift_y + (y_offset * pixel_height), clamp_top, clamp_bottom);\n"
" float4 tex_sample = texture(samp0, float3(uv.x + shift_x, clamp_y, {}));\n",
mono_depth ? "0.0" : "uv.z");
if (uid_data->is_depth_copy)